I am reading the book 'Practical Common Lisp' by Peter Seibel.
In Chapter 6, "Variables" sections
"Lexical Variables and Closures" and "Dynamic, a.k.a. Special, Variables".
http://www.gigamonkeys.com/book/variables.html
My problem is that the examples in both sections show how (let ...) can shadow global variables and doesn't really tell the difference between the Dynamic and Lexical vars.
I understand how closures work but I don't really get whats so special about let in this example:
(defvar *x* 10)
(defun foo ()
(format t "Before assignment~18tX: ~d~%" *x*)
(setf *x* (+ 1 *x*))
(format t "After assignment~18tX: ~d~%" *x*))
(defun bar ()
(foo)
(let ((*x* 20)) (foo))
(foo))
CL-USER> (foo)
Before assignment X: 10
After assignment X: 11
NIL
CL-USER> (bar)
Before assignment X: 11
After assignment X: 12
Before assignment X: 20
After assignment X: 21
Before assignment X: 12
After assignment X: 13
NIL
I feel like there is nothing special is going on here. The outer foo in bar increments the global x, and foo surrounded by let in bar increments the shadowed x. What's the big deal? I don't see how is this supposed to explain the difference between lexical and dynamic variables. Yet the book continues like this:
So how does this work? How does LET
know that when it binds x it's
supposed to create a dynamic binding
rather than a normal lexical binding?
It knows because the name has been
declared special.12 The name of every
variable defined with DEFVAR and
DEFPARAMETER is automatically declared
globally special.
What would happen if let would bind x using "normal lexical binding"? All in all, what are the differences between dynamic and lexical binding and how is this example special regarding dynamic binding?
What's going on?
You say: feel like there is nothing special is going on here. The outer foo in bar increments the global x, and foo surrounded by let in bar increments the shadowed x. What's the big deal?
The special that's going on here is that LET can shadow the value of *x*. With lexical variables that's not possible.
The code declares *x* to be special via the DEFVAR.
In FOO now the value of *x* is looked up dynamic. FOO will take the current dynamic binding of *x* or, if there is none, the symbol value of the symbol *x*. A new dynamic binding can, for example, be introduced with LET.
A lexical variable on the other hand has to be present in the lexical environment somewhere. LET, LAMBDA, DEFUN and others can introduce such lexical variables. See here the lexical variable x introduced in three different ways:
(let ((x 3))
(* (sin x) (cos x)))
(lambda (x)
(* (sin x) (cos x)))
(defun baz (x)
(* (sin x) (cos x)))
If our code were:
(defvar x 0)
(let ((x 3))
(* (sin x) (cos x)))
(lambda (x)
(* (sin x) (cos x)))
(defun baz (x)
(* (sin x) (cos x)))
Then X were special in all three above cases, because of the DEFVAR declaration, which declares X to be special - globally for all levels. Because of this, there is the convention to declare special variables as *X*. Thus only variables with stars around them are special - by convention. That's a useful convention.
In your code you have then:
(defun bar ()
(foo)
(let ((*x* 20))
(foo))
(foo))
Since *x* has be declared special via the DEFVAR above in your code, the LET construct introduces a new dynamic binding for *x*. FOO is then called. Since inside FOO the *x* uses dynamic binding, it looks up the current one and finds that *x* is dynamically bound to 20.
The value of a special variable is found in the current dynamic binding.
Local SPECIAL declarations
There are also local special declarations:
(defun foo-s ()
(declare (special *x*))
(+ *x* 1))
If the variable had been declared special by a DEFVAR or DEFPARAMETER, then the local special declaration can be omitted.
A lexical variable directly references the variable binding:
(defun foo-l (x)
(+ x 1))
Let's see it in practice:
(let ((f (let ((x 10))
(lambda ()
(setq x (+ x 1))))))
(print (funcall f)) ; form 1
(let ((x 20)) ; form 2
(print (funcall f))))
Here all variables are lexical. In form 2 the LET will not shadow the X in our function f. It can't. The function uses the lexical bound variable, introduced by the LET ((X 10). Surrounding the call with another lexically bound X in form 2 has no effect on our function.
Let's try special variables:
(let ((f (let ((x 10))
(declare (special x))
(lambda ()
(setq x (+ x 1))))))
(print (funcall f)) ; form 1
(let ((x 20)) ; form 2
(declare (special x))
(print (funcall f))))
What now? Does that work?
It does not!
The first form calls the function and it tries to look up the dynamic value of X and there is none. We get an error in form 1: X is unbound, because there is no dynamic binding in effect.
Form 2 would work, since the LET with the special declaration introduces a dynamic binding for X.
When a variable is lexically scoped, the system looks to where the function is defined to find the value for a free variable. When a variable is dynamically scoped, the system looks to where the function is called to find the value for the free variable. Variables in Common Lisp are all lexical by default; however, dynamically scoped variables can be defined at the top level using defvar or defparameter.
A simpler example
lexical scoping (with setq):
(setq x 3)
(defun foo () x)
(let ((x 4)) (foo)) ; returns 3
dynamic scoping (with defvar):
(defvar x 3)
(defun foo () x)
(let ((x 4)) (foo)) ; returns 4
How does the let know if a variable is lexical or dynamic? It doesn't. On the other hand, when foo goes to find the value of X, it will initially find the lexical value defined at the top level. It then checks to see if the variable is supposed to be dynamic. If it is, then foo looks to the calling environment, which, in this case, uses let to overshadow the value of X to be 4.
(note: this is an oversimplification, but it will help to visualize the difference between the different scoping rules)
Maybe this example will help.
;; the lexical version
(let ((x 10))
(defun lex-foo ()
(format t "Before assignment~18tX: ~d~%" x)
(setf x (+ 1 x))
(format t "After assignment~18tX: ~d~%" x)))
(defun lex-bar ()
(lex-foo)
(let ((x 20)) ;; does not do anything
(lex-foo))
(lex-foo))
;; CL-USER> (lex-bar)
;; Before assignment X: 10
;; After assignment X: 11
;; Before assignment X: 11
;; After assignment X: 12
;; Before assignment X: 12
;; After assignment X: 13
;; the dynamic version
(defvar *x* 10)
(defun dyn-foo ()
(format t "Before assignment~18tX: ~d~%" *x*)
(setf *x* (+ 1 *x*))
(format t "After assignment~18tX: ~d~%" *x*))
(defun dyn-bar()
(dyn-foo)
(let ((*x* 20))
(dyn-foo))
(dyn-foo))
;; CL-USER> (dyn-bar)
;; Before assignment X: 10
;; After assignment X: 11
;; Before assignment X: 20
;; After assignment X: 21
;; Before assignment X: 11
;; After assignment X: 12
;; the special version
(defun special-foo ()
(declare (special *y*))
(format t "Before assignment~18tX: ~d~%" *y*)
(setf *y* (+ 1 *y*))
(format t "After assignment~18tX: ~d~%" *y*))
(defun special-bar ()
(let ((*y* 10))
(declare (special *y*))
(special-foo)
(let ((*y* 20))
(declare (special *y*))
(special-foo))
(special-foo)))
;; CL-USER> (special-bar)
;; Before assignment X: 10
;; After assignment X: 11
;; Before assignment X: 20
;; After assignment X: 21
;; Before assignment X: 11
;; After assignment X: 12
You can tell your Lisp to bind local variables dynamically, too:
(let ((dyn 5))
(declare (special dyn))
... ;; DYN has dynamic scope for the duration of the body
)
Rewrite example from PCL.
;;; Common Lisp is lexically scoped by default.
λ (setq x 10)
=> 10
λ (defun foo ()
(setf x (1+ x)))
=> FOO
λ (foo)
=> 11
λ (let ((x 20))
(foo))
=> 12
λ (proclaim '(special x))
=> NIL
λ (let ((x 20))
(foo))
=> 21
Yet another great explanation from On Lisp, chapter 2.5 Scope:
Common Lisp is a lexically scoped Lisp. Scheme is the oldest dialect with lexical scope; before Scheme, dynamic scope was considered one of the defining features of Lisp.
The difference between lexical and dynamic scope comes down to how an implementation deals with free variables. A symbol is bound in an expression if it has been established as a variable, either by appearing as a parameter, or by variable-binding operators like let and do. Symbols which are not bound are said to be free. In this example, scope comes into play:
(let ((y 7))
(defun scope-test (x)
(list x y)))
Within the defun expression, x is bound and y is free. Free variables are interesting because it’s not obvious what their values should be. There’s no uncertainty about the value of a bound variable—when scope-test is called, the value of x should be whatever is passed as the argument. But what should be the value of y? This is the question answered by the dialect’s scope rules.
In a dynamically scoped Lisp, to find the value of a free variable when exe- cuting scope-test, we look back through the chain of functions that called it. When we find an environment where y was bound, that binding of y will be the one used in scope-test. If we find none, we take the global value of y. Thus, in a dynamically scoped Lisp, y would have the value it had in the calling expression:
> (let ((y 5)) (scope-test 3))
(3 5)
With dynamic scope, it means nothing that y was bound to 7 when scope-test was defined. All that matters is that y had a value of 5 when scope-test was called.
In a lexically scoped Lisp, instead of looking back through the chain of calling functions, we look back through the containing environments at the time the function was defined. In a lexically scoped Lisp, our example would catch the binding of y where scope-test was defined. So this is what would happen in Common Lisp:
> (let ((y 5)) (scope-test 3))
(3 7)
Here the binding of y to 5 at the time of the call has no effect on the returned value.
Though you can still get dynamic scope by declaring a variable to be special, lexical scope is the default in Common Lisp. On the whole, the Lisp community seems to view the passing of dynamic scope with little regret. For one thing, it used to lead to horribly elusive bugs. But lexical scope is more than a way of avoiding bugs. As the next section will show, it also makes possible some new programming techniques.
Related
I am new to Lisp and I am trying to understand how variables and assigning variables work. I am trying to check if a given number is 5 or not. If it is, it is supposed to change it to 10 and print it. If not it just tells you that it is not 5 but my code below is not working.
(print "Give me a number")
(setq *x* (read))
(defun check(*x*)
(if (= *x* 5) (setq *x* 10) (format t "~d is not 5" *x*))
)
check(*x*)
print(*x*)
check(*x*) and print(*x*) isn't Lisp syntax. Replace that with (check *x*) and (print *x*)
Your function operates with some *x*, but it isn't your global *x*, but local variable*x* from argument list. Don't name function arguments same as global variables. Check this example:
(defparameter a 8)
(defun add (a)
(setf a (+ a 2))
(print a))
(add a)
(print a)
Returned values are 10 and then 8. Compare it with:
(defparameter *a* 8)
(defun add (a)
(setf *a* (+ *a* 2))
(print *a*))
(add *a*)
(print *a*)
Returned values are 10 and 10.
Don't use setf or setq for creating variable, these functions are only for setting new value. Use defparameter or defvar instead.
This code assigns value to global variable:
(print "Give me a number")
(defparameter *x* (read *query-io*))
(defun check ()
(if (= *x* 5)
(setf *x* 10)
(format t "~d is not 5" *x*)))
(check)
(print *x*)
You can also do this task without global variables.
(print "Give me a number")
(defun check (n)
(if (= n 5)
(setf n 10)
(format t "~d is not 5" n))
(print n))
(check (read *query-io*))
If I compile a file with this definition in SBCL:
(print "Give me a number")
(setq *x* (read))
(defun check(*x*)
(if (= *x* 5) (setq *x* 10) (format t "~d is not 5" *x*))
)
There are two warnings:
warning: undefined variable: *X*
This is located at the global setq, because setq does not declare global variables. So the compiler does not know any global variable named *x*.
Then, inside the function:
style-warning:
using the lexical binding of the symbol (*X*), not the
dynamic binding, even though the name follows
the usual naming convention (names like *FOO*) for special variables
--> PROGN SB-IMPL::%DEFUN SB-IMPL::%DEFUN SB-INT:NAMED-LAMBDA
==>
#'(SB-INT:NAMED-LAMBDA AAAB::CHECK
(*X*)
(DECLARE (SB-C::TOP-LEVEL-FORM))
(BLOCK CHECK
(IF (= *X* 5)
(SETQ *X* 10)
(FORMAT T "~d is not 5" *X*))))
This is pretty self-explanatory, but here the binding is lexical.
This is however not a property of defun, this is because there is no declared special variable named *x*.
If instead, you use defvar or defparameter, there is no warning (e.g. (defvar *x* 0)). The same goes if you only declare the variable as special: (declaim (special *x*)), before you define the function that binds it.
Inside the function, assuming *x* is declared as a special variable, the bindings works as a let, which means you can use special variables as function parameters. In your case this does not change much because you only set the current binding with the inner setq (the parameter shadows the global binding), so in effect this is a lot like a lexical variable.
But you can use a special variable to rebind dynamically a parameter:
(defun foo (*a*) ...)
This is the same as:
(defun foo (a)
(let ((*a* a))
...))
I have lisp in javascript which is similar to scheme. It can be used with lexical and dynamic scopes. I was not sure how dynamic scope works and it's seems ok but this code don't work when scope is dynamic:
(define Y
(lambda (h)
((lambda (x) (x x))
(lambda (g)
(h (lambda args (apply (g g) args)))))))
(define (trampoline f)
(lambda args
(let ((result (apply f args)))
(while (eq? (type result) "function")
(set result (result)))
result)))
(define (! n)
((trampoline (Y (lambda (f)
(lambda (n acc)
(if (== n 0)
acc
(lambda ()
(f (- n 1) (* n acc)))))))) n 1))
(print (! 1000))
it works fine when scope is lexical. Should this code work when scope is dynamic? Right now it just do nothing and I don't know why but wanted to be sure that this code should work before I start debugging and make my dynamic scope break because of this.
My lisp with demo is here https://jcubic.github.io/lips/ but the code that make this work for lexical scope is not yet published so it will not work. (it's in devel branch and I can create codepen demo with it or using Stack Snippet).
I don't see how trampoline can work with dynamic scoping.
Simplified evaluation:
(define Y ...)
Now Y is bound (to some value).
(define (trampoline f)
(lambda args
(let ((result (apply f args)))
...)))
Now trampoline is bound to (lambda (f) (lambda args (let ((result (apply f args))) ...))).
(define (! n)
((trampoline ...) n 1))
Now ! is bound to (lambda (n) ((trampoline ...) n 1)).
(print (! 1000))
We evaluate the inner call first, so we need to resolve ! and apply it to 1000.
By the definition of ! above we bind n to 1000 and evaluate ((trampoline ...) n 1).
We need to call trampoline. By the definition of trampoline above, we bind f to ... and return (lambda args (let ((result (apply f args))) ...)).
We return from trampoline and undo the binding of f.
We now need to evaluate ((lambda args (let ((result (apply f args))) ...)) n 1) (applying the return value of trampoline to n and 1).
n is currently bound to 1000, so this expression becomes ((lambda args (let ((result (apply f args))) ...)) 1000 1). To perform the call call we bind args to (1000 1).
Now we need to evaluate (apply f args) (to bind the result to result as part of let). apply is in the standard library. args was just bound to (1000 1) above. But there is no binding for f.
At this point we should throw an error: The only binding of f we've seen so far was during the call to trampoline (where f was a parameter). But that call has already returned and the binding was removed, so f is unbound.
Live demo (using a Perl version of your code where all bindings are made dynamic manually): https://ideone.com/DWjwBj
It blows up as predicted: Can't use an undefined value as a subroutine reference for the line local $result = $f->(#args); because $f is unbound.
If you change all bindings to lexical (replace all occurrences of local by my), $fac->(5) returns 120 as expected.
No. Trampoline and Y combinators work with closures.
Dynamic scope has no closures so a procedure/function that refers to a free variable means whatever variable with that name in the call stack of the program.
In Lexical scope it is the variables captured when the lambda was created. Thus the code:
(define test 10)
(define (make-adder test)
(lambda (v) (+ test v)))
(define add20 (make-adder 20))
(add20 5)
; ==> 25 in lexical scope
; ==> 15 in dynamic scope
The reson is simple. The function returned by the make-adder stores the value 20 as test, while in dynamic scope test is whatever is bound closest so it's the local variable 10. Also when calling:
(let ((test 30))
(add20 5))
; ==> 25 in lexical scope
; ==> 35 in dynamic scope
Now Common Lisp has dynamic scope and lexical scope. A dynamically scoped variable is one that is defined top level with defvar, defparameter or declared special. This is so prone to errors that we have a special naming for such variables using *earmuffs*.
Scheme has parameters that are mutable objects and there are syntax for updating and restoring it so that it will act as a dynamic variable.
EDIT
I've tested your lexical and dynamic lisp and both seem to work as intended.
I'm trying different binding models for macro lambda lists.
Edit: in fact the lambda list for my test macros is always (&rest ...). Which means that I'm 'destructuring' the argument list and not the lambda list. I try to get a solution that works for combining optional with key arguments or rest/body with key arguments - both combinations don't work in the Common Lisp standard implementation.
So I have different functions giving me a list of bindings having the same syntax as used by 'let'.
E.g:
(build-bindings ...) => ((first 1) middle (last "three"))
Now I thought to use a simple macro inside my test macros feeding such a list to 'let'.
This is trivial if I have a literal list:
(defmacro let-list (_list &rest _body)
`(let ,_list ,#_body))
(let-list ((a 236)) a) => 236
But that's the same as a plain 'let'.
What I'd like to have is the same thing with a generated list.
So e.g.
(let-list (build-bindings ...)
(format t "first: ~s~%" first)
last)
with (build-bindings ...), evaluated in the same lexical scope as the call (let-list ...), returning
((first 1) middle (last "three"))
the expansion of the macro should be
(let
((first 1) middle (last "three"))
(format t "first: ~s~%" first)
last)
and should print 1 and return "three".
Any idea how to accomplish that?
Edit (to make the question more general):
If I have a list of (symbol value) pairs, i.e. same syntax that let requires for it's list of bindings, e.g. ((one 1) (two 'two) (three "three")), is there any way to write a macro that creates lexical bindings of the symbols with the supplied values for it's &rest/&body parameter?
This is seems to be a possible solution which Joshua pointed me to:
(let ((list_ '((x 23) (y 6) z)))
(let
((symbols_(loop for item_ in list_
collect (if (listp item_) (car item_) item_)))
(values_ (loop for item_ in list_
collect (if (listp item_) (cadr item_) nil))))
(progv symbols_ values_
(format t "x ~s, y ~s, z ~s~%" x y z))))
evaluates to:
;Compiler warnings :
; In an anonymous lambda form: Undeclared free variable X
; In an anonymous lambda form: Undeclared free variable Y
; In an anonymous lambda form: Undeclared free variable Z
x 23, y 6, z NIL
I could also easily rearrange my build-bindings functions to return the two lists needed.
One problem is, that the compiler spits warnings if the variables have never been declared special.
And the other problem that, if the dynamically bound variables are also used in a surrounding lexical binding, they a shadowed by the lexical binding - again if they have never been declared special:
(let ((x 47) (y 11) (z 0))
(let ((list_ '((x 23) (y 6) z)))
(let
((symbols_(loop for item_ in list_
collect (if (listp item_) (car item_) item_)))
(values_ (loop for item_ in list_
collect (if (listp item_) (cadr item_) nil))))
(progv symbols_ values_
(format t "x ~s, y ~s, z ~s~%" x y z)))))
evaluates to:
x 47, y 11, z 0
A better way could be:
(let ((x 47) (y 11) (z 0))
(locally
(declare (special x y))
(let ((list_ '((x 23) (y 6) z)))
(let
((symbols_(loop for item_ in list_
collect (if (listp item_) (car item_) item_)))
(values_ (loop for item_ in list_
collect (if (listp item_) (cadr item_) nil))))
(progv symbols_ values_
(format t "x ~s, y ~s, z ~s~%" x y z))))))
evaluates to:
;Compiler warnings about unused lexical variables skipped
x 23, y 6, z NIL
I can't see at the moment whether there are other problems with the dynamic progv bindings.
But the whole enchilada of a progv wrapped in locally with all the symbols declared as special cries for a macro again - which is again not possible due to same reasons let-list doesn't work :(
The possiblilty would be a kind of macro-lambda-list destructuring-hook which I'm not aware of.
I have to look into the implementation of destructuring-bind since that macro does kind of what I'd like to do. Perhaps that will enlight me ;)
So a first (incorrect) attempt would look something like this:
(defun build-bindings ()
'((first 1) middle (last "three")))
(defmacro let-list (bindings &body body)
`(let ,bindings
,#body))
Then you could try doing something like:
(let-list (build-bindings)
(print first))
That won't work, of course, because the macro expansion leaves the form (build-bindings) in the resulting let, in a position where it won't be evaluated:
CL-USER> (pprint (macroexpand-1 '(let-list (build-bindings)
(print first))))
(LET (BUILD-BINDINGS)
(PRINT FIRST))
Evaluation during Macroexpansion time
The issue is that you want the result of build-bindings at macroexpansion time, and that's before the code as a whole is run. Now, in this example, build-bindings can be run at macroexpansion time, because it's not doing anything with any arguments (remember I asked in a comment what the arguments are?). That means that you could actually eval it in the macroexpansion:
(defmacro let-list (bindings &body body)
`(let ,(eval bindings)
,#body))
CL-USER> (pprint (macroexpand-1 '(let-list (build-bindings)
(print first))))
(LET ((FIRST 1) MIDDLE (LAST "three"))
(PRINT FIRST))
Now that will work, insofar as it will bind first, middle, and last to 1, nil, and "three", respectively. However, if build-bindings actually needed some arguments that weren't available at macroexpansion time, you'd be out of luck. First, it can take arguments that are available at macroexpansion time (e.g., constants):
(defun build-bindings (a b &rest cs)
`((first ',a) (middle ',b) (last ',cs)))
CL-USER> (pprint (macroexpand-1 '(let-list (build-bindings 1 2 3 4 5)
(print first))))
(LET ((FIRST '1) (MIDDLE '2) (LAST '(3 4 5)))
(PRINT FIRST))
You could also have some of the variables appear in there:
(defun build-bindings (x ex y why)
`((,x ,ex) (,y ,why)))
CL-USER> (pprint (macroexpand-1 '(let-list (build-bindings 'a 'ay 'b 'bee)
(print first))))
(LET ((A AY) (B BEE))
(PRINT FIRST))
What you can't do, though, is have the variable names be determined from values that don't exist until runtime. E.g., you can't do something like:
(let ((var1 'a)
(var2 'b))
(let-list (build-bindings var1 'ay var2 'bee)
(print first))
because (let-list (build-bindings …) …) is macroexpanded before any of this code is actually executed. That means that you'd be trying to evaluate (build-bindings var1 'ay var2 'bee) when var1 and var2 aren't bound to any values.
Common Lisp does all its macroexpansion first, and then evaluates code. That means that values that aren't available until runtime are not available at macroexpansion time.
Compilation (and Macroexpansion) at Runtime
Now, even though I said that Common Lisp does all its macroexpansion first, and then evaluates code, the code above actually uses eval at macroexpansion to get some extra evaluation earlier. We can do things in the other direction too; we can use compile at runtime. That means that we can generate a lambda function and compile it based on code (e.g., variable names) provided at runtime. We can actually do this without using a macro:
(defun %dynamic-lambda (bindings body)
(flet ((to-list (x) (if (listp x) x (list x))))
(let* ((bindings (mapcar #'to-list bindings))
(vars (mapcar #'first bindings))
(vals (mapcar #'second bindings)))
(apply (compile nil `(lambda ,vars ,#body)) vals))))
CL-USER> (%dynamic-lambda '((first 1) middle (last "three"))
'((list first middle last)))
;=> (1 NIL "three")
This compiles a lambda expression that is created at runtime from a body and a list of bindings. It's not hard to write a macro that takes some fo the quoting hassle out of the picture:
(defmacro let-list (bindings &body body)
`(%dynamic-lambda ,bindings ',body))
CL-USER> (let-list '((first 1) middle (last "three"))
(list first middle last))
;=> (1 NIL "three")
CL-USER> (macroexpand-1 '(let-list (build-bindings)
(list first middle last)))
;=> (%DYNAMIC-LAMBDA (BUILD-BINDINGS) '((LIST FIRST MIDDLE LAST)))
CL-USER> (flet ((build-bindings ()
'((first 1) middle (last "three"))))
(let-list (build-bindings)
(list first middle last)))
;=> (1 NIL "three")
This gives you genuine lexical variables from a binding list created at runtime. Of course, because the compilation is happening at runtime, you lose access to the lexical environment. That means that the body that you're compiling into a function cannot access the "surrounding" lexical scope. E.g.:
CL-USER> (let ((x 3))
(let-list '((y 4))
(list x y)))
; Evaluation aborted on #<UNBOUND-VARIABLE X {1005B6C2B3}>.
Using PROGV and special variables
If you don't need lexical variables, but can use special (i.e., dynamically scoped) variables instead, you can establish bindings at runtime using progv. That would look something like:
(progv '(a b c) '(1 2 3)
(list c b a))
;;=> (3 2 1)
You'll probably get some warnings with that if run it, because when the form is compiled, there's no way to know that a, b, and c are supposed to be special variables. You can use locally to add some special declarations, though:
(progv '(a b c) '(1 2 3)
(locally
(declare (special a b c))
(list c b a)))
;;=> (3 2 1)
Of course, if you're doing this, then you have to know the variables in advance which is exactly what you were trying to avoid in the first place. However, if you're willing to know the names of the variables in advance (and your comments seem like you might be okay with that), then you can actually use lexical variables.
Lexical variables with values computed at run time
If you're willing to state what the variables will be, but still want to compute their values dynamically at run time, you can do that relatively easily. First, lets write the direct version (with no macro):
;; Declare three lexical variables, a, b, and c.
(let (a b c)
;; Iterate through a list of bindings (as for LET)
;; and based on the name in the binding, assign the
;; corresponding value to the lexical variable that
;; is identified by the same symbol in the source:
(dolist (binding '((c 3) (a 1) b))
(destructuring-bind (var &optional value)
(if (listp binding) binding (list binding))
(ecase var
(a (setf a value))
(b (setf b value))
(c (setf c value)))))
;; Do something with the lexical variables:
(list a b c))
;;=> (1 NIL 3)
Now, it's not too hard to write a macrofied version of this. This version isn't perfect, (e.g., there could be hygiene issues with names, and declarations in the body won't work (because the body is being spliced in after some stuff). It's a start, though:
(defmacro computed-let (variables bindings &body body)
(let ((assign (gensym (string '#:assign-))))
`(let ,variables
(flet ((,assign (binding)
(destructuring-bind (variable &optional value)
(if (listp binding) binding (list binding))
(ecase variable
,#(mapcar (lambda (variable)
`(,variable (setf ,variable value)))
variables)))))
(map nil #',assign ,bindings))
,#body)))
(computed-let (a b c) '((a 1) b (c 3))
(list a b c))
;;=> (1 NIL 3)
One way of making this cleaner would be to avoid the assignment altogether, and the computed values to provide the values for the binding directly:
(defmacro computed-let (variables bindings &body body)
(let ((values (gensym (string '#:values-)))
(variable (gensym (string '#:variable-))))
`(apply #'(lambda ,variables ,#body)
(let ((,values (mapcar #'to-list ,bindings)))
(mapcar (lambda (,variable)
(second (find ,variable ,values :key 'first)))
',variables)))))
This version creates a lambda function where the arguments are the specified variables and the body is the provided body (so the declarations in the body are in an appropriate place), and then applies it to a list of values extracted from the result of the computed bindings.
Using LAMBDA or DESTRUCTURING-BIND
since I'm doing some "destructuring" of the arguments (in a bit a different way), I know which arguments must be present or have which
default values in case of missing optional and key arguments. So in
the first step I get a list of values and a flag whether an optional
or key argument was present or defaulted. In the second step I would
like to bind those values and/or present/default flag to local
variables to do some work with them
This is actually starting to sound like you can do what you need to by using a lambda function or destructuring-bind with keyword arguments. First, note that you can use any symbol as a keyword argument indicator. E.g.:
(apply (lambda (&key
((b bee) 'default-bee b?)
((c see) 'default-see c?))
(list bee b? see c?))
'(b 42))
;;=> (42 T DEFAULT-SEE NIL)
(destructuring-bind (&key ((b bee) 'default-bee b?)
((c see) 'default-see c?))
'(b 42)
(list bee b? see c?))
;;=> (42 T DEFAULT-SEE NIL)
So, if you just make your function return bindings as a list of keyword arguments, then in the destructuring or function application you can automatically bind corresponding variables, assign default values, and check whether non-default values were provided.
Acting a bit indirectly:
a solution that works for combining optional with key arguments or
rest/body with key arguments
Have you considered the not-entirely-uncommon paradigm of using a sub-list for the keywords?
e.g.
(defmacro something (&key (first 1) second) &body body) ... )
or, a practical use from Alexandria:
(defmacro with-output-to-file ((stream-name file-name
&rest args
&key (direction nil direction-p)
&allow-other-keys)
&body body)
To me these operators seem to do the same thing. Both take a symbol and return the function associated with it. Is there any difference?
elisp evaluation returns the following:
(defun foo (x) (+ 1 x))
foo
(foo 3)
4
#'foo
Which I don't understand either.
Furthermore is there a difference between common lisp and elisp? I'm learning from resources on either.
Common Lisp:
SYMBOL-FUNCTION can't retrieve functions from lexically bound functions. FUNCTION references the lexically bound function by default. #'foo is just a shorter notation for (FUNCTION foo).
CL-USER 1 > (defun foo () 'foo)
FOO
CL-USER 2 > (flet ((foo () 'bar))
(list (funcall (symbol-function 'foo))
(funcall #'foo)
(funcall (function foo))
(eq (function foo) (symbol-function 'foo))))
(FOO BAR BAR NIL)
CL-USER 3 > (eq (function foo) (symbol-function 'foo))
T
Rainer's answer discusses the things that you can do with function that you can't do with symbol-function, namely retrieve the value of lexically scoped functions, but there are a few other differences too.
The special operator FUNCTION
The special operator FUNCTION provides a way to find the functional value of a name in a lexical environment. Its argument is either a function name or a lambda expression. That function can take a lambda expression means that you can write: (function (lambda (x) (list x x))). The term function name includes more than just symbols. It also includes lists of the form (setf name), which means that you can do things like (function (setf car)).
The accessor SYMBOL-FUNCTION
The accessor symbol-function, on the other hand, lets you retrieve and set the functional value of a symbol. Since it requires a symbol, you can't do (symbol-function (lambda …)) or (function (setf name)). Symbol-function also can't see lexical environments; it only works with global definitions. E.g.,
(flet ((foo () 'result))
(symbol-function 'foo))
;=> NIL
Since symbol-function is an accessor, you can change the value of a function's symbol with it. E.g.:
CL-USER> (setf (symbol-function 'foo) (lambda () 42))
#<FUNCTION (LAMBDA ()) {1005D29AAB}>
CL-USER> (foo)
42
CL-USER> (setf (symbol-function 'foo) (lambda () 26))
#<FUNCTION (LAMBDA ()) {1005D75B9B}>
CL-USER> (foo)
26
The accessor FDEFINITION
There's also the accessor fdefinition which is kind of like symbol-function in that is can only access globally defined functions, but kind of like function in that it can access of symbols and (setf name) lists. However, it does not retrieve the value of lambda functions.
I'm just learning ANSI Common Lisp (using clisp on a Win32 machine) and I was wondering if mapcar could use a function passed in as a formal argument? Please see the following:
(defun foo (fn seq)
(mapcar #'fn seq))
This would, in my opinion, provide a greater level of flexibility than:
(defun mult (i)
(* i 2))
(defun foo ()
(mapcar #'mult '(1 2 3)))
This is absolutely possible! You're almost there. You just bumped into Common Lisp's dual namespaces, which can take a lot of getting used to. I hope I can say a thing or two to make Common Lisp's two namespaces a bit less confusing.
Your code is almost correct. You wrote:
(defun foo (fn seq)
(mapcar #'fn seq))
But, what is that trying to do? Well, #' is shorthand. I'll expand it out for you.
(defun foo (fn seq)
(mapcar (function fn) seq))
So, #'symbol is shorthand for (function symbol). In Common Lisp -- as you seem to know -- symbols can be bound to a function and to a variable; these are the two namespaces that Lispers talk so much about: the function namespace, and the variable namespace.
Now, what the function special form does is get the function bound to a symbol, or, if you like, the value that the symbol has in the function namespace.
Now, on the REPL, what you wrote would be obviously what you want.
(mapcar #'car sequence)
Would map the car function to a sequence of lists. And the car symbol has no variable binding, only a function binding, which is why you need to use (function ...) (or its shorthand, #') to get at the actual function.
Your foo function doesn't work because the function you pass it as an argument is being bound to a symbol as a variable. Try this:
(let ((fn #'sqrt))
(mapcar #'fn '(4 9 16 25)))
You might have expected a list of all those numbers' square roots, but it didn't work. That's because you used let to bind the square root function to fn as a variable. Now, try this code:
(let ((fn #'sqrt))
(mapcar fn '(4 9 16 25)))
Delightful! This binds the square root function to the fn symbol as a variable.
So, let's go revise your foo function:
(defun foo (fn seq)
(mapcar fn seq))
That will work, because fn is a variable. Let's test it, just to make sure:
;; This will not work
(foo sqrt '(4 9 16 25))
;; This will work
(foo #'sqrt '(4 9 16 25))
The first one didn't work, because the square root function is bound to sqrt in the function namespace. So, in the second one, we grabbed the function from the symbol, and passed it to foo, which bound it to the symbol fn as a variable.
Okay, so what if you want to bind a function to a symbol in the function namespace? Well, for starters, defun does that, permanently. If you want it to be temporary, like a let binding, use flet. Flet is, in my opinion, stupid, because it doesn't work exactly like let does. But, I'll give an example, just so you can see.
(flet ((fn (x) (sqrt x)))
(mapcar fn '(4 9 16 25)))
will not work, because flet didn't bind the function to the symbol in the variable namespace, but in the function namespace.
(flet ((fn (x) (sqrt x)))
(mapcar #'fn '(4 9 16 25)))
This will do what you expect, because flet bound that function to the symbol fn in the function namespace. And, just to drive the idea of the function namespace home:
(flet ((fn (x) (sqrt x)))
(fn 16))
Will return 4.
Sure, you can do this:
(defun foo (fn)
(mapcar fn '(1 2 3)))
Examples:
(foo #'(lambda (x) (* x 2)))
(foo #'1+)
(foo #'sqrt)
(foo #'(lambda (x) (1+ (* x 3))))