I've done some tests in Common Lisp :
(defvar *a* 0)
(defvar *b* *a*)
(setf *b* 5)
*b* ; returns 5 of course
*a* ; returns 0. Is there a way to set it to 5 without setting *a* directly, via *b* ?
Is there a simple way to simultaneously :
set the value of *b* as a sort of "function" which checks if the value of *b* is a symbol, if "yes" access to the value of the symbol (here *a*) and so on until it is a non-symbol atom or a symbol which points to nothing or to himself,
*b* is self-evaluating (important, i do not want to (funcall ...) everywhere) and returns the non-symbol atom or ...(see definition above).
The question can be reformulated : Is this possible to set a variable to a function, and when evaluating this variable evaluate the function ? Is there a way to force and control self-evaluation ?
I've thought to change the eval function (probably a very bad idea), or to create a custom defvar and custom setf, but maybe is there a built-in tool for this ?
I know it is possible to set *b* to a function like (lambda () *a*) but I would prefer to use only *b* instead of (funcall *b*) for code readability.
Note : I have a preference for a non-macro solution since i could use this feature at runtime.
I think you are looking for define-symbol-macro:
(defvar *a* 1)
(define-symbol-macro *b* *a*)
*b*
==> 1
(setq *b* 5)
*a*
==> 5
See also Symbols as Forms.
Related
How to evaluate some lisp code using eval in not null lexical environment ? I need this feature for proper interpolation functionality.
If you model your environment as bindings like those found in let:
((x 3) (y 2))
... then you can evaluate any form f with those bindings in place, like so:
(eval `(let ,e ,f))
This is the simplest case, but you can easily convert your data to fit this syntax. You can also bind functions, macros, etc. if needed.
Note that if you need values at runtime, then maybe dynamic bindings are better. You can use hash-tables, etc. but note that there is also the lesser-known PROGV special operator:
Among other things, progv is useful when writing interpreters for languages embedded in Lisp; it provides a handle on the mechanism for binding dynamic variables.
Although I think the OP knows the answer already, let me try to give a somewhat more descriptive solution, hoping more experienced lispers can point to mistakes I may make below:
As #coredump mentions, progv is an option as well as a let form in eval. Here is an example:
Let's create a list with some numbers and a cons that has a lambda form, bypassing the reader lambda conversion:
(setf list1 '(1
1
(lambda ()
(print a))))
we can eval:
(eval
`(let ((a 3))
;; statement after comma is turned to a function by the reader.
;; same effect with explicit (funcall (function ,(third list1)))
;; because of the (lambda ..) macro form
(funcall ,(third list1))))
3
3
Note that variable a above is lexical, not special.
now, with progv we can create special variables and eval will use them.
Let's first start with a mistake:
(progv '(a) '(4)
(funcall (function (third list1))))
Error: (THIRD LIST1) is not a valid argument for FUNCTION.
or similarly:
(progv '(a) '(4)
(funcall (third list1)))
Error: Argument to apply/funcall is not a function: (LAMBDA NIL (PRINT A)).
Then, let's evaluate or compile:
(progv '(a) '(4)
(funcall (eval (third list1))))
4
4
or
(progv '(a) '(4)
(funcall (compile nil (third list1))))
Warning in 246: A assumed special
4
4
Above is the behaviour I got with LispWorks 7.1. eval didn't give the warning for special assumption, because:
(eval (third list1))
#<anonymous interpreted function 40600009EC>
eval returned an interpreted function, not compiled. If we further compile, then we'll see the same warning:
(eval (third list1))
#<anonymous interpreted function 40600009EC>
(compile nil *)
;;;*** Warning in 248: A assumed special
To make things right with progv, since it creates special variables, change the function:
(setf list1 '(1
1
(lambda ()
(declare (special a))
(print a))))
(progv '(a) '(4)
(funcall (compile nil (third list1))))
4
4
Note that to make the example politically correct, as CLHS does in progv page, we should better use (progv '(*a*) '(4) ...) and the lambda function should be defined with the *a* variable.
I thought I would be able to find this through Google, SO, or the books I'm reading, but it is proving elusive.
In the implementation I'm learning with, I can do the following at the top-level:
(defvar *foo* 4)
(set 'bar 3)
If I then call (describe '*foo*) and (describe 'bar), I get a description saying that *foo* is special and bar is non-special (among other details).
Is there a function that takes a symbol variable as an argument and returns true or false if it is special? If so, is describe probably implemented in part by calling it?
Context: I'm learning Common Lisp, but at work I have a system with a dialect of Lisp similar to Common Lisp, but the describe function is unimplemented. There's sort of an XY thing going on here, but I'm also trying to grok Lisp and CL.
Many Common Lisp implementations provide the function variable-information in some system dependent package.
Here in SBCL:
* (require :sb-cltl2)
NIL
* (sb-cltl2:variable-information '*standard-output*)
:SPECIAL
NIL
((TYPE . STREAM))
This function was proposed as part of some other functionality to be included into ANSI CL, but didn't make it into the standard. Still many implementations have it. For documentation see: https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node102.html
A non-special variable's environment will be captured when you create a closure over it:
(let ((x 1))
(let ((f (lambda () x)))
(let ((x 2))
(eql 2 (funcall f)))))
;;=> NIL
A special variable's lexical environment will not:
(defvar *x*) ; *x* is special
(let ((*x* 1))
(let ((f (lambda () *x*)))
(let ((*x* 2))
(eql 2 (funcall f)))))
;;=> T
Using this approach, you could easily define a macro that will expand to code like the previous that will let you determine whether a symbol is globally proclaimed special:
(defmacro specialp (symbol)
(let ((f (gensym "FUNC-")))
`(let ((,symbol 1))
(let ((,f (lambda () ,symbol)))
(let ((,symbol 2))
(eql 2 (funcall ,f)))))))
(specialp x) ;=> NIL
(specialp *x*) ;=> T
Note that this isn't a function, it's a macro. That means that the macro function for specialp is getting called with the symbols X and *X*. This is important, because we have to construct code that uses these symbols. You can't do this with a function, because there'd be no (portable) way to take a symbol and create a lexical environment that has a lexical variable with that name and a lambda function that refers to it.
This also has some risks if you try to use it with certain symbols. For instance, in SBCL, if you try to bind, e.g., *standard-output* to something that isn't a stream or a stream designator, you'll get an error:
CL-USER> (specialp *standard-output*)
; in: SPECIALP *STANDARD-OUTPUT*
; (LET ((*STANDARD-OUTPUT* 1))
; (LET ((#:FUNC-1038 (LAMBDA # *STANDARD-OUTPUT*)))
; (LET ((*STANDARD-OUTPUT* 2))
; (EQL 2 (FUNCALL #:FUNC-1038)))))
;
; caught WARNING:
; Constant 1 conflicts with its asserted type STREAM.
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 1 WARNING condition
Defining globals with set or setq is not supported. There are 2 common ways to define globals:
(defparameter *par* 20) ; notice the earmuffs in the name!
(defvar *var* 30) ; notice the earmuffs in the name!
All global variables are special. Lexically scoped variables (not special) are not possible to get described. E.g.
(let ((x 10))
(describe 'x)) ; ==> X is the symbol X
It describes not the lexical variable but the symbol representation. It really doesn't matter since you probably never need to know in run time since you know this when you're writing if it's a bound lexical variable or global special by conforming to the earmuffs naming convention for global variables.
I believe the only way to get this information at run time* is by either using an extension to CL, as Rainer noted, or to use eval.
(defun specialp (x)
(or (boundp x)
(eval `(let (,x)
(declare (ignorable ,x))
(boundp ',x)))))
(Defect warning: If the variable is unbound but declared to be a type incompatible with nil, this could raise an error. Thanks Joshua for pointing it out in his answer.)
* The macro approach determines which symbol it is checking at macro expansion time, and whether that symbol is lexical or special at compile time. That's fine for checking the status of a variable at the repl. If you wanted to e.g. print all of the special variables exported by a package, though, you would find that to use the macro version you would end up having to use eval at the call site:
(loop for s being the external-symbols of :cl-ppcre
when (eval `(specialp-macro ,s)) do (print s))
Currently I am reading "Land of Lisp". In one of the recent code samples the author gave:
> (eq 'fooo 'FoOo)
T
to prove that the symbols are case-insensitive. A few pages later data mode is formally introduced.
However I fail to really understand the following. eq is a function, so its name is case-insensitive as well. Therefore I should be able to do this:
> (eq 'Eq 'EQ)
T
Great. That worked as expected. But what if I put this into a list in data mode? Keep in mind, I am just experimenting with something that's new for me.
> (eq '(Eq) '(EQ))
NIL
> (eq '('Eq) '('EQ))
NIL
Uhm. Okay? Why is that? I would have expected that if I put the same symbol into two lists, that the lists would be considered equal.
Now the question: does that mean that not the contents of the lists are compared, but the list "objects" themselves? What am I missing?
Symbols are Case-Sensitive
> (eq (print (intern "foo")) (print (intern "FOO")))
|foo| ; printed
FOO ; printed
==> NIL ; returned
The default reader is Case-Converting
(eq (read-from-string "foo") (read-from-string "FOO"))
==> T
However, you can make the reader case-preserving:
(let ((*readtable* (copy-readtable)))
(setf (readtable-case *readtable*) :preserve)
(eq (read-from-string "foo") (read-from-string "FOO")))
==> NIL
Please take a look at
Reader Algorithm
Effect of Readtable Case on the Lisp Reader
EQ compares for pointer identity
Common Lisp provides 4 equality predicates, you should use the right one for your needs:
(equal '(Eq) '(EQ))
==> T
(equal '('Eq) '('EQ))
==> T
eq compares for things to be exactly the same, think pointer equality. This is like == in Java, even logically equivalent data will be falsy.
The solution here is to use equal which just does the "intelligent" thing and compares the lists' elements
> (equal '(A) '(a))
T
Additionally symbols are case sensitive. But by default the reader (the thing that turns code into an AST) defaults to being case insensitive. You can notice this distinction with a function like intern.
Lisp symbols are case sensitive. And even the lisp reader is case sensitive. The only point is that when the reader reads a symbol it usually make it in uppercase. The easiest way to tell the reader that the case in important is to put it between the vertical lines.
> '|asd|def|ghj|
|asdDEFght|
> '|asd|
|asd|
> '|ASD|
ASD
> 'ASD
ASD
> (eq 'asd '|ASD|)
t
> (eq 'asd '|aSd|)
nil
The eq predicate check that the arguments are the same objects (similar to compare the pointers to variables in C)
> (defparameter *x* 1)
> (defparameter *y* 1)
> (eq *x* *y*)
nil
So when you write '(asd) in REPL the list with one element is created. And when you write it the second time another list is created and these lists are actually different objects.
> (defparameter *list1* '('qwe))
> (defparameter *list2* '('qwe))
> (eq *list1* list2*) ;this are 2 different objects
nil
> (setf (first *list1* 'def))
> *list1* ;this list has changed
(DEF)
> *list2* ;and this did not
(QWE)
> (setf *list1* *list2*) ;now they are just different names for one object
> *list1*
(QWE)
> (eq *list1* *list2*)
t
There are another ways how to compare objects (eq eql equal equalp =). It's better to read documentation and play with REPL to see the difference.
To complicate things a bit.
Let's say we have the following in a file. Then we compile and load that file.
(defparameter *a* '(1))
(defparameter *b* '(1))
Now we calculate:
(eq *a* *b*)
It is undefined if this is NIL or T. The Common Lisp compiler may detect that the lists are equal and set both variables to the same list - that is EQ then also would be true. Actually there are Common Lisp compilers which are doing this. Executing the two DEFPARAMETER forms in a *REPLone would usually expect that the Lisp system does not detect that and that(eq a *b*)isNIL`.
EQUAL compares structure and (eq *a* *b*) for our example is always T.
I've tried to reduce it to the minimal example. The code runs without an error, producing the expected output. But it gives me a warning that my first variable is undefined. It seems that the second statement of progn doesn't "see" the results of the first statement. Thanks for the help!
(I originally did not have the progn construct in the code at all, but after getting this error I added it to see if that would force execution in order -- but the error is the same.)
Here's the code:
(let ((input (open "input.lisp")))
(progn (defvar var1 (read input))
(defvar arr1 (make-array var1 :initial-contents (read input))))
(close input))
(print var1)
(print arr1)
These are the contents of the file "input.lisp":
9
(10 8 6 4 2 4 6 8 10)
And this is the output I get from sbcl after executing (load "test.lisp"):
; in: DEFVAR ARR1
; (MAKE-ARRAY VAR1 :INITIAL-CONTENTS (READ INPUT))
;
; caught WARNING:
; undefined variable: VAR1
;
; compilation unit finished
; Undefined variable:
; VAR1
; caught 1 WARNING condition
9
#(10 8 6 4 2 4 6 8 10)
T
So, it seems to me that both definition statements are executing, but the second doesn't "see" the results of the first. It still constructs the array correctly because it's filled with the given initial-contents. But why isn't var1 already defined?
See the documentation for defvar in the Hyperspec:
If a defvar or defparameter form appears as a top level form, the compiler must recognize that the name has been proclaimed special.
This implies (and it seems to be the case for SBCL) that if a defvar appears as a non-top-level form, then the compiler need not recognize that the name has been declared. So how come your defvars are not being compiled as top level forms? See section 3.2.3.1, Processing of Top Level Forms (point 6) for the answer: the let surrounding your code causes it to be compiled as non-top-level forms.
So you need to defvar your variables at top level, and then assign them later on with setf inside the let.
Like this. It's also usually simpler to use with-open-file rather than open and close.
(defvar var1)
(defvar arr1)
(with-open-file (input "input.lisp" :direction :input)
(setf var1 (read input))
(setf arr1 (make-array var1 :initial-contents (read input))))
(print var1)
(print arr1)
The reason that you are having this trouble is that you are placing your code at top level in the file. This is a slightly unusual thing to do: the normal Lisp coding style is to put most of your code in function definitions, and then to call those functions when you need to run them.
For example, this would be a more typical way to write this kind of code, with the initialization code in its own function.
(defvar *var1* nil "Documentation for var1.")
(defvar *arr1* nil "Documentation for arr1.")
(defun init-from-file (file)
"Read *var1* and *arr1* from file."
(with-open-file (input file :direction :input)
(setf *var1* (read input))
(setf *arr1* (make-array *var1* :initial-contents (read input)))))
(when (null *var1*) (init-from-file "input.lisp"))
Considering the behavior of dynamic and lexical bound variables, I understand the output of symbol-value in the following code (dynamically bound variable a is shadowed by a lexical bound variable a (that explanation is wrong, see edit below)):
(defvar a 1)
(let ((a 2))
(list a (symbol-value 'a)))
; => (2 2)
But when using progv to create a similar environment, symbol-value gives a different result:
(progv '(x) '(1)
(let ((x 2))
(list x (symbol-value 'x))))
; => (2 1)
Why is (symbol-value 'x) returning 1 in the second example?
final edit accompanying the accepted answer: throughout comments at Rainer Joswig's answer I learnt that (let ((a 2)) ... ) does not bind a lexical variable, but shadows the value of the former dynamic binding. Also Martin Buchmann pointed out, in a comment, that symbol-value ignores lexical variables.
The PROGV special form creates dynamic bindings, but does not declare the variable to be special for enclosed forms.
Thus we need to declare the LET binding of the variable x to be special:
CL-USER 27 > (progv '(x) '(1)
(let ((x 2))
(declare (special x))
(list x (symbol-value 'x))))
(2 2)
DEFVAR OTOH declares its variable to be special. Globally and there is no direct way to undo that declaration.