SETF neither terminates nor reports an error - common-lisp

I'm a Common Lisp beginner and came across this piece of code:
(let ((foo (list 42)))
(setf (rest foo) foo))
The REPL seem to just loop forever when trying to execute it.

What is FOO?
FOO is initially a fresh list, (42). In Lisp, lists are represented by cons cells, blocks of mutable memory containing each a CAR and a CDR slot.
Another way to print it is (42 . NIL), where the CAR and CDR are on each side of the dot. This can also be pictured as follows:
car cdr
------------
| 42 | NIL |
------------
^
|
FOO
When you call SETF with the (rest foo) place and the foo value, you are saying that you want the cdr cell of FOO to hold the value FOO. In fact, this occurrence of SETF is likely to macroexpand into a call to RPLACD.
------------
| 42 | FOO |
------------
^
|
FOO
Why does the REPL loop forever?
The "P" part of the "REPL" (print) tries to print your circular structure. This is because SETF's value is the one being returned from the form being evaluated, and the value returned by SETF is the value of its second argument, namely FOO. Imagine you want to write a cons cell X with a naive algorithm:
1. PRINT "("
2. PRINT the CAR of X
3. PRINT " . "
4. PRINT the CDR of X
5. PRINT ")"
However, for foo, step 4 will print the same structure, recursively, and will never terminate.
What can you do?
Try setting *PRINT-CIRCLE* to T first:
(setf *print-circle* t)
And now, your REPL should be happy:
CL-USER> (let ((foo (list 42)))
(setf (rest foo) foo))
#1=(42 . #1#)
The "Sharpsign Equal-Sign" notation allows the reader to affect part of a form to a (reader) variable, like #1=..., and reuse it afterwards, e.g. #1#. This make it possible to represent circular cross-references between data, either during reading or printing. Here, we can see that the variable #1# denotes a cons-cell, where the CAR is 42 and the CDR is #1# itself.

Related

Common Lisp shared structure confusion

I am reading the book Practical Common Lisp, and in the footnote5 of chapter22, page284, I saw a code snippet that made me confused.
I know that the variable list and tail have a list structure in common,
but I am confusing that since tail will be assigned the value of 'new' each time during the iteration, why (setf (cdr tail) new) would affect the state of the variable list?
(do ((list nil) (tail nil) (i 0 (1+ i)))
((> i 10) list)
(let ((new (cons i nil)))
(if (null list)
(setf list new)
(setf (cdr tail) new))
(setf tail new)))
;;; => (0 1 2 3 4 5 6 7 8 9 10)
The invariant is that tail is always the last cons cell of list.
On each iteration, a new cons cell is created holding the new value as car. The first time through, list is set to this cons cell, and tail too. In all subsequent iterations, the new cons cell is appended by setting the cdr of the last cell to it, then setting tail to the new cell, to recreate the invariant.
After first iteration:
[ 0 | nil ]
^- list
^- tail
After second:
[ 0 | -]--->[ 1 | nil ]
^- list ^- tail
Third:
[ 0 | -]--->[ 1 | -]--->[ 2 | nil ]
^- list ^- tail
The do form in your example keeps a pointer to the tail cons to make appending an element to the end of the list a cheap operation. Otherwise one would need to traverse the list all the time to find the last cons - for example by using appendor nconc. Another way would be to collect new elements on the head and at the end to reverse the result list.
One would expect that the LOOP macro implements something efficient by transforming a higher level loop expression into efficient code.
The macro form
(loop for i upto 10 collect i)
might expand into something that works internally similar as your do example. The advantage of loop is that you don't need to implement the logic to track the tail, since that's what the macro should do for you.

Understanding sharp quote in common lisp

In my experiments below I've abbreviated where the REPL returns an error, & added [num] so these can be referenced in discussion.
I'm a bit confused as to why my attempts to call a function stored in a variable are failing. It seems to me that the syntax is more complex than it needs to be.
Why can I issue neither (f 3) nor even (#'f 3)?
Is sharp quote not allowed as the first element of a form?
Why is funcall required here?
[235]> (setf f #'abs) ; I'm ok with this
#<SYSTEM-FUNCTION ABS>
[236]> (abs 3) ; This is fine
3
[237]> (f 3) ; Err due to sep. fn namespace. OK.
-- Err[1]: "Undefined function f" --
[238]> (#'f 3) ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"
[239]> (funcall #'f 3) ; seems very long winded...!
3
Does this mean system functions are treated differently from user defined functions?
For completeness:
[240]> (funcall abs 3)
-- Err[3]: variable ABS has no value -- ; I get why this is an error.
[241]> (funcall #'abs 3) ; Isn't this verbose... ?
3
I haven't got to the symbols chapter in ANSI Common Lisp yet, maybe that will help... thanks for any tips.
[235]> (setf f #'abs) ; I'm ok with this
#<SYSTEM-FUNCTION ABS>
Above kind of sets a variable named f to a function object - from the function called abs.
[236]> (abs 3) ; This is fine
3
Above called the function abs.
[237]> (f 3) ; Err due to sep. fn namespace. OK.
Above: there is no function named f.
-- Err[1]: "Undefined function f" --
[238]> (#'f 3) ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"
Above: Common Lisp accepts only symbols as function names, symbols as macro names, symbols as special operators or lambda expressions as the first element of a cons form. (function f) is not a function name.
Does this mean system functions are treated differently from user defined functions?
No.
[239]> (funcall #'f 3) ; seems very long winded...!
3
Above calls the function funcall with the function object from the named function f. funcall then calls this function object with 3 as the argument.
seems very long winded
It is.
Why can I issue neither (f 3) nor even (#'f 3)? Is sharp quote not allowed as the first element of a form?
Because f is not naming a function. It names a variable. #'f is also not a function name. We are required to use a function name (a symbol actually).
Namespaces
Common Lisp (like some other Lisp dialects) has two namespaces for functions and for variables.
Defining a variable foo:
CL-USER 54 > (defvar foo 3)
FOO
Defining a function foo:
CL-USER 55 > (defun foo (x) (* foo 10))
FOO
We can call the function foo with the value obtained from the variable foo:
CL-USER 56 > (foo foo)
30
How to get the function object from the global name of the function:
CL-USER 57 > (fdefinition 'foo)
#<interpreted function FOO 4060001CAC>
CL-USER 58 > (symbol-function 'foo)
#<interpreted function FOO 4060001CAC>
Same as above, but with a short notation:
CL-USER 58a > #'foo
#<interpreted function FOO 4060001CAC>
CL-USER 59 > (function foo) ; works also for local functions
#<interpreted function FOO 4230008AAC>
How to get a value from a global variable:
CL-USER 60 > (symbol-value 'foo)
3
Or just use the variable:
CL-USER 61 > foo
3
Some positives:
Positive: No name clashes.
We can write
(defun foo (list) (list list))
and don't have to write
(defun foo (lst) (list lst))
Positive: simpler compilation
(let ((list 3))
(list 1 list 3))
Above will never be an error in Common Lisp. In Scheme it would be an error: 3 is not a function.

(LIST . VALUES) is not a proper list

Here is a sample code :
(defun my-test (&rest values)
(macrolet ((my-macro (v)
`(list ,#v)))
(print values)
(my-macro values)))
(my-test 1 2 3 4)
;; The goal is to obtain : (1 2 3 4).
When I execute last line, it prints (1 2 3 4), then the function fails.
When I execute the defun or try to execute last line, I get the following warning/error (resp.) :
; in: DEFUN MY-TEST
; (MY-PACKAGE::MY-MACRO VALUES)
; ==>
; (LIST . VALUES)
;
; caught ERROR:
; (LIST . VALUES) is not a proper list.
;
; compilation unit finished
; caught 1 ERROR condition
Why does it fails ?
A macro transform code and it does not know anything about the runtime values, only the literal code. Eg.
(cond (p1 e1) (p2 e2) (t e3))
Turns into
(if p1
e1
(if p2
e3))
And we really don't know p1 is at this moment. Now look at your code:
(defun my-test (&rest values)
(macrolet ((my-macro (v)
`(list ,#v)))
(print values)
(my-macro values)))
So the macro is expanded when my-test is created. Could you please tell me how my-macro is going to expand (my-macro values) if not (list . values)?
(list . values) is not valid Common Lisp and that is the source of your error.
You should perhaps do this without macros. eg. just use values works fine. For calling a function with a list as the argument you can use apply. To copy a list, which is not needed, you could use copy-list or copy-tree

Does FORMAT provide a counter for lists iteration

I often want to output lists and also print their position in the list e.g.
'(a b c) would become "1:A 2:B 3:C"
As FORMAT already supports iterating over a given list, I was wondering whether it also provides some sort of counting directive?
E.g. the FORMAT string could look like this: "~{~#C:~a~}" whereas ~#C would be the counter.
If you want a boring answer, here you go:
(format T "~:{~a:~a ~}" (loop for i from 0 for e in '(x y z) collect (list i e)))
And now for a more interesting one! Similarly to #Renzo's answer, this uses the Tilde directive to achieve its work.
(defvar *count* 0)
(defvar *printer* "~a")
(defun iterate-counting (stream arg c at)
(declare (ignore c))
(let ((*count* (if at -1 0)))
(destructuring-bind (*printer* delimiter &rest args) arg
(format stream (format NIL "~~{~~/iterate-piece/~~^~a~~}" delimiter) args))))
(defun iterate-piece (stream arg &rest dc)
(declare (ignore dc))
(incf *count*)
(format stream *printer* *count* arg))
This uses two special variables to make it both thread-safe and to allow nesting. I won't say that it's handy to use though. The first item of the argument to list has to be a format string that denotes how to print the argument and counter. For such a format list, the first argument is the counter, and the second argument is the actual item to list. You can switch those around if you need to using the asterisk directive. The second item should be a string to print as the delimiter between each item. Finally, the rest of the list has to be the actual items to print.
(format T "~/iterate-counting/" '("~a:~a" " " x y z))
=> 1:X 2:Y 3:Z
(format T "~/iterate-counting/" '("~a:~/iterate-counting/" " " ("~a>~a" "," 0 1 2) ("~a>~a" "," a b c) ("~a>~a" "," x y z)))
=> 1:1>0,2>1,3>2 2:1>A,2>B,3>C 3:1>X,2>Y,3>Z
If you want it to start counting from zero, add an # modifier to the iterate-counting:
(format T "~#/iterate-counting/" '("~a:~a" " " x y z))
=> 0:X 1:Y 2:Z
I wouldn't personally use this, as it's far less than obvious what is going on if you stumble across the directive uninitiated. It would probably be much less confusing for the potential future reader to write a tailored function for this, than trying to ab/use format.
A not so simple but reusable way of producing a numbered list is by using the ~/ directive (Tilde Slash: Call Function) with a user-defined function. For instance:
(let ((position 0))
(defun init-pos(str arg col at)
(declare (ignore str arg col at))
(setf position 0))
(defun with-pos(str arg col at)
(declare (ignore col at))
(format str "~a:~a" (incf position) arg)))
and then write format like this one:
(format nil "~/init-pos/~{~/with-pos/~^ ~}" nil '(a b c))
Note that, as said in a comment, this solution has two limitations:
You cannot use it if you need to format objects in concurrent threads, and
you cannot use it for nested lists.

LISP global alist variable

I am new to LISP, and here is the question I have with its global variable.
What I am trying to do is to create a "alist" that can store key-value pairs in a structure. Here is my sample code:
(setq *x* '())
(acons 'apple 'fruit *x*)
*x*
(first *x*)
I want my output looks like, after I add the (apple.fruit) pair, x should be ((apple.fruit)), but here is what I got (on loading of the above code):
CL-USER>
NIL
((APPLE . FRUIT))
NIL <--- this is still nil?
NIL
Can anyone please help me with this, since I am not sure why I can not add value to the variable x.
Also, I have another question regarding to the alist: is there a way to look up element in the a list by a key? for example, for the above list, how can I use the key apple to find its corresponding value fruit?
thank you
The function acons has no side effects, i.e. it doesn't modify *x*.
You have to setq the result to get the result of the acons to stick in *x*:
(setq *x* (acons 'apple 'fruit *x*))
If you want to do Functional Programming, then mutable global variables are definitely not a way to go.
Functional Programming is mostly concerned with computation by calling functions with arguments.
Often solutions are recursive.
Let's say, we have a list of fruits and their prices and we want to have a price sum for each fruit category. Let's try a recursive solution using ACONS.
(defun note-category-price (type price sums)
(let ((pair (assoc type sums)))
(if pair
(progn (incf (cdr pair) price) sums)
(acons type price sums))))
In above function you can see that the function directly returns the result of calling ACONS. It is not stored.
(defun compute-price-sums (data sums)
(if (null data)
sums
(compute-price-sums (rest (rest data))
(note-category-price (first data)
(second data)
sums))))
In above function the extended data structure will be used in the recursive call.
Example:
CL-USER 22 > (compute-price-sums
'(apple 10 orange 20 banana 10 apple 20
grape 5 orange 75 apple 30 peach 30
orange 90 apple 20)
nil)
((PEACH . 30) (GRAPE . 5) (BANANA . 10) (ORANGE . 185) (APPLE . 80))

Resources