In the following Lisp REPL interaction:
CL-USER> (defparameter *unison* 0)
*UNISON*
CL-USER> (member *unison* '(*unison*))
NIL
why is nil returned?
Because the *unison* variable is bound to 0, and the list has only a *unison* symbol since it's quoted. Try this in comparison:
(member *unison* (list *unison*))
This will actually evaluate the second *unison* which returns 0, resulting in a (0) list.
Related
I have a struct spider:
(defstruct spider omegas values k)
And an instance spider:
(set '*spider* (make-spider
:omegas '()
:values (list *input*)
:k '(#'omegashift #'dec #'dupval '((0 . #'dec) (1 . #'inc) (2 . #'dec)))))
But when I run the expression: (listp (car (spider-k *spider*)) on Emacs and SBCL (and SLIME is involved but I'm not sure what it is.)
The REPL returns T. This is obviously confusing as (car (spider-k *spider*) correctly returns #'OMEGASHIFT and (listp (function OMEGASHIFT)) properly returns NIL.
Why is (listp (car (spider-k *spider*)) true? Shouldn't it be false?
#'omegashift is a reader-macro that expands to the list (function omegashift).
When you evaluate (function omegashift) you get a function, but you're not evaluating it because you quoted the list. So you're just getting the list that the reader-macro expands to.
You'd see the same thing if you did (listp (car '('foo))). 'foo expands to the list (quote foo). This evaluates to the symbol foo, but the quote before the list prevents evaluation.
To get functions instead of lists, you need to evaluate the function expressions. You can do this by calling the function list rather than quoting a list.
(setq *spider* (make-spider
:omegas '()
:values (list *input*)
:k (list #'omegashift #'dec #'dupval (list (cons 0 #'dec) (cons 1 #'inc) (cons 2 #'dec)))))
You can also use backquote to simplify this:
(setq *spider* (make-spider
:omegas '()
:values (list *input*)
:k `(,#'omegashift ,#'dec ,#'dupval '((0 . ,#'dec) (1 . ,#'inc) (2 . ,#'dec)))))
Inside a backquoted expression, you use comma to mark the sub-expressions that you want to evaluate.
BTW, you should use setq to assign variables, not set with a quoted symbol. They're equivalent for global variables, but you can't use set with a local variable.
I'm trying to write a macro to return a variable's name and value in common lisp. How do I return the name and value of a variable in a LISP macro?
So something like
(RETURNVAL (x))
would return
x has value 5
(defmacro returnval (x)
`(format t "~a has value ~a." ',x ,x))
CL-USER> (defparameter *forty-two* 42)
*FORTY-TWO*
CL-USER> (returnval *forty-two*)
*FORTY-TWO* has value 42.
NIL
CL-USER> (let ((x 5))
(returnval x))
X has value 5.
NIL
If you really want that extra set of parens around the form, you can do that, too:
(defmacro returnval ((x))
`(format t "~a has value ~a." ',x ,x))
CL-USER> (returnval (*forty-two*))
*FORTY-TWO* has value 42.
NIL
CL-USER> (let ((x 5))
(returnval (x)))
X has value 5.
NIL
I am new to lisp and I'm trying to a simple check to see if a list is empty. For test purposes i created this test function:
(defun test (list)
(if (null (caddr list))
(make-node 1)
(caddr list)))
if uses the make-node function defined as:
(defun make-node (atm)
(cons atm `(`() `())))
when running (make-node 6) I get:
(6 (QUOTE NIL) (QUOTE NIL))
which is what I want.
i then call (test (make-node 6)) which i then get:
(QUOTE NIL)
which is the (caddr list) from test. if you run (null (QUOTE NIL)) you get T which is what i want to get but when i run it from the given test function i receive NIL.
So my question is why when i check if this is null why do i get NIL instead of T?
When you evaluate (null (quote nil)), (quote nil) is evaluated, resulting in nil being used as the argument for the function null.
However when you evaluate something like (null (function-returning-quote-nil)), function-returning-quote-nil is evaluated, resulting in the list (quote nil) which is then used as the argument for the function null without further evaluation.
Compare to the difference between
(null (quote nil)) ; => t
and
(null '(quote nil)) ; => nil
(CADDR '(6 (QUOTE NIL) (QUOTE NIL))) ; ==> (QUOTE NIL) or just 'NIL
The list with the two symbols QUOTE and NIL are not equal to NIL. Only NIL is equal to NIL. eg.
(DEFPARAMETER TEST 'NIL)
TEST ; ==> NIL
(NULL TEST) ; ==> T
This works since 'NIL gets evaluated to NIL and assigned to TEST. TEST gets evaluated to NIL and it's CLs NULL value. However:
(DEFPARAMETER TEST2 ''NIL)
TEST2 ; ==> 'NIL or (QUOTE NIL)
(NULL TEST2) ; ==> NIL
A list with two elements QUOTE and NIL, famously displayed as 'NIL, is NOT NIL. Only NIL is NIL.
EDIT
After looking at your comments about unquoting I'm pretty sure you want this as make-node:
(defun make-node (atm)
(cons atm '(() ())))
(test (make-node 6)) ; ==> (1 NIL NIL)
There is no such thing as unquoting in a data structure and unless you actually want the symbol quote in your data there is no sense in having quotes inside something quoted. (Half truth since there is, but it involves macros)
I wrote a function to convert alist to hash:
(defun hash-alist (alist)
"Convert association list to a hash table and return it."
(let ((my-hash (make-hash-table :test 'equal)))
(dolist (entry alist)
(if (gethash (car entry) my-hash)
(error "repeated key"))
(puthash (car entry) (cdr entry) my-hash))
my-hash))
but when I run it as following, why I get nil at the end?
Run:
(setq a '(("a" . 2) ("b" . 1)))
(setq b (hash-alist a))
(maphash (lambda (x y) (princ (format "%s:%d " x y) t))
b)
Output:
a:2 b:1 nil
nil is the return value of maphash. Nothing more than that.
It is the way that you are evaluating the maphash sexp that causes the return value to be printed.
If you look in buffer *Messages* you might see something like this (depending on how you evaluate the expression):
Evaluating...
a:2 b:1
Buffer `*Pp Eval Output*' is in mode `Emacs-Lisp'. For info on the mode: `C-h m'.
nil
The return value is documented in the Elisp manual, node Hash Access. It should also be, but is not, documented in the doc string.
Every Lisp expression has a value.
c-x c-e evaluates an expression and prints the result.
If you evaluate (+ 1 2) you see that it evaluates to 3. If you evaluate a maphash expression, then it evaluates to NIL. So this is printed.
Since your code calls functions which produce output, you see that output printed before the return value. So there is no extra NIL. It is just the NIL that is the result.
Consider these two:
(defparameter *lfn*
(let ((count 0))
#'(lambda ()
(incf count))))
(defun testclosure ()
(let ((count 0))
#'(lambda ()
(incf count))))
Why do they behave differently:
CL-USER> (funcall (testclosure))
1
CL-USER> (funcall (testclosure))
1
CL-USER> (funcall *lfn*)
1
CL-USER> (funcall *lfn*)
2
count is closed over in the defparameter version but not in the defun version. Why is this?
When you are making *lfn* you are creating a function within one closure.. Calling it will increase the closed over count and evaluate to it.
testclosure does the same as what you did with *lfm* for every time it gets called. Thus:
(defparameter *lfn2* (testclosure))
(funcall *lfn2*) ; ==> 1
(funcall *lfn2*) ; ==> 2
(funcall *lfn2*) ; ==> 3
Will make exactly the same as *lfn* such that consecutive calls to it will increase the value returned. However
(funcall (testclosure)) ; ==> 1 (and the closure can be recycled)
(funcall (testclosure)) ; ==> 1 (and the closure can be recycled)
Here you are doing funcall on a newly created closure, that you don't store for consecutive calls, so it will return 1. Then you are doing funcall again on a completely new closure that you also don't store and it's first call also evaluates to 1.
So the answer is, count is closed over in both, but in you example you were creating a new closure and using it only once, several times.
Sylwester's answer explains this very well, but in a case an example with more explicit side effects makes this any clearer, consider:
CL-USER> (defparameter *foo* (progn (print 'hello) 0))
HELLO
*FOO*
CL-USER> *foo*
0
CL-USER> *foo*
0
In defining *foo*, the (progn (print 'hello) 0) is evaluated once, so hello is printed, and the value is 0, which becomes the value of *foo*. Evaluating *foo* later just means looking up *foo*'s value (0), not reƫvaluating the form that produced its original value. In contrast, consider calling a function whose body is(progn (print 'hello) 0)`:
CL-USER> (defun foo () (progn (print 'hello) 0))
FOO
CL-USER> (foo)
HELLO
0
CL-USER> (foo)
HELLO
0
CL-USER> (foo)
HELLO
0
Each time foo is called, (progn (print 'hello) 0) is evaluated, so hello is printed and 0 is returned. After seeing this example, your code should be a bit clearer.
(defparameter *lfn*
(let ((count 0))
#'(lambda ()
(incf count))))
(let ...) is evaluated once, and the closure that that evaluation produces its the value of *lfn*. On the other hand, in
(defun testclosure ()
(let ((count 0))
#'(lambda ()
(incf count))))
(let ...) is evaluated every time that testclosure is called, a new closure is returned each time.
The value of *lfn* is a closure.
The function testclosure returns a new closure each time you call it.