[plt-scheme] Recognizing datums in macros

From: Danny Yoo (dyoo at hkn.eecs.berkeley.edu)
Date: Tue Feb 7 19:19:22 EST 2006

>    (define-constant-setter null!            '())
>    (define-constant-setter zero!            0)
>    (define-constant-setter one!             1)
>    (define-constant-setter infinite!        +inf.0)
>    (define-constant-setter minus-infinite!  -inf.0)
>    (define-constant-setter empty-vector!    #())
> With the intended usage:
>    > (define foo 42)
>    > (null! foo)
>    ()
>    > foo
>    ()
> Is there a way to signal an error if datum is not a datum?

Hi Jens,

I'm still a macro newbie still, so this might be totally off.  *grin* But
would something like this be ok?

(module test-stx-datum mzscheme
  (provide stx-datum-or-quoted?)

  ;; stx-datum-or-quoted?: stx -> boolean
  ;; Returns true if the stx looks like a datum or a quoted thing
  (define (stx-datum-or-quoted? stx)
    (let ((expanded-head
           (car (syntax-object->datum (expand stx)))))
      (or (eq? expanded-head 'quote)
          (eq? expanded-head '#%datum)))))

For example, if I run this:

(module test mzscheme
  (require-for-syntax test-stx-datum)
  (define-syntax (s stx)
    (syntax-case stx ()
      ((_ thing)
         (display (syntax-object->datum (syntax thing)))
         (display "\t")
         (display  (stx-datum-or-quoted? (syntax thing)))
         (syntax/loc stx
    (s '())
    (s 0)
    (s (lambda (x) x))
    (s #())
    (s +inf.0)))

Then I get the following output:

(quote ())	#t
0	#t
(lambda (x) x)	#f
#()	#t
+inf.0	#t

which sort of looks right, but then again, I might be missing something.

Best of wishes!

Posted on the users mailing list.