[racket] Completely disallow numbers, quoted and all
At Wed, 4 Jun 2014 00:38:11 -0400, Daniel Brady wrote:
> So I'm playing around with the DrRacket reader, and I'm decided to see if I
> could disallow certain types of literal data. I figured I'd start with
> numbers, and maybe see if I can come up with a tiny numberless language
> like pure lambda calculus.
>
> This is a simple module that I came up with:
>
> (module numberless racket
> (provide (rename-out [no-nums #%datum]))
>
> ;; Raises a syntax error when a number literal is encountered.
> ;; Note that the datum must be quoted to prevent infinite expansion.
> (define-syntax (no-nums stx)
> (syntax-case stx ()
> ((_ . datum) #'(if (number? (quote datum)) (raise-syntax-error 'Sorry
> "number literals disallowed" (quote datum)) (quote datum))))))
>
> I don't know if that's the right way to go about it, but it gets most of
> the job done.
That's the right idea, but I think you want to check for numbers at
expansion time instead of generating code to check at run time, which
means moving the test out of the #' like this:
(define-syntax (no-nums stx)
(syntax-case stx ()
((_ . datum)
(if (number? (syntax-e #'datum))
(raise-syntax-error 'Sorry
"number literals disallowed"
#'datum)
#'(quote datum)))))
Some compound values are can be sent to `datum`, such as vectors like
#(1 2 3)
If you want to disallow numbers in things like vectors, you'll need to
traverse `datum` looking for numbers. See the documentation for
`syntax-e` for the description of values that you'd have to traverse.
> But it doesn't catch quoted number literals:
>
> > '3
> 3
>
> I don't know what part the reader deals with quoted values.
The reader turns
'3
into
(quote 3)
So, you don't want to change the reader, but instead define a new
`quote` macro that expands to `no-nums`:
(provide (rename-out [no-nums-quote quote]))
(define-syntax-rule (no-nums-quote v)
(no-nums . v))