[racket] Macro defining functions question
This one leaves me scratching my head. Why doesn’t this work? When you run the macro the functions aren’t defined outside of the extent of the begin.
(define-syntax (foo stx)
(syntax-case stx ()
[(foo)
#'(begin
(define (bar x) x)
(define (baz x) x))]))
After inning the macro (bar 3) produces an bar undefined error.
On the other hand, this works:
(define-syntax (defstruct-lite stx)
(syntax-case stx ()
[(defstruct-lite name field ...)
(let ([make-id
(lambda (template . ids)
(let ([str (apply format template (map syntax->datum ids))])
(datum->syntax stx (string->symbol str))))])
(with-syntax ([make-name (make-id "make-~a" #'name)]
[name? (make-id "~a?" #'name)]
[(arg ...) (generate-temporaries #'(field ...))]
[(name-field ...)
(map (lambda (f) (make-id "~a-~a" #'name f))
(syntax->list #'(field ...)))])
#'(begin
(define (make-name arg ...) (list 'name (cons 'field arg) ...))
(define (name? x) (and (pair? x) (eq? 'name (car x))))
(define (name-field x)
(and (name? x) (cdr (assq 'field (cdr x)))))
...)))]))
In the 2nd example, once you run the macro you can then use the make- functions to define points.