The "set" function - common-lisp

I'm having difficulty understanding the workings of a bit of code that someone with more experience may comprehend:
(let ((x 0))
(loop for var in '(x)
do (set var 3))
x)
My expectation is that the expression should return 3, the new value of x, but it actually returns 0. Why does x not get reset? Is there another way to iterate over a list of variables and assign them values?

Access to lexical variables using symbols is not supported.
Common Lisp does not give you access to lexical variables via symbols. By default variables are bound lexically.
Special variables use dynamic binding.
It works with special variables, which use dynamic binding:
CL-USER 14 > (let ((x 0))
(declare (special x))
(loop for var in '(x) do (set var 3))
x)
3
Alternatively you can declare a global special variable and the special declaration extends to let bindings. That's also why one marks them visually with a naming convention. We write *foo* and not foo.
CL-USER 15 > (defvar *x123* 0)
*X123*
CL-USER 16 > (let ((*x123* 1))
(loop for var in '(*x123*) do (set var 3))
*x123*)
3

Related

Evaluating a List of Variables to a List of Their Values in Common Lisp

I am wondering how one can achieve the following. Suppose I have a list of variables that are bound by some let above. I would like to turn this list into a list of the values to which those variables are bound.
That is, suppose we have
(define make-plist-from-variables (variables)
(let ((keys variables)
(values (mapcar #'identity variables)))
(if (eq (length keys) (length values))
(make-plist keys values)
nil))))
What can I use in place of #'identity to unpack those values properly?
At the moment, the following call produces the following output.
CL-USER> (let ((a 2) (b 3)) (make-plist-from-variables '(a b)))
(A A B B)
I would like it to be (A 2 B 3)
It needs to be a macro because there is no way to fetch a variable's lexical value based on its symbol.
(defmacro make-plist-from-variables (&rest variables)
(loop :for binding :in variables
:collect `',binding :into result
:collect binding :into result
:finally (return `(list ,#result))))
(macroexpand-1 '(make-plist-from-variables a b))
; ==> (list 'a a 'b b)
(let ((a 2) (b 3))
(make-plist-from-variables a b))
; ==> (a 2 b 3)
EDIT
Implementation without loop using mapcan:
(defmacro make-plist-from-variables (&rest variables)
`(list ,#(mapcan (lambda (v) `(',v ,v)) variables))
Functions don't have access to the lexical environment of their callers.
More precisely, during evaluation you cannot access the values of lexical variables knowing only their symbols. Only macros have access to environment objects.
Special variables
You can use dynamic binding:
(defun foo ()
(declare (special a))
(symbol-value 'a))
(let ((a 3))
(declare (special a))
(foo))
=> 3
In your case, you would collect the symbol along its value, by using SYMBOL-vaLUE on all your symbols.
Related to your question is how to dynamically bind variables to values where the variable names and/or values are known at evaluation time; see special operator PROGV.
Macros
You could obtain e.g. an association list by writing the following code:
(acons 'a a (acons 'b b nil))
Depending on the use case behind your question, you may want to have a macro that expands into such code, that references the variables you want to evaluate.

My code signals the error "application: not a procedure" or "call to non procedure"

During the execution of my code I get the following errors in the different Scheme implementations:
Racket:
application: not a procedure;
expected a procedure that can be applied to arguments
given: '(1 2 3)
arguments...:
Ikarus:
Unhandled exception
Condition components:
1. &assertion
2. &who: apply
3. &message: "not a procedure"
4. &irritants: ((1 2 3))
Chicken:
Error: call of non-procedure: (1 2 3)
Gambit:
*** ERROR IN (console)#2.1 -- Operator is not a PROCEDURE
((1 2 3) 4)
MIT Scheme:
;The object (1 2 3) is not applicable.
;To continue, call RESTART with an option number:
; (RESTART 2) => Specify a procedure to use in its place.
; (RESTART 1) => Return to read-eval-print level 1.
Chez Scheme:
Exception: attempt to apply non-procedure (1 2 3)
Type (debug) to enter the debugger.
Guile:
ERROR: In procedure (1 2 3):
ERROR: Wrong type to apply: (1 2 3)
Chibi:
ERROR in final-resumer: non procedure application: (1 2 3)
Why is it happening
Scheme procedure/function calls look like this:
(operator operand ...)
Both operator and operands can be variables like test, and + that evaluates to different values. For a procedure call to work it has to be a procedure. From the error message it seems likely that test is not a procedure but the list (1 2 3).
All parts of a form can also be expressions so something like ((proc1 4) 5) is valid syntax and it is expected that the call (proc1 4) returns a procedure that is then called with 5 as it's sole argument.
Common mistakes that produces these errors.
Trying to group expressions or create a block
(if (< a b)
((proc1)
(proc2))
#f)
When the predicate/test is true Scheme assumes will try to evaluate both (proc1) and (proc2) then it will call the result of (proc1) because of the parentheses. To create a block in Scheme you use begin:
(if (< a b)
(begin
(proc1)
(proc2))
#f)
In this (proc1) is called just for effect and the result of teh form will be the result of the last expression (proc2).
Shadowing procedures
(define (test list)
(list (cdr list) (car list)))
Here the parameter is called list which makes the procedure list unavailable for the duration of the call. One variable can only be either a procedure or a different value in Scheme and the closest binding is the one that you get in both operator and operand position. This would be a typical mistake made by common-lispers since in CL they can use list as an argument without messing with the function list.
wrapping variables in cond
(define test #t) ; this might be result of a procedure
(cond
((< 5 4) result1)
((test) result2)
(else result3))
While besides the predicate expression (< 5 4) (test) looks correct since it is a value that is checked for thurthness it has more in common with the else term and whould be written like this:
(cond
((< 5 4) result1)
(test result2)
(else result3))
A procedure that should return a procedure doesn't always
Since Scheme doesn't enforce return type your procedure can return a procedure in one situation and a non procedure value in another.
(define (test v)
(if (> v 4)
(lambda (g) (* v g))
'(1 2 3)))
((test 5) 10) ; ==> 50
((test 4) 10) ; ERROR! application: not a procedure
Undefined values like #<void>, #!void, #<undef>, and #<unspecified>
These are usually values returned by mutating forms like set!, set-car!, set-cdr!, define.
(define (test x)
((set! f x) 5))
(test (lambda (x) (* x x)))
The result of this code is undetermined since set! can return any value and I know some scheme implementations like MIT Scheme actually return the bound value or the original value and the result would be 25 or 10, but in many implementations you get a constant value like #<void> and since it is not a procedure you get the same error. Relying on one implementations method of using under specification makes gives you non portable code.
Passing arguments in wrong order
Imagine you have a fucntion like this:
(define (double v f)
(f (f v)))
(double 10 (lambda (v) (* v v))) ; ==> 10000
If you by error swapped the arguments:
(double (lambda (v) (* v v)) 10) ; ERROR: 10 is not a procedure
In higher order functions such as fold and map not passing the arguments in the correct order will produce a similar error.
Trying to apply as in Algol derived languages
In algol languages, like JavaScript and C++, when trying to apply fun with argument arg it looks like:
fun(arg)
This gets interpreted as two separate expressions in Scheme:
fun ; ==> valuates to a procedure object
(arg) ; ==> call arg with no arguments
The correct way to apply fun with arg as argument is:
(fun arg)
Superfluous parentheses
This is the general "catch all" other errors. Code like ((+ 4 5)) will not work in Scheme since each set of parentheses in this expression is a procedure call. You simply cannot add as many as you like and thus you need to keep it (+ 4 5).
Why allow these errors to happen?
Expressions in operator position and allow to call variables as library functions gives expressive powers to the language. These are features you will love having when you have become used to it.
Here is an example of abs:
(define (abs x)
((if (< x 0) - values) x))
This switched between doing (- x) and (values x) (identity that returns its argument) and as you can see it calls the result of an expression. Here is an example of copy-list using cps:
(define (copy-list lst)
(define (helper lst k)
(if (null? lst)
(k '())
(helper (cdr lst)
(lambda (res) (k (cons (car lst) res))))))
(helper lst values))
Notice that k is a variable that we pass a function and that it is called as a function. If we passed anything else than a fucntion there you would get the same error.
Is this unique to Scheme?
Not at all. All languages with one namespace that can pass functions as arguments will have similar challenges. Below is some JavaScript code with similar issues:
function double (f, v) {
return f(f(v));
}
double(v => v * v, 10); // ==> 10000
double(10, v => v * v);
; TypeError: f is not a function
; at double (repl:2:10)
// similar to having extra parentheses
function test (v) {
return v;
}
test(5)(6); // == TypeError: test(...) is not a function
// But it works if it's designed to return a function:
function test2 (v) {
return v2 => v2 + v;
}
test2(5)(6); // ==> 11

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.

donĀ“t know how to assign values to an array

I have recently started to learn about Lisp, and I have this simple code which defines a function(using defun) and it creates an array of four elements and then it assigns the value 7 to the first position of the array
(defun func(setf array (make-array '(4))))
(setf (aref array 0) 7)
but it prints FUNC in the output, why is that??
A function always needs a parameter list, even if it is empty
(defun func () ; <- here
(setf array (make-array '(4)))
(setf (aref array 0) 7))
Evaluating this form defines and registers the function named func and returns the symbol it is registered with. That's why you see FUNC then, and it is quite right and expected.
There are other problems:
When you do (setf array...) here, array is not defined. In principle, anything could happen, but in practice, a global variable will be created and set which might or might not be declaimed special (i. e. of dynamic extent).
You should create a local variable instead. This is usually done using let:
(defun func ()
(let ((array (make-array '(4))))
(setf (aref array 0) 7)))
This does not do much, since the return value is the last value assigned by setf, which is 7. You would most likely want to return the array:
(defun func ()
(let ((array (make-array '(4))))
(setf (aref array 0) 7))
array))
Note that elements 1, 2, and 3 are not initialized, so trying to read from them has undefined behaviour later (unless you set their values before, of course). If you want to treat the array as being filled only to the first element, you could use a fill-pointer:
(defun func ()
(let ((array (make-array 4 :fill-pointer 0)))
(vector-push 7 array)
array))
If you just need the exact structure of your array, you could copy a literal:
(defun func ()
(copy-seq #(7 0 0 0)))

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.

Resources