7
votes

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.

2

2 Answers

6
votes

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

5
votes

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