[racket] anamorphic macros
You're better off defining head and tail as syntax parameters and defining your macro with the more hygienic syntax-parameterize using rename transformers.
The then case:
(let ([h (car val)]
[t (cdr val)])
(syntax-parameterize
([head (make-rename-transformer #'h)]
[tail (make-rename-transformer #'t)])
yes))
-Ian
----- Original Message -----
From: Jon Zeppieri <zeppieri at gmail.com>
To: Peter Samarin <petrsamarin at gmail.com>
Cc: Racket Users <users at racket-lang.org>
Sent: Sun, 18 Jan 2015 20:04:58 -0500 (EST)
Subject: Re: [racket] anamorphic macros
Breaking hygiene with `syntax-case`:
(define-syntax (split stx)
(syntax-case stx ()
([split val yes no]
(let ([head-stx (datum->syntax stx 'head)]
[tail-stx (datum->syntax stx 'tail)])
#`(if (empty? val)
no
(let ([#,head-stx (car val)]
[#,tail-stx (cdr val)])
yes))))))
On Sun, Jan 18, 2015 at 7:49 PM, Peter Samarin <petrsamarin at gmail.com> wrote:
> Hi all,
>
> I was working through chapter 16 of "land of lisp" and there is (at that
> point) a buggy split macro defined like this:
>
> (defmacro split (val yes no)
> `(if ,val
> (let ((head (car ,val))
> (tail (cdr ,val)))
> ,yes)
> ,no))
>
> Here is my version of the equivalently buggy Racket counterpart:
>
> (define-syntax split
> (syntax-rules ()
> ([split val yes no]
> (eval
> '(if (empty? val)
> no
> (let ([head (car val)]
> [tail (cdr val)])
> yes))))))
>
> Calling the macro works as intended (ignoring the multiple evaluation of
> "val" in this buggy version):
>
> (split (list 1 2 3 4 5 6) tail #f)
> ;; => (2 3 4 5 6)
>
> Now to my question: is there a way to make head and tail visible without
> resorting to the eval-quote combination?
> In other words, is there a more Racket-like way to achieve the same?
>
> Cheers,
> Peter
>
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users
____________________
Racket Users list:
http://lists.racket-lang.org/users