chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] hart and syntax-case won't play nice. :(


From: Graham Fawcett
Subject: Re: [Chicken-users] hart and syntax-case won't play nice. :(
Date: Sat, 15 Mar 2008 15:24:58 -0400

On Sat, Mar 15, 2008 at 2:49 PM, Robin Lee Powell
<address@hidden> wrote:
>
> On Sat, Mar 15, 2008 at 02:48:01PM -0400, Graham Fawcett wrote:
>  > On Sat, Mar 15, 2008 at 1:26 PM, Kon Lovett <address@hidden>
>  > wrote:
>  > > hart uses low-level macros only.
>  >
>  > Is there a way I can alter hart so that it will play better with
>  > code that uses higher-level macro systems? I'd rather not rewrite
>  > it in syntax-case (though it's really not very much macro code;
>  > perhaps a syntax-case version wouldn't be that hard).
>  >
>  > I confess to being an unhygienic, low-level macro user, and have
>  > to scratch my head whenever I encounter syntax-case code.
>
>  What about define-syntax, rather than syntax-case?  That's the only
>  thing I'm importing syntax-case for anyways.  (Yes, I'm friends with
>  John Cowan :)

Lucky you! :-) I guessed, from the Lojban .sigs.

The main macro in Hart is ridiculously small. Hart-support (the
non-macro code) does all the work:

(define-macro (hart . forms)
  `(noop ,(apply hart-parse forms)))

That should be trivial to translate into any macro system.

The trickiest macro is hart-for, which provides some polymorphism
(iteration over both lists and vectors) and destructuring for the
(for: ...) construct.

(define-macro (hart-for args . body)
  (let ((real-iter (gensym 'iter))
        (foreach (gensym 'foreach))
        (lst (gensym 'list)))
    (match-let (((iter the-lst) args))
               `(let* ((,lst ,the-lst)
                       (,foreach (if (list? ,lst)
                                     for-each
                                     hart-vector-for-each*)))
                  (,foreach (lambda (,real-iter)
                              (match-let ((,iter ,real-iter))
                                         ,@body))
                            ,lst)))))

That too could be simplified. There's no real need to choose for-each
vs. hart-vector-for-each* at the macro-level, since really the
decision between the two is made at runtime. So we could add a generic
hart-for-each* support procedure that takes either:

(define (hart-for-each* proc lst)
  (cond ((list? lst)
         (for-each proc lst))
        ((vector? lst)
         (hart-vector-for-each* proc lst))
        (#t (error "not a list or vector"))))

and simplify the macro down to this (totally untested):

(define-macro (hart-for args . body)
  (let ((real-iter (gensym 'iter))
        (foreach (gensym 'foreach))
        (lst (gensym 'list)))
    (match-let (((iter the-lst) args))
      `(hart-for-each* (lambda (,real-iter)
                          (match-let ((,iter ,real-iter))
                            ,@body))
                        ,lst))))

which *might* be easier to write in higher-level macro systems. It
might be hard to do the variable capture though.

Ignoring (for: ...) for the moment, just (use hart) and then use
(define-syntax) to define your own high-level version of:

(define-macro (hart . forms)
  `(noop ,(apply hart-parse forms)))

and you should be good to go.

Sorry, I don't have more time for a tested solution today...

Graham




reply via email to

[Prev in Thread] Current Thread [Next in Thread]