I am learning LISP using PC Scheme TI implementation and from the book 'Structure and Interpretation of Computer Programs'. PC scheme doesn't seem to have a 'nil' variable
[VM ERROR encountered!] Variable not defined in current environment
NIL
Instead '()' seems to work.
[55] (define one-through-four (list 1 2 3 4 ()))
ONE-THROUGH-FOUR
Do both have the same meaning? What is the correct way to use a sequence of no elements in the PC scheme dialect?
Thanks.
When you say that this dialect "does not have a NIL variable", you are right in two ways. Not only does not nil exist, but it seems to be treated as an ordinary symbol that you can use as a variable. It says "Variable not defined".
In Lisp dialects where nil has a special meaning, nil usually cannot be used as a variable.
nil is equivalent to () only in "classical" Lisps (my term). By this I mean Lisps that are related by ancestry or imitation to the original John MacCarthy Lisp. Emacs Lisp and Common Lisp are that way. The classical Lisps use nil as the list terminator: i.e. (cons 1 nil) producing the list (1)
Scheme is not a classical Lisp in this sense. There is no nil. It uses () as the printed notation for an empty list and when you want that value in an expression, it is quoted, just like a non-empty list literal: '(). In Scheme, (cons 1 nil) is written (cons 1 '()). Boolean false is represented by an object which is notated #f. An empty list is true not false, so (if '() 1 2) yields 1, not 2 like in a classical Lisp. Neither '() nor #f are symbols.
Scheme is also case-sensitive. Even if you do have a variable NIL in Scheme, it has nothing to do with nil. You can use both as variable names.
The SICP text causes confusion on this topic by, in its early chapters, making references to a variable called nil which holds the value of '(). There is no such variable in Scheme; you have to make it yourself if you want those examples to work. This is an unfortunate aspect of the textbook.
If you define a variable nil whose value is the object '(), so that that Chapter 2 code from SICP works, it is still not equivalent to an empty list the way it is in a classical Lisp, because in a classical Lisp, nil and () are equivalent notations for a symbol. The symbol nil itself is the empty list, and vice versa. It is not the name of a variable which merely holds a list. And so the quote expression 'nil also evaluates to the empty list! Whereas in scheme 'nil evaluates to the ordinary symbol nil even if you've defined it as a variable holding the empty list.
Regarding the second question, "() seems to work, do both have the same meaning?". The "same meaning" aspect is covered above: no, not the same meaning in Scheme. As far as it working, consider the following quote from the R5RS Scheme Report:
Note: In many dialects of Lisp, the empty combination, (), is a legitimate expression. In Scheme, combinations must have at least one subexpression, so () is not a syntactically valid expression. [4.1.3 Procedure Calls]
Therefore this loose treatment of () as valid expression that produces the empty list appears to be a PC Scheme extension of behavior, not standard Scheme. It is accepting an expression which is not a syntactically valid Scheme expression.
Related
I would have thought this would work:
(defun list-of-things (thing1 thing2 thing3)
"returns a ???"
'(thing1 thing2 thing3))
But this is actually what is needed to return a list:
(defun list-of-things (thing1 thing2 thing3)
"returns a list"
(list thing1 thing2 thing3))
Those are two different things, and a central concept in Lisp languages.
The syntax '(a b c) is a shorthand for (quote (a b c)) and quote is a special form that returns its argument unevaluated. In that case, it would be list, containing three symbols.
On the other hand, list is a normal function, it evaluates its arguments and return the list of their values.
To go a bit more in-depth: before evaluating any expression, the code has to be read. The part that is very specific to Lisp (and, in fact, even more so with Common Lisp) is that the "parser" is actually just a Lisp function, returning Lisp objects. Those objects are then given to the "evaluator", which evaluates them:
When reading the characters '(thing1 thing2 thing3), the reader knows that ' is a reader-macro, and so it reads (quote (thing1 thing2 thing3)). This is a list of two elements, a symbol and another list of three symbols. This list is then given to the evaluator: it knows that quote is a special form that returns its argument unevaluated, and so it simply returns the list (thing1 thing2 thing3), given to it by the reader.
On the other hand, when reading (list thing1 thing2 thing3), the reader also reads this as a list (this time, containing 4 symbols) that it then gives to the evaluator. Now, the evaluator sees that the first symbol is list, a function, and so it evaluates the arguments (i.e. it determines what the symbols thing1 ... are bound to), passes them to the list functions, etc.
All this is possible because Lisp code is defined in terms of Lisp objects (such as lists, etc). After the "parsing" (actually called reading) phase, the evaluator is really given an actual Lisp object to evaluate. Things are of course slightly more complicated when talking about compilation, etc, but the general idea is the same. The quote operator, abbreviated ', is a way to "directly" access the thing created by the reader, and to "bypass" evaluation.
Lisp evaluation rules
You need to understand the evaluation rules of Common Lisp first:
the symbol a is a variable and evaluates to its value
the list (operator ... ) is a form. There are four types of forms: function call, macro form, special form, lambda form
everything else evaluates to itself: numbers, strings, arrays, hash tables, characters, CLOS objects, structures, ...
There is a fixed number of special operators. One is QUOTE. (QUOTE ...) means that the object inside does not get evaluated. '(...) is another notation for (QUOTE ...) - it's easier to write.
So symbols and lists have a role: they are variables and forms.
What if you want to have literal symbols and literal lists? Answer: you have to quote them.
Remember: If you quote a list, then the whole list including its elements is literal data and not evaluated.
Examples:
A global variable defined:
CL-USER 18 > (defvar *a* 42)
*A*
The symbol *a* is quoted and thus the form (QUOTE *A*) evaluates to the symbol:
CL-USER 19 > '*a*
*A*
Inside quoted lists everything is literal data and not evaluated.
CL-USER 20 > '(*a*) ; same as (QUOTE (*A*))
(*A*)
The unquoted symbol is evaluated as a variable:
CL-USER 21 > *a*
42
A function call has all its arguments evaluated:
CL-USER 22 > (list *a*)
(42)
A backquote expression allows certain elements in a list to be evaluated using the comma prefix:
CL-USER 23 > `(41 ,*a* (+ 1 *a*) (+ 1 ,*a*) ,(+ 2 *a*))
(41 42 (+ 1 *A*) (+ 1 42) 44)
Summary
When you want to return a list from a function, you can:
return a fixed literal list
or compute a new list based on some objects by constructing the list with the usual operators: CONS, LIST, APPEND, ...
or use a backquote expression which gets expanded by the Lisp reader into an implementation specific version of 2.
The list function is used for creating lists. They called LISP because it’s for LISt Processing. Also, because Lisp functions are written as lists, they can be processed exactly like list.
These all work:
(defun testcaseexpr (thecase)
(case thecase
('foo (format t "matched foo"))
(bar (format t "matched bar"))
((funk) (format t "matched funky"))))
Which of these three expressions is considered the idiomatic way? And perhaps as a side point, why are they all working, when clearly they are not the same syntax. In fact in other contexts they have different semantics completely. A list (funk) is certainly not the same as a quoted atom, 'foo. Yet just passing in the words foo bar and funk all work the same.
First, note that you've actually only got two cases here. 'foo is expanded by the reader as (quote foo), so your code is equivalent to
(defun testcaseexpr (thecase)
(case thecase
((quote foo) (format t "matched foo"))
(bar (format t "matched bar"))
((funk) (format t "matched funky"))))
wherein the first and third cases have the same structure; the keys part of the clause is a list of objects.
Perhaps this question is off-topic, since it's asking for the “best”, and that might be primarily opinion based. I agree with the points made in wvxvw's answer, but I tend to use the style you've shown in the third case almost exclusively. I've got a couple reasons for this:
It's the most general form.
It's the most general form. In the documentation for case, we read that in an normal-clause ::= (keys form*) keys is a designator for a list of keys. This means that a clause like (2 (print 'two)) is equivalent to ((2) (print 'two)). You never lose anything by using a list instead of a non-list, but if you have some clauses with multiple objects and some with single objects, you'll have consistent syntax for all of them. E.g., you can have
(case operator
((and or) ...)
((if iff) ...)
((not) ...))
It's harder to mess up.
It makes it harder to mess up the special cases of t and otherwise. The documentation says about keys that (emphasis added):
keys—a designator for a list of objects. In the case of case, the
symbols t and otherwise may not be used as the keys designator. To
refer to these symbols by themselves as keys, the designators (t) and
(otherwise), respectively, must be used instead.
In practice, some implementations will let you use t and otherwise as keys in normal-clauses, even though it seems like this shouldn't be allowed. E.g., in SBCL:
CL-USER> (macroexpand-1 '(case keyform
(otherwise 'a)
(otherwise 'b)))
(LET ((#:G962 KEYFORM))
(DECLARE (IGNORABLE #:G962))
(COND ((EQL #:G962 'OTHERWISE) NIL 'A)
(T NIL 'B)))
Using explicit lists removes any ambiguity about what you're trying to do. Even though t and otherwise are called out specifically, keys is a list designator, which means that nil (an atom and a list) needs some special consideration. Will the following code produce a or b? (Can you tell without testing it or checking the spec? This case is actually highlighted in the examples.)
(case nil
(nil 'a)
(otherwise 'b))
It returns b. To return a, the first normal-clause would have to be ((nil) 'a).
Conclusion
If you always make sure that keys is a list, you'll:
end up with more consistent looking code;
avoid edge-case bugs (especially if you're writing macros that expand into case); and
make your intentions clearer.
Second :)
First is never used, unless you expand a macro into something like it by accident, and third is used when you have more then one matching symbol (a fall-through case).
I'm trying to learn and understand the Lisp programming language to a deep level. The function + evaluates its arguments in applicative order:
(+ 1 (+ 1 2))
(+ 1 2) will be evaluated and then (+ 1 3) will be evaluated, but the if function works differently:
(if (> 1 2) (not-defined 1 2) 1)
As the form (not-defined 1 2) isn't evaluated, the program doesn't break.
How can the same syntax lead to different argument evaluation? How is the if function defined so that its arguments aren't evaluated?
if is a special operator, not an ordinary function.
This means that the normal rule that the rest elements in the compound form are evaluated before the function associated with the first element is invoked is not applicable (in that it is similar to macro forms).
The way this is implemented in a compiler and/or an interpreter is that one looks at the compound form and decides what to do with it based on its first element:
if it is a special operator, it does its special thing;
if it is a macro, its macro-function gets the whole form;
otherwise it is treated as a function - even if no function is defined.
Note that some special forms can be defined as macros expanding to other special forms, but some special forms must actually be present.
E.g., one can define if in terms of cond:
(defmacro my-if (condition yes no)
`(cond (,condition ,yes)
(t ,no)))
and vice versa (much more complicated - actually, cond is a macro, usually expanding into a sequence of ifs).
PS. Note that the distinction between system-supplied macros and special operators, while technically crisp and clear (see special-operator-p and macro-function), is ideologically blurred because
An implementation is free to implement a Common Lisp special operator
as a macro. An implementation is free to implement any macro operator
as a special operator, but only if an equivalent definition of the
macro is also provided.
sds's answer answers this question well, but there are a few more general aspects that I think are worth mentioning. As that answer and others have pointed out, if, is built into the language as a special operator, because it really is a kind of primitive. Most importantly, if is not a function.
That said, the functionality of if can be achieved using just functions and normal function calling where all the arguments are evaluated. Thus, conditionals can be implemented in the lambda calculus, on which languages in the family are somewhat based, but which doesn't have a conditional operator.
In the lambda calculus, one can define true and false as functions of two arguments. The arguments are presumed to be functions, and true calls the first of its arguments, and false calls the second. (This is a slight variation of Church booleans which simply return their first or second argument.)
true = λ[x y].(x)
false = λ[x y].(y)
(This is obviously a departure from boolean values in Common Lisp, where nil is false and anything else is true.) The benefit of this, though, is that we can use a boolean value to call one of two functions, depending on whether the boolean is true or false. Consider the Common Lisp form:
(if some-condition
then-part
else-part)
If were were using the booleans as defined above, then evaluating some-condition will produce either true or false, and if we were to call that result with the arguments
(lambda () then-part)
(lambda () else-part)
then only one of those would be called, so only one of then-part and else-part would actually be evaluated. In general, wrapping some forms up in a lambda is a good way to be able delay the evaluation of those forms.
The power of the Common Lisp macro system means that we could actually define an if macro using the types of booleans described above:
(defconstant true
(lambda (x y)
(declare (ignore y))
(funcall x)))
(defconstant false
(lambda (x y)
(declare (ignore x))
(funcall y)))
(defmacro new-if (test then &optional else)
`(funcall ,test
(lambda () ,then)
(lambda () ,else)))
With these definitions, some code like this:
(new-if (member 'a '(1 2 3))
(print "it's a member")
(print "it's not a member"))))
expands to this:
(FUNCALL (MEMBER 'A '(1 2 3)) ; assuming MEMBER were rewritten
(LAMBDA () (PRINT "it's a member")) ; to return `true` or `false`
(LAMBDA () (PRINT "it's not a member")))
In general, if there is some form and some of the arguments aren't getting evaluated, then the (car of the) form is either a Common Lisp special operator or a macro. If you need to write a function where the arguments will be evaluated, but you want some forms not to be evaluated, you can wrap them up in lambda expressions and have your function call those anonymous functions conditionally.
This is a possible way to implement if, if you didn't already have it in the language. Of course, modern computer hardware isn't based on a lambda calculus interpreter, but rather on CPUs that have test and jump instructions, so it's more efficient for the language to provide if a primitive and to compile down to the appropriate machine instructions.
Lisp syntax is regular, much more regular than other languages, but it's still not completely regular: for example in
(let ((x 0))
x)
let is not the name of a function and ((x 0)) is not a bad form in which a list that is not a lambda form has been used in the first position.
There are quite a few "special cases" (still a lot less than other languages, of course) where the general rule of each list being a function call is not followed, and if is one of them. Common Lisp has quite a few "special forms" (because absolute minimality was not the point) but you can get away for example in a scheme dialect with just five of them: if, progn, quote, lambda and set! (or six if you want macros).
While the syntax of Lisp is not totally uniform the underlying representation of code is however quite uniform (just lists and atoms) and the uniformity and simplicity of representation is what facilitates metaprogramming (macros).
"Lisp has no syntax" is a statement with some truth in it, but so it's the statement "Lisp has two syntaxes": one syntax is what uses the reader to convert from character streams to s-expressions, another syntax is what uses the compiler/evaluator to convert from s-expressions to executable code.
It's also true that Lisp has no syntax because neither of those two levels is fixed. Differently from other programming languages you can customize both the first step (using reader macros) and the second step (using macros).
It would not make any sense to do so. Example: (if (ask-user-should-i-quit) (quit) (continue)). Should that quit, even though the user does not want to?
IF is not a function in Lisp. It is a special built-in operator. Lisp a several built-in special operators. See: Special Forms. Those are not functions.
The arguments are not evaluated as for functions, because if is a special operator. Special operators can be evaluated in any arbitrary way, that's why they're called special.
Consider e.g.
(if (not (= x 0))
(/ y x))
If the division was always evaluated, there could be a division by zero error which obviously was not intended.
If isn't a function, it's a special form. If you wanted to implement similar functionality yourself, you could do so by defining a macro rather than a function.
This answer applies to Common Lisp, but it'll probably the same for most other Lisps (though in some if may be a macro rather than a special form).
Does emacs lisp have a function that provides a unique object identifier, such as e.g. a memory address? Python has id(), which returns an integer guaranteed to be unique among presently existing objects. What about elisp?
The only reason I know for wanting a function like id() is to compare objects, and ensure that they only compare equal if they are the same (as in, in the same memory location). In Lisps, this is done a bit differently from in Python:
In most lisps, including elisp, there are several different notions of equality. The most expensive, and weakest equivalence is equal. This is not what you want, since two lists (say) are equal if they have the same elements (tested recursively with equal). As such
(equal (list 1 2) (list 1 2)) => T
is true. At the other end of the spectrum is eq, which tests "identity" rather than equality:
(eq (list 1 2) (list 1 2)) => NIL
This is what you want, I think.
So, it seems that Python works by providing one equality test, and then a function that gives you a memory location for each object, which then can be compared as integers. In Elisp (and at least Common Lisp too), on the other hand, there is more than one meaning of "equality".
Note, there is also "eql", which lies somewhere between the two.
(EDIT: My original answer probably wasn't clear enough about why the distinction between eq and equal probably solves the problem the original poster was having)
There is no such feature in Emacs Lisp, as far as I know. If you only need equality, use eq, which performs a pointer comparison behind the scenes.
If you need a printable unique identifier, use gensym from the cl package.
If you need a unique identifier to serve as an index in a data structure, use gensym (or maintain your own unique id — gensym is simpler and less error-prone).
Some languages bake a unique id into every object, but this has a cost: either every object needs extra memory to store the id, or the id is derived from the address of the object, which precludes modifying the address. Python chooses to pay the cost, Emacs chooses not to.
My whole point in asking the question was that I was looking for a way to distinguish between the printed representations of different symbols that have the same name. Thanks to the elisp manual, I've discovered the variable print-gensym, which, when non-nil, causes #: to be prepended to uninterned symbols printed. Moreover, if the same call to print prints the same uninterned symbol more than once, it will mark the first one with #N= and subsequent ones with `#N#. This is exactly the kind of functionality I was looking for. For example:
(setq print-gensym t)
==> t
(make-symbol "foo")
==> #:foo
(setq a (make-symbol "foo"))
==> #:foo
(cons a a)
==> (#1=#:foo . #1#)
(setq b (make-symbol "foo"))
==> #:foo
(cons a b)
==> (#:foo . #:foo)
The #: notation works for read as well:
(setq a '#:foo)
==> #:foo
(symbol-name a)
==> "foo"
Note the ' on '#:foo--the #: notation is a symbol-literal. Without the ', the uninterned symbol is evaluated:
(symbol-name '#:foo)
==> "foo"
(symbol-name #:foo)
==> (void-variable #:foo)
Consider this piece of code:
(defvar lst '(1 1))
(defmacro get-x (x lst)
`(nth ,x ,lst))
(defun get-y (y lst)
(nth y lst))
Now let us assume that I want to change the value of the elements of the list called lst, the car with get-x and the cdr with get-y.
As I try to change the value with get-x (with setf) everything goes fine but if I try it with get-y it signals an error (shortened):
; caught STYLE-WARNING:
; undefined function: (SETF GET-STUFF)
Why does this happen?
I myself suspect that this happens because the macro simply expands and the function nth simply returns a reference to the value of an element in the list and the function on the other hand evaluates the function-call to nth and returns the value of the referenced value (sounds confusing).
Am I correct in my suspicions?
If I am correct then how will one know what is simply a reference to a value and an actual value?
The error does not happen with the macro version, because, as you assumed, the expression (setf (get-x some-x some-list) some-value) will be expanded (at compile-time) into something like (setf (nth some-x some-list) some-value) (not really, but the details of setf-expansion are complex), and the compiler knows, how to deal with that (i.e., there is a suitable setf expander defined for function nth).
However, in the case of get-y, the compiler has no setf expander, unless you provide one. The easiest way to do so would be
(defun (setf get-y) (new-value x ls) ; Note the function's name: setf get-y
(setf (nth x ls) new-value))
Note, that there are a few conventions regarding setf-expanders:
The new value is always provided as the first argument to the setf function
All setf functions are supposed to return the new value as their result (as this is, what the entire setf form is supposed to return)
There is, BTW, no such concept as a "reference" in Common Lisp (at least not in the C++ sense), though there once were Lisp dialects which had locatives. Generalized place forms (ie., setf and its machinery) work very differently from plain C++ style references. See the CLHS, if you are curious about the details.
SETF is a macro.
The idea is that to set and read elements from data structures are two operations, but usually require two different names (or maybe even something more complex). SETF now enables you to use just one name for both:
(get-something x)
Above reads a datastructure. The inverse then simply is:
(setf (get-something x) :foobar)
Above sets the datastructure at X with :FOOBAR.
SETF does not treat (get-something x) as a reference or something like that. It just has a database of inverse operations for each operation. If you use GET-SOMETHING, it knows what the inverse operation is.
How does SETF know it? Simple: you have to tell it.
For The NTH operation, SETF knows how to set the nth element. That's builtin into Common Lisp.
For your own GET-Y operation SETF does not have that information. You have to tell it. See the Common Lisp HyperSpec for examples. One example is to use DEFUN and (SETF GET-Y) as a function name.
Also note following style problems with your example:
lst is not a good name for a DEFVAR variable. Use *list* as a name to make clear that it is a special variable declared by DEFVAR (or similar).
'(1 2) is a literal constant. If you write a Common Lisp program, the effects of changing it are undefined. If you want to change a list later, you should cons it with LIST or something like COPY-LIST.