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.
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? |#
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*
.