Why do quoted objects stay quoted in lisp? - lisp

I have made a simple implementation of LISP using SICP metacircular evaluator as a reference, but even though I know and see the code I don't quite understand something about it. In the apply function that applies a closure to its arguments there is a piece of code that calls eval on each of it's arguments. If I quote an argument, then eval of that argument will give the raw form of that argument.
For clarity of the nature of the question and to present my current understanding of what is happening I will walk through an example.
(define f (lambda (x) (print x)))
(define g (lambda (x) (f x)))
; prints "bar" into the console
(g (quote bar))
First we call g with (quote bar) as the first parameter. The argument to g is evaluated to a symbol bar.
When g is evaluated, it passes it should evaluate it's argument and pass it to function f. But evaluating a symbol will cause a lookup from the environment, which doesn't seem to happen (if it did I should have printed an error, or something like that).
So what I want to know is why does the code print bar and not an error.

I walked through the code with the debugger and now I believe I understand. When g was called, a new environment was created with x associated with the symbol bar. And when a function is executed it's parameters are being evaluated to the things that are stored in the environment. So it's not bar that got evaluated, it's x that got evaluated to bar. And after x is evaluated there's no second-time evaluation.
The reason why quoted things appear to stay quoted is because they actually do get unquoted, but they don't get evaluated as arguments (they only get evaluated once you explicitly call eval on them).

Related

Defining atom function

I'm new with common-lisp and my stuck with this easy problem.
I need to define a function that return true if the input is an atom
So, if in enter in the command line atom 'a returns T, but my code not
Variable x has to be quoted or the result will be false.
(defun check (x)
if(atom 'x)
T)
There already is a function that does that. It is called atom:
(atom 1)
=> T
(atom '(1))
=> NIL
This is thus a rather pointless exercise. If you absolutely must, you could wrap it in another function call:
(defun pointless-exercise (x)
(atom x))
(pointless-exercise 1)
=> T
(pointless-exercise '(1))
=> NIL
Note that you absolutely must not quote that x in your function:
(defun failed-exercise (x)
(atom 'x))
-> WARNING: parameter x is unused
(failed-exercise 1)
=> T
(failed-exercise '(1))
=> T ; oops
That is because 'x means that the symbol x stands for itself and is not evaluated as a variable name, and a symbol is always an atom.
[This is an extended comment which is too long for one.]
Based on your comments either you are confused or your function cannot be written in Common Lisp.
Here's why:
you are writing a function, and so your function will obey the standard evaluation rules of the language for function applications;
you require your function, check to return t in a form (check a) where a is not previously known.
These two conditions can not be met. They can't be met because the evaluation rules for the language forbid it. In a form like (check a) the rules are:
find out what sort of thing check refers to;
if it refers to a function, evaluate all its arguments in left-to-right order in the current environment;
retrieve the function binding of check from the current environment (this step can happen before, after, or during (2));
apply it to the results of (2).
See 3.1.2.1.2.3 of the Hyperspec.
In your case this process fails at (2): a has no binding and so evaluation of a signals an error.
Given that you are being asked to write a function you must have misunderstood the question.
Further, it's unlikely that you were being asked merely to write a wrapper around atom: rather the chances are the question wanted you either to reimplement atom (hint: what is its definition?), or to implement some variant of atom which considers a different set of objects to be 'atomic' than atom does. Which of those is true we can't tell from your question as it stands (v1).

Odd behaviour with nconc in emacs lisp

I have the following function (simplified to that version):
(defun append-test (xs)
(let ((ys `(foo ,(nconc `(bar) xs))))
(nconc ys `((baz)))))
If I evaluate the function multiple times (append-test '((foo))) the list keeps increasing in size, but I can't understand why. The nconc modifies the original list, but because the original list is either a function argument or let-variable, they should be created anew per every invocation, right? What is happening here?
If you change `(bar) to (list 'bar), then the code returns the same result every time.
nconc modifies all arguments but the last one. Obviously, if the first argument were '(bar), then the quoted list contained within the function definition would be modified, and we would expect to see the result you see. Apparently using a backquote expression that doesn't contain any commas is equivalent to using a quoted list.
Actually, the following piece of code keeps the backquote, but adds a pointless expression to the cdr of the list. Apparently, this makes it allocate a new list every time the function is called, and thus it returns the same result every time:
(defun append-test (xs)
(let ((ys `(foo ,(nconc `(bar . ,(ignore)) xs))))
(nconc ys `((baz)))))
I was bitten by this. Here are some bugs that resulted.
http://comments.gmane.org/gmane.emacs.bugs/50783
http://lists.gnu.org/archive/html/emacs-bug-tracker/2011-09/msg00220.html
This issue seems to be a rite of passage for lisp developers. :-)
From what I understand, lisp evaluation is split in two phases:
Read : A reader that statically allocates storage and reads forms into memory.
Evaluate : The read form is evaluated.
What about quote?
quote simply returns the read form without evaluation.
Implicitly,
When a quote form is evaluated, it just returns the reader allocated
object directly.
When a quote form is re-evaluated (i.e. function call, etc), it returns
the same reader allocated object.
quote does not allocate new memory
Ta-da!

Lisp grammar/formatting

Trying my hand at Lisp. I wonder though, why does:
(defun hello(x)
(print x)
)
work fine, but:
(defun hello (x)
(print(x)) ; Fails with EVAL: undefined function X.
)
not?
In LISPs, non-empty, unquoted lists are considered (function, macro, or special form) calls.
So,
(print x)
is a function call to print with an argument x.
But,
(print (x))
is a function call to print with an argument equal to the value of (x). But since (x) is also non-empty list, in order to get the value of (x) there is an attempt to make a call to a non-existent function x with no arguments.
It's key to note that parentheses are not simply grouping syntax as they are in many other languages; they invoke function as well, similar to how X.val is not the same as X.val() in e.g. Python.
So in this case, you are trying to call x as though it were a function. But, depending on what you've passed to hello, x is not a function, and as such cannot be called.

Common Lisp, reference to value and actual value

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.

Clojure macros and symbol binding

not sure how to express this..
I've written a macro which takes two arguments. The first one essentially contains identifiers for generating a let expression. The second is the code to use inside the let expression (it wants to have access to these identifiers).
An example:
(match (Add {ast-> x}) (println x))
When the second argument is raw code, things work nicely. x binds to the x defined in the let expression (when macroexpanded it just shows as x). However, when the second argument is a macro which generates (println x), x expands to something like user/x.
Any good ideas on how to fix this?
It sounds like your second macro is defined as:
(defmacro foo
[]
`(println x))
This is incorrect as x will be namespace qualified. The correct version of the second macro in this case would be:
(defmacro foo
[]
`(println ~'x))
Now the x in the println call will be a literal x symbol and not namespace qualified.