modified expand-let and other macros

Pondering the philosophy behind the language
Locked
jsmall
Posts: 26
Joined: Mon Sep 20, 2004 1:44 am

modified expand-let and other macros

Post by 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.)

Locked