I have a beginner question regarding “variable-expansion” while creating a quoted list.
Given the b/m code snippet, I want to set the variable content to hold the following list of cons cells (("a" . "b") ("c" . "d")).
(setq cvar "c")
;; Desperate try
(setq content '(("a" . "b")((symbol-value cvar) . "d"))
However, my problem is, that cvar does not get expanded, since the list is treated as it is. How can I achieve the intended result? Can somebody help me with that?
use backquote
(setq content `(("a" . "b") (,cvar . "d"))
or
(setq content (list '("a" . "b") (cons cvar "d"))
Related
I am beginner in Lisp. There is a question that I cannot solve.
Show the simplest expression that Lisp will print out when you type the following
expression:
’(a b (c . e) (d . nil))
I tried (cons 'a (cons 'b (cons (cons 'c 'e) (cons (cons 'd nil)))))
However, it wouldn't create (d . nil).
So, is there any way to create such a dot pair?
Show the simplest expression that Lisp will print out when you type the following expression
The question does not ask you to create a dotted pair, but how the dotted pair is printed. I suppose this question aims at showing you that lists are just dotted pairs printed in a special way.
If you write this in a REPL:
'(a b (c . e) (d . nil))
The REPL replies:
(A B (C . E) (D))
You have the exact same output if you write:
'(a . (b . ((c . e) . ((d . nil) . nil))))
Basically, (a b) is the list made of a symbol a in front of a sublist (b), written (a . (b)). Here I am only talking about how forms are read. If you write them directly in the REPL, they will first be read, then evaluated, and in that case you will get an error. That's why in the examples are quoted: an expression being quoted is not evaluated, but returned as-is.
If you want to write code that, when evaluated, produces the cons-cell (0 . 1), you have to write this list:
(cons 0 1)
The above is a list of three elements, which could be written equally:
(cons . (0 . (1 . nil)))
Your interpreter will read this list (a symbol, two numbers) and evaluate the resulting form. That forms produces, at runtime, the following cons cell:
(0 . 1)
I trying to store two colors in list:
(defparameter *colist* '(sdl:*black* sdl:*red*))
Printing sdl:color will return color in sbcl console
(print sdl:*black*) ;;#<LISPBUILDER-SDL:COLOR {1001E980A3}>
But if I try to print color from list I got different result
(print (car *colist*)) ;;LISPBUILDER-SDL:*BLACK*
How can I get from list?
As mentioned in first comment it is necessarily to use (list a b c) form.
I'm new to Lisp and have no idea how to write this...
You give: ("Test" "TEST" "third" "the last")
You get: (("A" . "Test") ("B" . "TEST") ("C" . "third") ("D" . "the last"))
Function: (defun choices (&rest choices))
In C, I can just write a for for this, but Lisp can't +1 to string and loop doesn't have a counter, either... Could someone please give me a sample?
I would write something like this:
(defun choices (&rest choices)
(loop for i from 1 to 26
and item in choices
collect (cons (string (digit-char (+ 9 i) 36))
item)))
The above code has no error checking for more than 26 choices (and you
didn't specify how to handle them if it's not an error).
You could use CHAR-CODE and CODE-CHAR to "increment a character",
but the encoding they provide is not standardized (only some
properties of it are guaranteed). With DIGIT-CHAR in radix 36, we're
guaranteed to get the English alphabet (uppercase) for weights 10 to
35.
And of course, LOOP has a lot of things, including whatever counters you want.
You can concatenate two lists in the way you described by simply doing mapcar+cons:
(mapcar #'cons '("A" "B" "C" "D") '("Test" "TEST" "third" "the last"))
; => (("A" . "Test") ("B" . "TEST") ("C" . "third") ("D" . "the last"))
Since the second list is given, now the problem is only in generating the ABCD list. That can be achieved with loop and code-char:
(loop for i from 65 to 68 collect (string (code-char i)))
; => ("A" "B" "C" "D")
Combining those two into an answer and tailoring it to your specific problem should be easy now.
Say I have a list of cons cells like so:
(setq foo '(("a" . 1) ("b" . 2) ("c" . 3)))
And I'd like to retrieve the value of a particular cons cell by "key name". Is there a function that will let me do this?
E.g.
(get-by-key "a" foo) ;; => 1
Or something similar. Thanks in advance!
Such list is called an association list, or alist for short. Formally, an association list is a list of conses of a key and its associated value.
The assoc function is what you are looking for. It takes a key and an alist as its arguments and returns the first association for the key in the alist in terms of equal:
ELISP> (setq foo '(("a" . 1) ("b" . 2) ("c" . 3)))
(("a" . 1)
("b" . 2)
("c" . 3))
ELISP> (assoc "a" foo)
("a" . 1)
ELISP> (cdr (assoc "a" foo))
1
The assoc-string function is similar to the assoc function but specific to association lists whose keys are strings. In addition to a key and an alist, it can take another optional argument that makes the key comparison case-insensitive:
ELISP> (assoc-string "a" foo)
("a" . 1)
ELISP> (assoc-string "A" foo)
nil
ELISP> (assoc-string "A" foo t)
("a" . 1)
For the full list of association list-related functions, refer to GNU Emacs Lisp Reference Manual.
assoc-default lets you retrieve the value of a particular cons cell by "key name".
ELISP> (setq foo '(("a" . 1) ("b" . 2) ("c" . 3)))
(("a" . 1)
("b" . 2)
("c" . 3))
ELISP> (assoc-default "a" foo)
1
alist-get with the KEY and the ALIST as arguments gives you VALUE associated to the KEY.
E.g.,
(alist-get 'a '((a . 1) (b . 2) (c . 3)))
evaluates to 1.
Comparison is done with eq by default. But its full argument list is:
(alist-get KEY ALIST &optional DEFAULT REMOVE TESTFN)
So one can give:
A DEFAULT value that is returned if there is no match for KEY,
A flag REMOVE that removes the KEY VALUE pair if the new value is DEFAULT in
(setf (alist-get KEY ALIST DEFAULT t) DEFAULT)
A test function TESTFN for comparing KEY with the cars of ALIST
Is there any way by which cons can be implemented in Common LISP using list, append, first, rest etc?
In the following code
(defun my_list (&rest arguments)
`(,#arguments) ; Line 1
)
What does complete line 1 mean ?
First question: No, because cons is the building block for list and append, not the other way around. It is like trying to construct a brick out of houses.
Second question: The backquote syntax is explained in the CLHS (http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/sec_2-4-6.html).
Stylistic comments:
It is spelt "Common Lisp".
Do not use underscores to separate parts of names, but hyphens: my-list.
Do not let parentheses dangle around. Your snippet should be formatted like this:
(defun my-list (&rest arguments)
`(,#arguments)) ; Line 1
Using the backquote syntax outside of macros is usually not a good idea. In this case, it is completely superfluous:
(defun my-list (&rest arguments)
arguments)
Yes, you could in theory define cons in terms of list and append, like so:
(defun cons (car cdr) (append (list car) cdr))
I have the answer for the second question:
for the ,:
if my_symbol = 1
`(my_symbol 2 3) = (my_symbol 2 3), but with the ,:
`(,my_symbol 2 3) = (1 2 3)
The , evaluates the next symbol in a ` statement
Now for the # (which is a symbol, so it needs the , to be activated)
`(,#('a 'b 'c) ('d 'e 'f)) = ('a 'b 'c ('d 'e 'f) )
`(,#('a 'b 'c) ,#('d 'e 'f) ) = ('a 'b 'c 'd 'e 'f)
I hope these examples could help.
So the line 1 is simply extracting the arguments from a list and putting them into another one.
How about this?
(defun cons (a b) '(a . b))
Or, if you desperately need to use lists...
(defun cons (a b) (first (list '(a . b))))