chicken-users
[Top][All Lists]
Advanced

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

Re: [Chicken-users] need help with hygienic macros


From: Marco Maggi
Subject: Re: [Chicken-users] need help with hygienic macros
Date: Sun, 12 May 2013 18:17:16 +0200

Jörg F. Wittenberger wrote:
> not exactly chicken  related; but I hope  someone here can
> help me.

I  am  not  a  Chicken   user,  neither  I  have  a  general
solution. ;-)

> I'm  trying   to  replace  an  unhygienic   macro  with  a
> syntax-rules based version.  Just I can't.

If I  understand correctly the  problem and the way  you are
trying  to  solve  it:   your  solution  pattern  is  highly
unhygienic and problematic because nesting macro definitions
into  macro  definitions   somehow  "flattens"  the  lexical
context of  the function's body, loosing  informations about
the original context.

  This is what  I understand: you would like  to execute the
code:

   (define (red a b r s)
     (list a b r s))

   (define (blue c d r s)
     (list c d r s))

   (list (red 1 2 3 4)
         (blue 5 6 7 8))

but you only want to write:

   (define-with-more (red a b)
     (list a b r s))

   (define-with-more (blue c d)
     (list c d r s))

   (list (red 1 2 3 4)
         (blue 5 6 7 8))

this would be gokuraku for your code.

  It  is  easy  to   envision  a  DEFINE  replacement  which
introduces arguments in the formals list:

   (define-syntax define-with-more
     (syntax-rules ()
       ((_ (?name ?formal ...)
           ?body0 ?body ...)
        (define (?name ?formal ... r s)
          ?body0 ?body ...))))

but how to access the  additional formals from the body?  In
other  words:  how  does  one introduce  identifiers  in  an
expression in lexical context A by expanding a macro defined
in lexical context B?

  With an expander providing the features of SYNTAX-CASE and
friends, that would be easy:

   (define-syntax define-with-more
     (lambda (stx)
       (syntax-case stx ()
         ((_ (?name ?formal ...)
             ?body0 ?body ...)
          (identifier? #'?name)
          (with-syntax
              ;;This macro  is defined in lexical  context B
              ;;and  we introduce  these identifiers  in the
              ;;output form as if they belong to the lexical
              ;;context A surrounding the macro use.
              ((R-ID (datum->syntax #'?name 'r))
               (S-ID (datum->syntax #'?name 's)))
            #'(define (?name ?formal ... R-ID S-ID)
                ?body0 ?body ...))))))

  I  am unable  to come  up with  a solution  involving only
SYNTAX-RULES for the  general case; but if  it is acceptable
to split the expressions using  the formals you type by hand
from the expression using the introduced formals:

  (define-syntax define-with-more
    (syntax-rules ()
      ((_ (?name ?formal ...)
          ?body0 ?body ...)
       (define (?name ?formal ... r s)
         (helper (begin ?body0 ?body ...)
                 r s)))))

  (define-syntax helper
    (syntax-rules ()
      ((_ ?body ?r ?s)
       (append ?body (list ?r ?s)))))

  (define-with-more (red a b)
    (list a b))

  (define-with-more (blue c d)
    (list c d))

  (pretty-print (list (red 1 2 3 4)
                      (blue 5 6 7 8))

not quite gokuraku in the code... but sometimes useful.  For
example this macro definition pattern is used effectively in
the Scheme reader of Ikarus/Vicare.

HTH
-- 
Marco Maggi



reply via email to

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