modified expand-let and other macros

Started by jsmall, September 25, 2004, 07:40:29 PM

Previous topic - Next topic

jsmall

I'm hoping something is gained execution wise over

the previous two definitions of expand-let. This is

Lutz's version slightly edited.



  (define-macro (expand-let )

    (eval

      (cons 'let

        (cons (rest (args))

          (list (cons 'expand

            (cons (first (args))

              (map (fn (arg) (apply quote (list (first arg))))

                (rest (args))))))))))



  > (expand-let '(x y z) (x 1) (y (+ 1 1)) (z 3))

  (1 2 3)



I've noticed that expand-let used within a define-macro

is not a good idea if you intend to use (args) within the let

part.  The problem is that it is lazily evalued within the expand-let

macro itself and thus pulls the wrong arguments.



For example consider a macro "" as a replacement for

lambda or fn.



    ;; wrong!!!



   (define-macro ( )

       (expand-let (lambda fargs body)

         (fargs (first (args)))

         (body (cons 'begin (rest (args))))))





    ;; correct



  (define-macro ( )

    (let ((fargs (first (args)))

          (body (cons 'begin (rest (args)))))

      (expand (lambda fargs body) 'fargs 'body)))



This also shows how "expand" is used with define-macro

together to constitute a macro expansion facility.

The define-macro by itself is just a lambda expression

with lazily evaluated arguments.  I was hoping that

expand-let would make a more convenient synthesis of

a quasiquote/unquote mechanism.  (I'm working on

implementing the quasiquote macro which will call

qq-eval and qq-eval-@ functions to synthesize unquote

and ,@ constructs.)



Perhaps the macro above is mainly of academic

interest but  I never the less find an abbreviation for

"define" convenient and semantically pleasing. (Any

comments?)



 (define-macro (: _var-or-fn _value)

  (if (list? _var-or-fn)

      (let ((_fn-name (first _var-or-fn))

            (_fargs (rest _var-or-fn))

            (_body (cons 'begin (rest (args)))))

        (set _fn-name (expand (lambda _fargs _body)

                        '_fargs '_body)))

      (set _var-or-fn (eval _value))))



  (: rows '((a11 a12 a13)(a21 a22 a33)(a31 a32 a33)))

  (: (id x) x)



  > rows

  ((a11 a12 a13)(a21 a22 a33)(a31 a32 a33))



  >  (map id '(1 2 3))

  (1 2 3)

 

But I guess convenience should be of form and not

just syntactical sugar in order to warrant the

overhead of calling a macro.



(More macros are coming.)