Hi!

The explanations are on

https://okmij.org/ftp/Scheme/macros.html#macro-symbol-p

Maybe this version will be easier to understand (we don't really
need continuation-passing style here):

(define-syntax symbol??
  (syntax-rules ()
    ((symbol?? maybe-symbol)
     (let-syntax
         ((test
           (syntax-rules ()
             ((test maybe-symbol) #t)
             ((test _) #f))))
       (test abracadabra)))))

(symbol?? foo) ⇒ #t
(symbol?? (a . b)) ⇒ #f
(symbol?? 5) ⇒ #f
(symbol?? "a") ⇒ #f
(symbol?? #(1 a)) ⇒ #f


Basically: the macro call

(symbol?? <foobar>)

expands to a macro definition of test as

(syntax-rules ()
  ((test <foobar>) #t)
  ((test _) #f))

and a call (test abracadabra). Now, observe that if <foobar>
is a symbol, then it's a catch-all pattern when inserted
in the syntax-rules definition of `test`, so it will match
abracadabra (because it matches anything). On the other hand,
if it's not a symbol, then it won't match abracadabra, by case
analysis: if it's a number it will only match that number; booleans,
strings and characters likewise; if it's a pair it can only match
pairs; if it's a vector it can only match vectors; etc.

I'm not exactly sure why Oleg Kiselyov included special cases for a pair
and a vector, but my guess is that not all Scheme implementations
support vectors in syntax-rules patterns (and the pair check is
necessary because the car or cdr could contain a vector). The Scheme
standards certainly have their opinion on this, and I knew that
stuff by heart at some point (when I implemented a syntax-rules/syntax-case
expander for a university project), but I don't remember, and it's
too late for scouring the standards...

Best,
Jean

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to