Using lists with Common LISP - lisp

I'm just starting out with LISP, as in, just opened the book, I'm two pages into it. I'm trying to understand what is and what is not an acceptable fn call. Every time I try to execute
(1 2 3 4)
I get an illegal fn call error
same goes for
(cdr (1 2 3 4))
(first (1 2 3 4))
(a b c d)
Are CL programs unable to return lists? How would I go about using these functions or printing a list? I'm using the SLIME implementation if it matters. LISP is very different than anything I've worked with before and I want to be sure I'm getting it conceptually.

You need to quote lists if you are using them as constants. Otherwise, the system will try to call the function 1 on the arguments 2 3 4, which will not work (note that function calls have the same syntax as lists). Your examples should be:
'(1 2 3 4)
(cdr '(1 2 3 4))
(first '(1 2 3 4))
'(a b c d)

Hooo boy.
Look up Practical Common Lisp by Seibel. He's such a nice guy, he put it online for free reading. It's very useful.
Part of the definition of Lisp is this rule:
When a list is seen: Using the first element of the list, apply it to the rest of the list.
But wait: How do you actually enter lists then? There are two functions to do this: QUOTE and LIST.
As an example, let's print a list to the screen on standard out:
(format *standard-output* "~a" '(1 2 3 4))
For format, *standard-output* is aliased to t (well, at least in SBCL!), so usually we see (format t ....

Related

Lisp: difference between 2 and (2)

I am just starting to learn lisp and am a bit puzzled as to why the compiler does not evaluate a simple integer enclosed in parentheses to the value of that integer.
In the REPL, when I do (+ 3 2) I get 5, but when I do (+ 3 (2)) I get an error, whereas I think the value of the expression (2) should also be 2. Clearly there is something important here that I am unable to lay my finger on - what's the difference between 2 and (2)? Any help would be most appreciated since this seems fundamental to the way lisp works.
The supported Common Lisp syntax for list forms is specified here: CLHS Section 3.1.2.1.2 Conses as Forms.
There are four supported types of lists as forms:
special forms like (quote foo)
macro forms like (defun foo (a1 a1) (+ a1 a2))
function forms like (+ 1 2)
lambda forms like ((lambda (a) (+ a 1)) 2)
That's all. Other lists can't be evaluated in Common Lisp.
You should also note that there is a difference between a list, and an form. All forms (+ 1 2) are lists, but not all lists (2) are forms.
When you type something at the prompt, that needs to be a form. The first part of a form almost always needs to be some kind of operator.
If you have the REPL prompt, and you type in the following, you will get an error, because it is just a list, not a form:
(2)
What will work is something that tells the REPL to construct a list:
'(2)
'(aardvark)
...which is really just shorthand for:
(quote (2))
(quote (aardvark))
Which means that it actually is still a list that starts with an operator, and is therefore a form.
The following examples will return results:
(+ 1 2)
(+ 1 (+ 2 3))
Basically, the way to think about it is that each element (except the first) in the list is evaluated, then the first element is executed on those elements. So (+ 1 (+ 2 3)) is first evaluated as 1 which results in 1, and then (+ 2 3) which again first has the arguments evaluated before the operator is executed, which means 2 and 3 is fed to +, which results in 5, and then 1 and 5 is fed to +.
Is you say (+ 1 (2)), it tries to evaluate each element after the first, going 1 evaluates to 1, but (2) evaluates to... nothing, because the first element is not an operator.
By the way, I find it helpful to look at multiple books and sources, because if one states something in a way I don't understand, I can always consult another one to see if it makes more sense. I suggest these:
Practical Common Lisp
Lisp Quickstart
A list of a bunch of books and references
Hope that helps!

push does not work as I would expect it - why?

I am experiencing a behavior of the push function that I don't get. Maybe someone could explain to me why Lisp behaves this way.
Supposed I define a list as a global variable, and then try to push a new value to it using the following code:
(defparameter *primes* '(3 5 7 11))
(push 2 *primes*)
Then *primes* is now (2 3 5 7 11). So far, so good.
Now I try to do the same thing, but without the *primes* variable, i.e.:
(push 2 '(3 5 7 11))
The result is an error message:
EVAL: 3 is not a function name; try using a symbol instead
Now I have two questions:
Why does this not work? I would expect that push returns the list (2 3 5 7 11), why does this not happen? Where am I wrong?
Apart from that, I don't get the error message. What is Lisp trying to tell me with 3 is not a function name? Of course, 3 is not a function name, but I don't try to call a function named 3 anywhere, do I?
Any help is appreciated :-)
If you read the CL Hyperspec for PUSH, you will read that push expects a place.
A place is something like a variable, a structure slot, a class slot, an array access, or similar. Since Lisp uses linked cons cells for lists, it does not make sense to push something in front of a cons cell, without a reference for that.
So above is simple: we can't push to a direct list.
Why this error message?
This gets a bit complicated...
(push 2 '(3 5 7 11))
Is actually:
(push 2 (quote (3 5 7 11))
A function can be a place, it then needs a corresponding setter function. Here the setter is thought to be (setf quote) - that's right, Common Lisp can sometimes have lists as function names, not only symbols.
If we look at the macroexpansion of above:
? (pprint (macroexpand '(push 2 (quote (3 5 7 11)))))
(LET* ((#:G328 2) (#:G327 (3 5 7 11)) (#:G326 (CONS #:G328 '#:G327)))
#:G327
#:G326
(FUNCALL #'(SETF QUOTE) #:G326 #:G327))
You can see that it tries to call the setter. But it also thinks that (3 5 7 11) is a Lisp form.
I give you an example, where it actually works, but we don't use quote, but a real accessor function:
CL-USER 40 > (let ((v (vector (list (list 'a 'b 'c) (list 'd 'e 'f))
(list (list 1 2 3) (list 4 5 6)))))
(print v)
(push 42 (first (aref v 1)))
(print v)
(values))
#(((A B C) (D E F)) ((1 2 3) (4 5 6)))
#(((A B C) (D E F)) ((42 1 2 3) (4 5 6)))
In above first is the getter and CL knows the corresponding setter. The form (aref v 1) is the call and returns the index 1 element of the vector. We are then pushing to the first list of the element.
Your call has a similar structure and (3 5 7 11) is at a similar position as (aref v 1). The Lisp system says that in (3 4 7 11) then number 3 is not a valid function. Which is correct. But the real error was about the push operation. Since the macro could not detect the error, the error gets later detected in the macro expanded code.
I have found only the emacs lisp manual push, but I guess it behaves similar for Common Lisp
— Macro: push element listname
This macro creates a new list whose car is element and whose cdr is the list specified by listname, and saves that list in listname.
So it seems push is modifying its argument listname, which isn't possible with a literal list. To do what you have in mind, one would use cons instead.
To the second part 3 is not a function name, I would say push, or some function inside it, tries to evaluate the literal list. Evaluating (3 5 7 11) means, call the function 3 with arguments 5 7 11. Hence the error message.
Again from emacs, Ctrl-h f push
push is a Lisp macro in `cl.el'.
(push X PLACE)
Insert X at the head of the list stored in PLACE.
Analogous to (setf PLACE (cons X PLACE)), though more careful about
evaluating each argument only once and in the right order. PLACE may
be a symbol, or any generalized variable allowed by `setf'.
setf in turn allows place to be a
symbolic references such as (car x) or (aref x i)
which explains, why push evaluates the second argument.
I think you need CONS in second case:
(cons 2 '(3 5 7 11)) => (2 3 5 7 11)

Can I make a macro that expands into more than one value?

Is there a way to define a racket macro foo so that
(list 1 (foo 2 3) 4)
expands into
(list 1 2 3 4)
?
It's currently not possible (and seems unlikely to change in the near future).
Here's one thread discussing this. See in particular the answer by Matthew Flatt:
allowing splicing of results in function-call
subexpressions would break equivalences that are currently exploited by
macros and the compiler.
As other answers have mentioned, you cannot have a macro expand into more than one value, and have that spliced into the calling context. But you can do something similar using quasiquotation.
Assuming your macro is adapted to return a list instead, you can do this (for your given example):
`(1 ,#(foo 2 3) 4)
Example (tested in Racket):
> `(1 ,#(map sqrt '(2 3)) 4)
'(1 1.4142135623730951 1.7320508075688772 4)

How to watch out for the fact that NREVERSE may modify CARs instead

http://www.aiai.ed.ac.uk/~jeff/lisp/cl-pitfalls states this as one of Common Lisp pitfalls
Destructive functions that you think would modify CDRs might
modify CARs instead. (Eg, NREVERSE.)
I am not sure what precautions I am supposed to take. Usual precaution I can take from the fact that NREVERSE may modify CDRs is to use NREVERSE only when the list (the argument) does not share tail with any other lists that my variables may refer to later (except for the variable I save the return value to). What precaution I should take from the fact that NREVERSE may modify CARs? How is this something to watch out for?
Without any context this is very hard to understand.
Example:
(setq list1 (list 1 2 3 4))
We now have a list of four numbers. The variable list1 points to the first cons.
If we look at a destructive reverse we are talking about an operation which may alter the cons cells. There are different ways how this list can be reversed.
We could for example take the cons cells and reverse those. The first cons cell then is the last. The cdr of that cons cell then has to be changed into NIL.
CL-USER 52 > (setq list1 (list 1 2 3 4))
(1 2 3 4)
CL-USER 53 > (nreverse list1)
(4 3 2 1)
Now our variable list1 still points to the same cons cell, but its cdr has been changed:
CL-USER 54 > list1
(1)
To make sure that the variable points to a reversed list, the programmer then has the duty to update the variable and set it to the result of the nreverse operation. One may also be tempted to exploit the observable result that list1 points to the last cons.
Above is what a Lisp developer usually would expect. Most implementation of reverse seem to work that way. But it is not specified in the ANSI CL standard how nreverse has to be implemented.
So what would it mean to change the CARs instead?
Let's look at an alternative implementation of nreverse:
(defun nreverse1 (list)
(loop for e across (reverse (coerce list 'vector))
for a on list do
(setf (car a) e))
list)
Above function let's the chain of cons cells intact, but changes the car.
CL-USER 56 > (setq list1 (list 1 2 3 4))
(1 2 3 4)
Now let's use the new version, nreverse1.
CL-USER 57 > (nreverse1 list1)
(4 3 2 1)
CL-USER 58 > list1
(4 3 2 1)
Now you see the difference: list1 still points to the whole list.
Summary: one needs to be aware that there are different implementations of nreverse possible. Don't exploit the usual behavior, where a variable then will point to the last cons. Just use the result of nreverse and everything is fine.
Side note: where could the second version have been used?
Some Lisp implementations on Lisp Machines allowed a compact vector-like representation of lists. If on such a Lisp implementation one would nreverse such a list, the implementors could provide an efficient vector-like nreverse.
In any case, be it CAR or CDR of cons cell modified, you shouldn't use NREVERSE if any cons cell (including first cons cell) of passed list may be shared with another list. Use REVERSE instead.
BTW, clisp indeed modifies CARs:
> (let ((a (list 1 2 3 4 5 6 7 8 9 0)))
(nreverse a)
a)
(0 9 8 7 6 5 4 3 2 1)

When to use ' (or quote) in Lisp?

After making it through the major parts of an introductory Lisp book, I still couldn't understand what the special operator (quote) (or equivalent ') function does, yet this has been all over Lisp code that I've seen.
What does it do?
Short answer
Bypass the default evaluation rules and do not evaluate the expression (symbol or s-exp), passing it along to the function exactly as typed.
Long Answer: The Default Evaluation Rule
When a regular (I'll come to that later) function is invoked, all arguments passed to it are evaluated. This means you can write this:
(* (+ a 2)
3)
Which in turn evaluates (+ a 2), by evaluating a and 2. The value of the symbol a is looked up in the current variable binding set, and then replaced. Say a is currently bound to the value 3:
(let ((a 3))
(* (+ a 2)
3))
We'd get (+ 3 2), + is then invoked on 3 and 2 yielding 5. Our original form is now (* 5 3) yielding 15.
Explain quote Already!
Alright. As seen above, all arguments to a function are evaluated, so if you would like to pass the symbol a and not its value, you don't want to evaluate it. Lisp symbols can double both as their values, and markers where you in other languages would have used strings, such as keys to hash tables.
This is where quote comes in. Say you want to plot resource allocations from a Python application, but rather do the plotting in Lisp. Have your Python app do something like this:
print("'(")
while allocating:
if random.random() > 0.5:
print(f"(allocate {random.randint(0, 20)})")
else:
print(f"(free {random.randint(0, 20)})")
...
print(")")
Giving you output looking like this (slightly prettyfied):
'((allocate 3)
(allocate 7)
(free 14)
(allocate 19)
...)
Remember what I said about quote ("tick") causing the default rule not to apply? Good. What would otherwise happen is that the values of allocate and free are looked up, and we don't want that. In our Lisp, we wish to do:
(dolist (entry allocation-log)
(case (first entry)
(allocate (plot-allocation (second entry)))
(free (plot-free (second entry)))))
For the data given above, the following sequence of function calls would have been made:
(plot-allocation 3)
(plot-allocation 7)
(plot-free 14)
(plot-allocation 19)
But What About list?
Well, sometimes you do want to evaluate the arguments. Say you have a nifty function manipulating a number and a string and returning a list of the resulting ... things. Let's make a false start:
(defun mess-with (number string)
'(value-of-number (1+ number) something-with-string (length string)))
Lisp> (mess-with 20 "foo")
(VALUE-OF-NUMBER (1+ NUMBER) SOMETHING-WITH-STRING (LENGTH STRING))
Hey! That's not what we wanted. We want to selectively evaluate some arguments, and leave the others as symbols. Try #2!
(defun mess-with (number string)
(list 'value-of-number (1+ number) 'something-with-string (length string)))
Lisp> (mess-with 20 "foo")
(VALUE-OF-NUMBER 21 SOMETHING-WITH-STRING 3)
Not Just quote, But backquote
Much better! Incidently, this pattern is so common in (mostly) macros, that there is special syntax for doing just that. The backquote:
(defun mess-with (number string)
`(value-of-number ,(1+ number) something-with-string ,(length string)))
It's like using quote, but with the option to explicitly evaluate some arguments by prefixing them with comma. The result is equivalent to using list, but if you're generating code from a macro you often only want to evaluate small parts of the code returned, so the backquote is more suited. For shorter lists, list can be more readable.
Hey, You Forgot About quote!
So, where does this leave us? Oh right, what does quote actually do? It simply returns its argument(s) unevaluated! Remember what I said in the beginning about regular functions? Turns out that some operators/functions need to not evaluate their arguments. Such as IF -- you wouldn't want the else branch to be evaluated if it wasn't taken, right? So-called special operators, together with macros, work like that. Special operators are also the "axiom" of the language -- minimal set of rules -- upon which you can implement the rest of Lisp by combining them together in different ways.
Back to quote, though:
Lisp> (quote spiffy-symbol)
SPIFFY-SYMBOL
Lisp> 'spiffy-symbol ; ' is just a shorthand ("reader macro"), as shown above
SPIFFY-SYMBOL
Compare to (on Steel-Bank Common Lisp):
Lisp> spiffy-symbol
debugger invoked on a UNBOUND-VARIABLE in thread #<THREAD "initial thread" RUNNING {A69F6A9}>:
The variable SPIFFY-SYMBOL is unbound.
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.
(SB-INT:SIMPLE-EVAL-IN-LEXENV SPIFFY-SYMBOL #<NULL-LEXENV>)
0]
Because there is no spiffy-symbol in the current scope!
Summing Up
quote, backquote (with comma), and list are some of the tools you use to create lists, that are not only lists of values, but as you seen can be used as lightweight (no need to define a struct) data structures!
If you wish to learn more, I recommend Peter Seibel's book Practical Common Lisp for a practical approach to learning Lisp, if you're already into programming at large. Eventually on your Lisp journey, you'll start using packages too. Ron Garret's The Idiot's Guide to Common Lisp Packages will give you good explanation of those.
Happy hacking!
It says "don't evaluate me". For example, if you wanted to use a list as data, and not as code, you'd put a quote in front of it. For example,
(print '(+ 3 4)) prints "(+ 3 4)", whereas
(print (+ 3 4)) prints "7"
Other people have answered this question admirably, and Matthias Benkard brings up an excellent warning.
DO NOT USE QUOTE TO CREATE LISTS THAT YOU WILL LATER MODIFY. The spec allows the compiler to treat quoted lists as constants. Often, a compiler will optimize constants by creating a single value for them in memory and then referencing that single value from all locations where the constant appears. In other words, it may treat the constant like an anonymous global variable.
This can cause obvious problems. If you modify a constant, it may very well modify other uses of the same constant in completely unrelated code. For example, you may compare some variable to '(1 1) in some function, and in a completely different function, start a list with '(1 1) and then add more stuff to it. Upon running these functions, you may find that the first function doesn't match things properly anymore, because it's now trying to compare the variable to '(1 1 2 3 5 8 13), which is what the second function returned. These two functions are completely unrelated, but they have an effect on each other because of the use of constants. Even crazier bad effects can happen, like a perfectly normal list iteration suddenly infinite looping.
Use quote when you need a constant list, such as for comparison. Use list when you will be modifying the result.
One answer to this question says that QUOTE “creates list data structures”. This isn't quite right. QUOTE is more fundamental than this. In fact, QUOTE is a trivial operator: Its purpose is to prevent anything from happening at all. In particular, it doesn't create anything.
What (QUOTE X) says is basically “don't do anything, just give me X.” X needn't be a list as in (QUOTE (A B C)) or a symbol as in (QUOTE FOO). It can be any object whatever. Indeed, the result of evaluating the list that is produced by (LIST 'QUOTE SOME-OBJECT) will always just return SOME-OBJECT, whatever it is.
Now, the reason that (QUOTE (A B C)) seems as if it created a list whose elements are A, B, and C is that such a list really is what it returns; but at the time the QUOTE form is evaluated, the list has generally already been in existence for a while (as a component of the QUOTE form!), created either by the loader or the reader prior to execution of the code.
One implication of this that tends to trip up newbies fairly often is that it's very unwise to modify a list returned by a QUOTE form. Data returned by QUOTE is, for all intents and purposes, to be considered as part of the code being executed and should therefore be treated as read-only!
The quote prevents execution or evaluation of a form, turning it instead into data. In general you can execute the data by then eval'ing it.
quote creates list data structures, for example, the following are equivalent:
(quote a)
'a
It can also be used to create lists (or trees):
(quote (1 2 3))
'(1 2 3)
You're probably best off getting an introductary book on lisp, such as Practical Common Lisp (which is available to read on-line).
In Emacs Lisp:
What can be quoted ?
Lists and symbols.
Quoting a number evaluates to the number itself:
'5 is the same as 5.
What happens when you quote lists ?
For example:
'(one two) evaluates to
(list 'one 'two) which evaluates to
(list (intern "one") (intern ("two"))).
(intern "one") creates a symbol named "one" and stores it in a "central" hash-map, so anytime you say 'one then the symbol named "one" will be looked up in that central hash-map.
But what is a symbol ?
For example, in OO-languages (Java/Javascript/Python) a symbol could be represented as an object that has a name field, which is the symbol's name like "one" above, and data and/or code can be associated with it this object.
So an symbol in Python could be implemented as:
class Symbol:
def __init__(self,name,code,value):
self.name=name
self.code=code
self.value=value
In Emacs Lisp for example a symbol can have 1) data associated with it AND (at the same time - for the same symbol) 2) code associated with it - depending on the context, either the data or the code gets called.
For example, in Elisp:
(progn
(fset 'add '+ )
(set 'add 2)
(add add add)
)
evaluates to 4.
Because (add add add) evaluates as:
(add add add)
(+ add add)
(+ 2 add)
(+ 2 2)
4
So, for example, using the Symbol class we defined in Python above, this add ELisp-Symbol could be written in Python as Symbol("add",(lambda x,y: x+y),2).
Many thanks for folks on IRC #emacs for explaining symbols and quotes to me.
Code is data and data is code. There is no clear distinction between them.
This is a classical statement any lisp programmer knows.
When you quote a code, that code will be data.
1 ]=> '(+ 2 3 4)
;Value: (+ 2 3 4)
1 ]=> (+ 2 3 4)
;Value: 9
When you quote a code, the result will be data that represent that code. So, when you want to work with data that represents a program you quote that program. This is also valid for atomic expressions, not only for lists:
1 ]=> 'code
;Value: code
1 ]=> '10
;Value: 10
1 ]=> '"ok"
;Value: "ok"
1 ]=> code
;Unbound variable: code
Supposing you want to create a programming language embedded in lisp -- you will work with programs that are quoted in scheme (like '(+ 2 3)) and that are interpreted as code in the language you create, by giving programs a semantic interpretation. In this case you need to use quote to keep the data, otherwise it will be evaluated in external language.
When we want to pass an argument itself instead of passing the value of the argument then we use quote. It is mostly related to the procedure passing during using lists, pairs and atoms
which are not available in C programming Language ( most people start programming using C programming, Hence we get confused)
This is code in Scheme programming language which is a dialect of lisp and I guess you can understand this code.
(define atom? ; defining a procedure atom?
(lambda (x) ; which as one argument x
(and (not (null? x)) (not(pair? x) )))) ; checks if the argument is atom or not
(atom? '(a b c)) ; since it is a list it is false #f
The last line (atom? 'abc) is passing abc as it is to the procedure to check if abc is an atom or not, but when you pass(atom? abc) then it checks for the value of abc and passses the value to it. Since, we haven't provided any value to it
Quote returns the internal representation of its arguments. After plowing through way too many explanations of what quote doesn't do, that's when the light-bulb went on. If the REPL didn't convert function names to UPPER-CASE when I quoted them, it might not have dawned on me.
So. Ordinary Lisp functions convert their arguments into an internal representation, evaluate the arguments, and apply the function. Quote converts its arguments to an internal representation, and just returns that. Technically it's correct to say that quote says, "don't evaluate", but when I was trying to understand what it did, telling me what it doesn't do was frustrating. My toaster doesn't evaluate Lisp functions either; but that's not how you explain what a toaster does.
Anoter short answer:
quote means without evaluating it, and backquote is quote but leave back doors.
A good referrence:
Emacs Lisp Reference Manual make it very clear
9.3 Quoting
The special form quote returns its single argument, as written, without evaluating it. This provides a way to include constant symbols and lists, which are not self-evaluating objects, in a program. (It is not necessary to quote self-evaluating objects such as numbers, strings, and vectors.)
Special Form: quote object
This special form returns object, without evaluating it.
Because quote is used so often in programs, Lisp provides a convenient read syntax for it. An apostrophe character (‘'’) followed by a Lisp object (in read syntax) expands to a list whose first element is quote, and whose second element is the object. Thus, the read syntax 'x is an abbreviation for (quote x).
Here are some examples of expressions that use quote:
(quote (+ 1 2))
⇒ (+ 1 2)
(quote foo)
⇒ foo
'foo
⇒ foo
''foo
⇒ (quote foo)
'(quote foo)
⇒ (quote foo)
9.4 Backquote
Backquote constructs allow you to quote a list, but selectively evaluate elements of that list. In the simplest case, it is identical to the special form quote (described in the previous section; see Quoting). For example, these two forms yield identical results:
`(a list of (+ 2 3) elements)
⇒ (a list of (+ 2 3) elements)
'(a list of (+ 2 3) elements)
⇒ (a list of (+ 2 3) elements)
The special marker ‘,’ inside of the argument to backquote indicates a value that isn’t constant. The Emacs Lisp evaluator evaluates the argument of ‘,’, and puts the value in the list structure:
`(a list of ,(+ 2 3) elements)
⇒ (a list of 5 elements)
Substitution with ‘,’ is allowed at deeper levels of the list structure also. For example:
`(1 2 (3 ,(+ 4 5)))
⇒ (1 2 (3 9))
You can also splice an evaluated value into the resulting list, using the special marker ‘,#’. The elements of the spliced list become elements at the same level as the other elements of the resulting list. The equivalent code without using ‘`’ is often unreadable. Here are some examples:
(setq some-list '(2 3))
⇒ (2 3)
(cons 1 (append some-list '(4) some-list))
⇒ (1 2 3 4 2 3)
`(1 ,#some-list 4 ,#some-list)
⇒ (1 2 3 4 2 3)