2

I am currently reading the chapter on read-time macros from Paul Graham's "On Lisp" book.

The problem I am encountering is the following. When I run one of his examples:

(set-dispatch-macro-character #\# #\?
  #’(lambda (stream char1 char2)
    ‘#’(lambda (&rest ,(gensym))
       ,(read stream t nil t))))

I get the following error:

No dispatch function defined for #\’

Why is it happening? Could it be because I am running it at the REPL? What can one do to fix it?

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
MadPhysicist
  • 5,401
  • 11
  • 42
  • 107

1 Answers1

9

The PDF from which you are copying the code uses punctuation marks outside the range of basic ASCII characters you are supposed to use here:

CL-USER> (char-name #\’)
"RIGHT_SINGLE_QUOTATION_MARK"

The usual quote symbol should instead use the apostrophe character:

CL-USER> (char-name #\')
"APOSTROPHE"

The same goes for backquote:

CL-USER> (char-name #\‘)
"LEFT_SINGLE_QUOTATION_MARK"

You should be writing instead:

(set-dispatch-macro-character #\# #\?
                              #'(lambda (stream char1 char2)
                                `#'(lambda (&rest ,(gensym))
                                     ,(read stream t nil t))))

The #' is not necessary before lambda, since Common Lisp also defines a macro named lambda which expands into (function (lambda ...)).

You can test your new read macro as follows:

CL-USER> #?10
#<FUNCTION (LAMBDA (&REST #:G617)) {1001C541FB}>

CL-USER> (funcall *)
10

When using SBCL, I obtain warnings about unused variables. This happens because the code declares variables in anonymous functions but never uses them. This is not a serious problem, but generally speaking, it is better to declare which variables are ignored:

(set-dispatch-macro-character
 #\# #\?
 (lambda (stream &rest chars)
   (declare (ignore chars))
   (let ((rest (gensym)))
     `(lambda (&rest ,rest)
        (declare (ignore ,rest))
        ,(read stream t nil t)))))
coredump
  • 37,664
  • 5
  • 43
  • 77
  • Thanks! That did it. Could you tell me what your last comment relates to? `(With SBCL, I have a lot of warnings about unused variables, too)` – MadPhysicist Apr 05 '18 at 16:40