Hello there!

I'm really glad you're picking up Racket and enjoying it!

I've been through the same paths and struggles before, so thank you very 
much for posting that piece of
experience here :)

For your information, here is a syntax-parse version of your macro, which I 
find simpler to write and understand:
(it's basically syntactic sugar over syntax-case, but it's really useful!)

    #lang racket/base

    (provide
      define-enum)

    (require
      (for-syntax
        racket/base
        racket/syntax
        syntax/parse))

    (define-syntax (define-enum stx)
      (syntax-parse stx
        [(_ name (element value) ...)
         #:with (name-element? ...)
                (datum->syntax
                  #'(element ...)
                  (map (lambda (elem)
                         (format-id elem "~a-~a?" #'name elem))
                       (syntax->list #'(element ...))))
         #'(begin
             (define element value) ...
             (define (name-element? v)
               (eq? element v)) ...)]))

    (module+ test
      (require rackunit)
      
      (define-enum unit
        (dry #\d)
        (empty #\.)
        (rock #\#)
        (water #\~))
      
      (check-true (unit-dry? #\d))
      (check-false (unit-empty? #\#))
      (check-false (unit-rock? #\~))
      (check-true (unit-water? #\~)))

To remove that ugly map, which requires transforming syntaxes to list then 
back to syntaxes, you can use a syntax-class:

    (begin-for-syntax
      (define-syntax-class (element-exp unit)
        (pattern (element value)
          #:with pred-name (format-id #'element "~a-~a?" unit #'element)
          #:with variable #'(define element value)
          #:with predicate #'(define (pred-name v) (eq? element v)))))

    (define-syntax (define-enum stx)
      (syntax-parse stx
        [(_ name (~var e (element-exp #'name)) ...)
         #'(begin
             e.variable ...
             e.predicate ...)]))

It's a bit more complicated at first, but it becomes really powerful once 
you understand how syntax-parse and syntax-classes work.

(the tricky part here is that I'm using a syntax-class that takes the unit 
name as an argument, which is not so common)

Have fun ;)


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to