[plt-scheme] Recognizing datums in macros
> (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)
(begin
(display (syntax-object->datum (syntax thing)))
(display "\t")
(display (stx-datum-or-quoted? (syntax thing)))
(newline)
(syntax/loc stx
'ok)))))
(begin
(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!