common lisp's let binds, not executes? - common-lisp

In this code
(defun foo ()
. . .
(let ((bar (foo)))
(if bar
. . .)))
in the let line, let is only binding, right? It doesn't actually run foo. I assume foo is run (recursively) for the first time in the if statement, correct? If what I assume is correct, is there a way to have let actually execute foo and then assign the results to bar?

There's an answer that shows an example that illustrates the behavior of let. However, an example via an implementation doesn't answer conclusively whether it's supposed to behave that way, or whether implementations are free to do different things, or whether there's a bug in the implementation. To know what's supposed to happen, you need to check the documentation. Fortunately, the Common Lisp HyperSpec is freely available online. The documentation for let says:
Special Operator LET, LET*
let and let* create new variable bindings and execute a series of
forms that use these bindings. let performs the bindings in parallel
and let* does them sequentially.
The form
(let ((var1 init-form-1)
(var2 init-form-2)
...
(varm init-form-m))
declaration1
declaration2
...
declarationp
form1
form2
...
formn)
first evaluates the expressions init-form-1, init-form-2, and so on,
in that order, saving the resulting values. Then all of the variables
varj are bound to the corresponding values; each binding is lexical
unless there is a special declaration to the contrary. The expressions
formk are then evaluated in order; the values of all but the last are
discarded (that is, the body of a let is an implicit progn).
Thus, all the forms are evaluated (executed), then the results are bound the values, and then the forms in the body are evaluated.

In the example you provided, foo is evaluated and then assigned to bar. You can test this by simply evaluating something like:
(let ((foo (+ 1 2)))
(if (= foo 3)
foo
nil))
; => 3
cf. PCL: Syntax and Semantics or Lispdoc.
Edit
As #paulo-madeira brought up in the comments, this is not enough to test, since you don't know when each one was evaluated. See his comment for a way to test it using FORMAT. Anyway, the takeaway is, the LET you propose evaluates foo and assigns it to bar, which means your function foo is defined in terms of itself, which means you're up to no good.

Related

Is it valid to use "setf" to create special variables?

It appears that I can use setf to create special variables. For example, if I start the REPL and enter (setf x 123), a special variable x will be created. There is no error in CLISP and ECL. SBCL gives a warning (undefined variable: COMMON-LISP-USER::X), but creates the special variable anyway. Is setf a valid way to create special variables?
It is not valid to use setf to create new variables. The HyperSpec is pretty clear that setf is only intended to update existing variables:
setf changes the value of place to be newvalue.
(setf place newvalue) expands into an update form that stores the result of evaluating newvalue into the location referred to by place.
setf is intended for updating a place. There is no behavior specified for attempting to use setf to update the value of a place that does not already exist.
In the section which discusses assignment, CLTL2 says a bit more:
Such alteration is different from establishing a new binding. Constructs for establishing new bindings of variables are described in section 7.5.
While this may seem to work, you can't rely on it. It often works in REPLs, and it is fine if you want to use setf this way when playing around in a REPL, but you should not do this in any program.
Actually it is a bit tricky.
This is one of the things in Common Lisp which are underspecified. Unfortunately.
LispWorks:
CL-USER 61 > (setf foo 1)
1
CL-USER 62 > (defun bar () foo)
BAR
CL-USER 63 > (bar)
1
CL-USER 64 > (let ((foo 2))
(bar))
1
The last foo in the let is using lexical binding and thus there it is not assumed to be special.
In the forms (setf foo 1) and (defun bar () foo) the variable foo is assumed by the particular Lisp implementation to be special and it even could be declared to be special by setf (-> which most implementations don't).
Whether above let form returns 1 or 2 is unspecified in the Common Lisp language standard. Most implementations will return 1, though.
Next:
CL-USER 65 > (let ((foo 2))
(declare (special foo))
(bar))
2
Above we see that the use of foo inside bar is actually using the dynamic binding of foo in the let.
Basically the exact effects of setting an undefined variable is unspecified. The variable could be assumed to be special or not. Most implementations prefer to NOT declare it special, such that further use of the variable must be special.
But whether the variable is special or not, and the exact effects using it, is actually undefined in the Common Lisp language standard.
Most implementations agree
that setf setting an undefined variable only changes the symbol value of the symbol
that setting and retrieving the variable is assuming a special variable
that rebinding the variable by let(or similar) does not create a special variable
that a compiler (if used) will warn about an undefined variable and/or about assuming a special variable.
One implementation where the default disagrees is CMUCL -> there the setf also declares the variable to be special, similar to what defparameter would do.
For a general style rule see the last paragraph of ad absurdum's answer.

Usefulness/point of function "symbol-name"?

On first look it seems somewhat silly to have a function which returns the name of a symbol, which must be called using the name of that same symbol. i.e. it should already be obvious in the calling context what the function will return. On the other hand there is identity which is sometimes useful (I forget where just now) but I supposed (perhaps wrongly) that symbol-function is there for a reason other than simply to act as a kind of identity.
However, the hyperspec offers a possible hint:
(symbol-name 'temp) => "TEMP"
(symbol-name :start) => "START"
(symbol-name (gensym)) => "G1234" ;for example
I note that :start means get the name of the symbol start from the keyword package, where the keyword package is denoted simply by :.
(:keyword being its longer form, unnecessary to use). Thus, in this case symbol-name plays the role of simply removing the package prefix.
The other thing it might do is, given an implementation is case insensitive, it would get the actual name by removing case in the symbol name supplied.
Is that roughly it or is there any importance to this function I am missing?
One thing I was confused by about symbols (cleared up now) is that symbol-plist does not tell you everything about the symbol (say, whether it holds the value of a special variable or function). Rather, plist is a mainly legacy feature now largely replaced by hashtables. So, a call to symbol-plist is going to return NIL even if one has set a special variable on the symbol.
One final question on that, Paul Graham says in Chapter 8 (p133), that "You can use symbols as data objects and as names for things without understanding how the two are related". Would it be correct say that if we rarely now use plists, that, today, we generally don't use symbols "as data objects" at all, instead, just as names for things (allbeit with the duality in CL of course, i.e. symbol-function and symbol-value simultaneously).
Symbols are objects. You can create them and pass them around programmatically. One of the properties of these objects is their name, which is a string. Symbol-name is the reader (not accessor) for that. That's all.
Symbols are also used in the representation of code. In this case, they are created by the reader and used by the compiler. This is not their only use, however, and the spec makes no such assumptions either. I hope that this addresses the core of your question.
Here is a function that, given a symbol, returns a symbol interned in the same package but with a reversed name:
(defun reverse-symbol (symbol)
(intern (make-symbol (reverse (symbol-name symbol)))
(symbol-package symbol)))
Here is a function that, given a string designator, returns the designated string:
(defun designated-string (string-designator)
(ctypecase string-designator
(string string-designator)
(symbol (symbol-name string-designator))))
You can also do all kinds of shenanigans in macros and compiler macros by inspecting the names of the symbols in the given form and applying some conventions (not that you should…).
Let's assume you want to write some protocol for transmitting bits of structure between two different systems over some serial channel
(defgeneric transmit-object (o stream))
What is the method for symbols going to look like?
(defmethod transmit-object ((o symbol) stream)
... (symbol-name o) ...)
In particular you certainly do not know the name of the symbol at the point where you need to reason about it, and you could not write such a protocol without using symbol-name (or some absolutely appalling hack like printing the symbol to a string and using that).
Regarding symbol-plist, the implementation is completely at liberty to keep all sorts of information on the property list of a symbol. I am not even sure that the implementation is not allowed to do (a cleverer version of):
(defun symbol-value (s)
(let* ((d (load-time-value (cons nil nil)))
(v (get s secret-value-indicator d)))
(when (eq v d)
(error ...))
v))
It may be that this is not allowed, but I am not sure. Certainly it was once fairly common for function definitions to be kept in this way.
It's not so silly when you process symbol names. When you for example build preprocessor - you read some data, convert it to list structures and then some code is processing those list and trigger some additional logic when symbol-name is lets say defun-my-ubermacro. It's exactly what's in Graham quote - you treat symbols as data.
And (in my opinion) it's not correct to say, that when you don't use plists, you generally don't use symbols as data. Plists are only on of many places where it's useful feature. A lot of what macros do is processing symbols as data / names.
On first look it seems somewhat silly to have a function which returns the name of a symbol, which must be called using the name of that same symbol.
That's wrong. symbol-name is called with a symbol and not a name. It returns the name as a string.
I note that :start means get the name of the symbol start from the keyword package, where the keyword package is denoted simply by :. (:keyword being its longer form, unnecessary to use). Thus, in this case symbol-name plays the role of simply removing the package prefix.
No, symbol-name returns the name of the symbol as a string. The keyword symbol is an object of type symbol.
A symbol is a data type and has several cells:
the name, a string
possibly a function
possibly a value
a property list
optionally the home package it is interned in
don't use symbols "as data objects" at all, instead, just as names for things
No, symbols as data objects have many purposes. For example Lisp source code uses many symbols. But it can also appear in all sorts of data.
CL-USER 6 > 'foo
FOO
CL-USER 7 > (type-of 'foo)
SYMBOL
CL-USER 8 > (symbol-name 'foo)
"FOO"
CL-USER 9 > (type-of (symbol-name 'foo))
SIMPLE-BASE-STRING
CL-USER 10 > (mapcar #'symbol-name '(a b c defun foo bar))
("A" "B" "C" "DEFUN" "FOO" "BAR")
CL-USER 11 > (mapcar #'type-of *)
(SIMPLE-BASE-STRING SIMPLE-BASE-STRING SIMPLE-BASE-STRING SIMPLE-BASE-STRING SIMPLE-BASE-STRING SIMPLE-BASE-STRING)
Since you haven't accepted an answer, here is my take.
For most day-to-day programming symbols, and therefore SYMBOL-NAME,
aren't very useful. Mostly they are used for their
unique-ness. However they shine when you are modifying the compiler
with macros.
Here are 3 examples where SYMBOL-NAME is used:
Firstly, LOOP is the CL generic looping construct, it works via
placeholder symbols in a way that some claim is un-lispy, but it
remains very handy, especially if you are stepping things in parallel.
The following 3 forms are equivalent (at run-time):
(loop for i in list collect i)
(loop :for i :in list :collect i)
(loop #:for i #:in list #:collect i)
I, personally, prefer the third form because it makes it really
obvious where the LOOP magic is happening, and also avoids interning
symbols in any package (which is usually harmless, but not
always). That the third works at all requires the existence of
SYMBOL-NAME
Secondly, I don't make much use of CLOS but classes are undeniably
useful. DEFCLASS tends to be too verbose for what I want to do though,
so I often employ a macro that uses implied symbols. So:
(defbean peer ()
(id)
(next
beats))
Becomes:
(defclass peer nil
((id :initarg :id :reader peer-id)
(next :initarg :next :accessor peer-next)
(beats :initarg :beats :accessor peer-beats)))
Saving much typing. Notice how the slot name is converted to a keyword
for the initargs, and how reader and accessor names are created.
Some don't like this sort of macro, and I can see how it might be
problematic if you have a large team with everyone doing this all over
the shop (though M-. and C-c ret are always available), but for
small teams I think this is one of the best reasons to use lisp,
customising it to how you actually want to use it.
Thirdly, my sqlite helper library uses SYMBOL-NAME to generate SQL
statements (along with some more implied symbols) for even more
code-saving:
(defsqlite-table artists
(id :auto-key)
(artist-name :t)
(sort-artist-name :t :n))
Becomes something pretty huge:
(progn
(defparameter +create-artists-sql+
"CREATE TABLE artists (
id INTEGER PRIMARY KEY NOT NULL,
artist_name TEXT NOT NULL,
sort_artist_name TEXT
)")
(defun create-artists-table (pjs-sqlite::db pjs-sqlite::recursive log)
###)
(eval-when (:load-toplevel)
###)
(defun insert-artists
(pjs-sqlite::db artist-name sort-artist-name &key (id nil id-p))
###)
(defun update-artists
(pjs-sqlite::db id
&key (artist-name nil artist-name-p)
(sort-artist-name nil sort-artist-name-p))
###)
(defun delete-artists (pjs-sqlite::db id)
(with-sqlite-statements (pjs-sqlite::db
(pjs-sqlite::stmt
"DELETE FROM artists WHERE id = ?"))
###)))
(I stripped out a lot of code that would be distracting, but it should
be clear how I mapped symbols to sql identifiers)
I hope this gives you some ideas on what sort of things SYMBOL-NAME
can be used for.

Let, flet, macrolet : is there a way to do a "class-let"?

I have a macro which defines a class under certain rules, pseudo-code :
(defvar *all-my-classes* nil)
(defmacro my-macro (param)
`(if ,param
(progn
(defclass class-A () ...)
(push class-A *all-my-classes*))
(progn
(defclass class-B () ...)
(push class-B *all-my-classes*))))
I want to test the behaviour of the macro. Let is a convenient tool to mock variables. If I have an instance of *all-my-classes* running, I just have to do :
(let ((*all-my-classes* my-new-value)) ; generally `nil` for the test
(my-macro false))
But I would like to conserve the correspondance between *all-my-classes* and the classes defined. Since I want to test all the cases, let us suppose class-A is defined in the current environment, and i want to test if running (my-macro false) correctly defines class-B.
Since it is just a test, I would like the test to assert that class-B is currently defined, and that class-A is undefined in the current local environment; then when the test is over, class-B is undefined in the global environment, and class-A is still defined (without any alteration).
This way would be the best for my use :
(let ((*all-my-classes* nil))
(class-let ((class-A nil) ; or a way to map to a pre-defined
(class-B nil)) ; empty class temporarily.
(my-macro false)
(and
;; assert that the class is added to the list
(eql (length *all-my-classes*) 1)
;; assert that class-A is not defined
(null (find-class 'class-A))
;; assert that class-B is defined
(find-class 'class-B))))
I've searched to see if I can undefine a class, but it seems to be complex and implementation-dependent. And I want to preserve the current environment.
Restarting LISP each time for each tests is too long, and I would prefer a solution without having to load-unload packages for each tests (I don't know if it could work and if the classes will be garbage-collected when unloading the package...).
Thank you for your answers.
I do not think so.
The mechanism of how classes are stored is completely implementation defined, they just need to conform to the MOP (at least as far as it is mandated by the standard). However, the MOP does not prescribe anything that would make the classes registry dynamic. In fact, types and class names are specified to be part of the global environment (CLHS ch. 3.1.1.1), so it would be difficult for a conforming implementation to get dynamic here.
As you wrote, there is also no specified way to get rid of a class once defined.
As a rationale, I think that without this it would be very difficult to provide the kind of optimized runtime that the existing implementations have. Class lookup needs to be fast.
Now, to get to the meta question: what are you trying to do? Usually, while code is data, you should not confuse program logic with the programmed logic. What you propose looks like it might be intended to have code represent data. I'd advise to think about a clean separation and orthogonal representation.

Unbound variable in Allegro

In example code in a book I'm reading, there's a line for a macro that provides shorthand for getting the global value of a symbol:
(defmacro sv (v) '(symbol-value `,v))
However, Allegro sees V as an unbound variable. I don't know how to change this macro to return the correct result, because I've never encountered a problem like this before. How would I get the global value of any symbol? Thanks for your help!
You need a backquote, not a single quote, in front of the whole s-exp:
(defmacro sv (v) `(symbol-value ,v))
(I know, it's hard to see: Just move the backquote in your original s-exp from in front of ,v and replace the single quote at the beginning of '(symbol-value ...)).
Backquote operates on expressions (lists), not individual atoms, per se. If what you typed was actually in the book, it's likely an erratum.
A slightly better version of sv:
(defmacro sv (v) `(symbol-value (quote ,v)))
or
(defmacro sv (v) `(symbol-value ',v))
In the last version, interchange the backquote and single quote in your original code. The penultimate version just makes it easier to read.
However, symbol-value only queries the current value bound to the variable. For example, this code evaluates to 'something-else:
(defparameter *wombat* 123)
(let ((*wombat* 'something-else)) (sv *wombat*))
The *wombat* in the let form is a lexical variable, whereas the *wombat* in the defparameter form is dynamic. The let form temporarily hides the visibility of the defparameter.

Common Lisp: What does #+nil?

The other day (perhaps yesterday) I was quite perplexed about this #+nil read-time conditional found in https://github.com/billstclair/defperson/blob/master/defperson.lisp#L289.
After some deep thinking I came to the conclusion that this is very lispy way of commenting out code. Can someone confirm this?
Perhaps my assumptions are completely wrong. Anyway, thanks in advance.
Yes, it is a lispy way of commenting code, but you shouldn't leave this out in production code.
A better alternative is #+(or).
It only takes one more character, it takes the same key presses if you use Emacs paredit or some other mode that automatically inserts the closing parenthesis, and it's not subject to the existence of the symbol :nil in *features*.
See CLHS 2.4.8.17 Sharpsign Plus
To conditionalize reading expressions from input, Common Lisp uses feature expressions.
In this case it has been used to comment out a form.
It's a part of the reader. #+ looks if the next item, usually as a keyword symbol with the same name, is a member of the list *features*. If yes, the then next item is read as normal, if not, it is skipped.. Usually :NIL is not a member of that list, so the item is skipped. Thus it hides the expression from Lisp. There might have been a Lisp implementation, where this would not work : NIL, New Implementation of Lisp. It might have had the symbol :NIL on the *features* list, to indicate the name of the implementation.
Features like NIL are by default read in the keyword package:
#+NIL -> looks for :NIL in cl:*features*
#+CL:NIL -> looks for CL:NIL in cl:*features*
Example
(let ((string1 "#+nil foo bar")) ; string to read from
(print (read-from-string string1)) ; read from the string
(let ((*features* (cons :nil *features*))) ; add :NIL to *features*
(print (read-from-string string1))) ; read from the string
(values)) ; return no values
It prints:
BAR
FOO
Note that Common Lisp has other ways to comment out forms:
; (sin 3) should we use that?
#| (sin 3) should we use that?
(cos 3) or this? |#

Resources