Get value of symbol without evaluating it - common-lisp

It is possible to get value of the symbol unevaluated like this:
(let ((form '(+ 1 2))) `',form)
This expression evaluates to the following:
'(+ 1 2)
Is there some way to do the same thing but without using backquote?

(let ((form '(+ 1 2))) (list 'quote form))
If form is really a constant:
(list 'quote (list '+ '1 '2))
The quotes on 1 and 2 are redundant, since they're literals, but they are informative and are already there in case you replace then with actual expressions.

You can use the longer syntax if you want. Let's see how your form is read and evaluated, step-by-step.
(let ((form '(+ 1 2))) `',form)
Apostrophe is quote:
(let ((form '(+ 1 2))) `(quote ,form))
Backquote/comma (quasiquote) is a shorthand for building data:
(let ((form '(+ 1 2))) (list 'quote form))
Evaluate the let binding, which associates form with its value, literally the list (+ 1 2), inside the lexical environment of this expression:
(list 'quote form)
Te above builds a list made of the quote symbol and the current value bound to form. The above results in a list starting with quote and a sublist, which prints as follows:
(quote (+ 1 2))
... which admits this simpler representation:
'(+ 1 2)
So you can use (list 'quote form) if you prefer, but this is not much different.

(let ((form '(+ 1 2))) `',form)
You ask:
It is possible to get value of the symbol unevaluated...
Actually this not really what it does. By default Common Lisp has local variables using lexical bindings, not symbols having values. Above form computes the value of the variable form, not of the symbol form. The value of form is the list (+ 1 2). With the backquoted quote, you put a list (quote ...) around it. Which gets printed as (QUOTE (+ 1 2)) or '(+ 1 2).
Note that Common Lisp has no way to get from a symbol to the value of a lexical binding. In the source code symbols denote variables, but at runtime we have lexical bindings and not associations from symbols to values.

Related

Format both an expression and its result without eval

I am trying to format an arbitrary expression, say (+ 2 3), and at the same time, its result, 5.
I have the following:
(defun expr-and-result (expr)
(format t "~a returns ~a~%" expr (eval expr)))
CL-USER> (expr-and-result '(+ 2 3))
(+ 2 3) returns 5
Though it's a simple matter by using eval, I'm curious if this effect can be accomplished without it (because I heard a lot that eval is to be avoided).
I understand that quoting the argument is necessary, because otherwise the given expression will be evaluated as the first step in calling expr-and-result, and only its result could be used inside expr-and-result. Therefore, any possible solution requires the input to be quoted, right?
I thought a bit about macros but I feel like it's the wrong approach to what I am looking for.
Edit: My intent was to construct a simple test-suite, such as:
(progn
(mapcar #'expr-and-result
'((= (my-remainder 7 3) 1)
(= (my-remainder 7 3) 2)))
'end-of-tests)
Outputs:
(= (MY-REMAINDER 7 3) 1) returns T
(= (MY-REMAINDER 7 3) 2) returns NIL
END-OF-TESTS
After reading Paulo's comment, it seems that eval is the shortest and cleanest solution for my purposes.
Here is a simple macro:
(defmacro exec-and-report (form)
`(format t "~S returns ~S~%" ',form ,form))
(macroexpand '(exec-and-report (+ 1 2)))
==>
(FORMAT T "~S returns ~S~%" '(+ 1 2) (+ 1 2)) ;
T
(exec-and-report (+ 1 2))
==>
(+ 1 2) returns 3
NIL
PS. I second #Sylvester's suggestion not to reinvent the wheel

How to access variable in quoted list

How do I tell Lisp that I want to evaluate a list "as a list", not "as a function"?
(let ((x 500)) '(x . nil))
When I type this, it returns
(X)
Good, it hasn't evaluated the list (as I want). But it hasn't replaced the variable x for its value.
'e fully quotes the expression e and has no way of knowing which sub-expressions you want to evaluate instead. If you use a backquote instead of a quote, you can then use a comma to unquote subexpressions.
In your example, you can do
(let ((x 500)) `(,x . nil))
which is equivalent to '(500 . nil) since the x is unquoted.
Use list:
(let ((x 500))
(list x 3))
=> (500 3)
Cactus' answer is great but I though I would throw a little extra info at you :)
In '(x . nil) x is not a variable, it is a symbol. Symbols are used to name things. This distinction seems silly but can really help your intuition to these problems in future.
A 'variable' is the binding between a symbol and a value.
So evaluating x is basically saying 'give me the value that is named by the symbol x'
Functions and variables can be named by the same symbol as they are in different namespaces, so.
(defun x () "jam")
(defvar x 10)
(print x) ;; prints 10
(print (x)) ;; prints "jam"
This is totally valid. Try it out in your repl!
Given that, look again at
'(x . nil)
x is neither the function or the variable, it is just the symbol.
Hope this helps!

common lisp how to set an element in a 2d array?

I think I just use setq (or setf, I'm not really sure the difference), but I don't understand how to reference the [i][j]-th element in an array in lisp.
My start condition is this:
? (setq x (make-array '(3 3)))
#2A((0 0 0) (0 0 0) (0 0 0))
I want to alter, say, the 2nd item of the 3rd "row" to give this:
? ;;; What Lisp code goes here?!
#2A((0 0 0) (0 0 0) (0 "blue" 0))
The following, which I would have thought close, gives an error:
(setq (nth 1 (nth 2 x)) "blue")
So what's the correct syntax?
Thanks!
I think proper way is to use setf with aref like this:
(setf (aref x 2 1) "blue")
For more details see reference.
You can find a dictionary of the ARRAY operations in the Common Lisp HyperSpec (the web version of the ANSI Common Lisp standard:
http://www.lispworks.com/documentation/lw50/CLHS/Body/c_arrays.htm
AREF and (SETF AREF) are documented here:
http://www.lispworks.com/documentation/lw50/CLHS/Body/f_aref.htm
The syntax to set an array element is: (setf (aref array &rest subscripts) new-element).
Basically if you want to set something in Common Lisp, you just need to know how to get it:
(aref my-array 4 5 2) ; access the contents of an array at 4,5,2.
Then the set operation is schematically:
(setf <accessor code> new-content)
This means here:
(setf (aref my-array 4 5 2) 'foobar) ; set the content of the array at 4,5,2 to
; the symbol FOOBAR
The correct invocation is
(setf (aref x 2 1) "blue")
setq is used when you're assigning to a variable. Only setf knows how to "reach into" compound objects as with setting a value in your array. Of course, setf also knows how to assign to variables, so if you stick with setf you'll always be okay.

Basic Lisp Macro error

Little help here please . I am trying to create this lisp macro which takes a list (of numbers) as input and returns the sum of those numbers. The code
(setf g (list 1 2 3 4))
(defmacro add-test(var)
`(+ ,#var))
(add-test g) gives this error
The value G is not of type LIST.
[Condition of type TYPE-ERROR]
At the same time (add-test (1 2 3 4)) gives the correct result which is 10.
Can you please explain , why is it not working when variable is passed in to the function?
Other details -
Lispbox - SBCL
Ubuntu Linux
Thanks in advance
That's easy and one of the most common macro questions.
(add-test g)
Now on macro expansion, the macro ADD-TEST is called with the parameter VAR getting the value G, a symbol.
Then you try a list operation. The backquote expression
`(+ ,#var)
The value of VAR is G, and you try to splice that into the list (+ ... ). Now the returned expression is (+ . G).
CL-USER 12 > (macroexpand '(add-test g))
(+ . G)
T
(+ . G) is not a valid Lisp form. It's not valid source code.
Remember, the parameters to a Macro are the unevaluated source expressions.
Compare that with the following:
CL-USER 13 > (macroexpand '(add-test (1 2 3 4)))
(+ 1 2 3 4)
T
You said: 'Can you please explain, why is it not working when variable is passed in to the function?'
Remember, ADD-TEST is NOT a function, it is a macro. A macro gets the source code passed and returns a new form - that form is then later evaluated.

Difference between `set`, `setq`, and `setf` in Common Lisp?

What is the difference between "set", "setq", and "setf" in Common Lisp?
Originally, in Lisp, there were no lexical variables -- only dynamic ones. And
there was no SETQ or SETF, just the SET function.
What is now written as:
(setf (symbol-value '*foo*) 42)
was written as:
(set (quote *foo*) 42)
which was eventually abbreviavated to SETQ (SET Quoted):
(setq *foo* 42)
Then lexical variables happened, and SETQ came to be used for assignment to them too -- so it was no longer a simple wrapper around SET.
Later, someone invented SETF (SET Field) as a generic way of assigning values to data structures, to mirror the l-values of other languages:
x.car := 42;
would be written as
(setf (car x) 42)
For symmetry and generality, SETF also provided the functionality of SETQ. At this point it would have been correct to say that SETQ was a Low-level primitive, and SETF a high-level operation.
Then symbol macros happened. So that symbol macros could work transparently, it was realized that SETQ would have to act like SETF if the "variable" being assigned to was really a symbol macro:
(defvar *hidden* (cons 42 42))
(define-symbol-macro foo (car *hidden*))
foo => 42
(setq foo 13)
foo => 13
*hidden* => (13 . 42)
So we arrive in the present day: SET and SETQ are atrophied remains of older dialects, and will probably be booted from eventual successors of Common Lisp.
(set ls '(1 2 3 4)) => Error - ls has no value
(set 'ls '(1 2 3 4)) => OK
(setq ls '(1 2 3 4)) => OK - make ls to (quote ls) and then have the usual set
(setf ls '(1 2 3 4)) => OK - same as setq so far BUT
(setf (car ls) 10) => Makes ls '(10 2 3 4) - not duplicated by setq/set
You can use setf in place of set or setq but not vice versa since setf can also set the value of individual elements of a variable if the variable has individual elements. See the exaples below:
All four examples will assign the list (1, 2, 3) to the variable named foo.
(set (quote foo) (list 1 2 3)) ;foo => (1 2 3)
(1 2 3)
(set 'foo '(1 2 3)) ;foo => (1 2 3) same function, simpler expression
(1 2 3)
(setq foo '(1 2 3)) ;foo => (1 2 3) similar function, different syntax
(1 2 3)
(setf foo '(1 2 3)) ;foo => (1 2 3) more capable function
(1 2 3)
setf has the added capability of setting a member of the list in foo to a new value.
foo ;foo => (1 2 3) as defined above
(1 2 3)
(car foo) ;the first item in foo is 1
1
(setf (car foo) 4) ;set or setq will fail since (car foo) is not a symbol
4
foo ;the fist item in foo was set to 4 by setf
(4 2 3)
However, you can define a symbol macro that reprents a single item within foo
(define-symbol-macro foo-car (car foo)) ; assumes FOO => (1 2 3)
FOO-CAR
foo-car ;foo-car is now a symbol for the 1st item in foo
1
(setq foo-car 4) ;set or setq can set the symbol foo-car
4
foo ;Lisp macros are so cool
(4 2 3)
You can use defvar if you have not already defined the variable and do not want to give it a value until later in your code.
(defvar foo2)
(define-symbol-macro foo-car (car foo2))
setq is just like set with a quoted first arg -- (set 'foo '(bar baz)) is just like (setq foo '(bar baz)). setf, on the other hand, is subtle indeed -- it's like an "indirection". I suggest http://www.n-a-n-o.com/lisp/cmucl-tutorials/LISP-tutorial-16.html as a better way to get started understanding it than any answer here can give... in short, though, setf takes the first argument as a "reference", so that e.g. (aref myarray 3) will work (as the first arg to setf) to set an item inside an array.
One can think of SET and SETQ being low-level constructs.
SET can set the value of symbols.
SETQ can set the value of variables.
Then SETF is a macro, which provides many kinds of setting things: symbols, variables, array elements, instance slots, ...
For symbols and variables one can think as if SETF expands into SET and SETQ.
* (macroexpand '(setf (symbol-value 'a) 10))
(SET 'A 10)
* (macroexpand '(setf a 10))
(SETQ A 10)
So SET and SETQ are used to implement some of the functionality of SETF, which is the more general construct. Some of the other answers tell you the slightly more complex story, when we take symbol macros into account.
I would like to add to previous answers that setf is macro that call specific function depending on what was passed as its first argument.
Compare results of macro expansion of setf with different types of arguments:
(macroexpand '(setf a 1))
(macroexpand '(setf (car (list 3 2 1)) 1))
(macroexpand '(setf (aref #(3 2 1) 0) 1))
For some types of arguments "setf function" will be called:
(defstruct strct field)
(macroexpand '(setf (strct-field (make-strct)) 1))

Resources