[racket] Completely disallow numbers, quoted and all

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed Jun 4 01:11:46 EDT 2014

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))


Posted on the users mailing list.