[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Difficult macro question: Doing custom `let'
From: |
Pascal Bourguignon |
Subject: |
Re: Difficult macro question: Doing custom `let' |
Date: |
18 Aug 2003 23:20:57 +0200 |
User-agent: |
Gnus/5.09 (Gnus v5.9.0) 21.3.50.pjb1.1 |
jari.aalto@poboxes.com (Jari Aalto+mail.emacs) writes:
> I'm trying to make a custom `let' macro. The basic idea is that
> the variables defined inside `let' should be user defined and
> the `let' form simply should set them to nil. Something like:
>
> (setq list '(a b c))
>
> Something, a macro, that turns that into:
>
> (let (a
> b
> b)
Are you aware that this is exactly the behavior of normal let, be it
form emacs lisp or from Common-Lisp?
(let (a b c) (insert (format "==> a=%s b=%s c=%s\n" a b c)))
==> a=nil b=nil c=nil
> I've experimented with this:
>
> (nconc
> (list 'let)
> (list
> (mapcar
> (function
> (lambda (x)
> (list x nil)))
> list)))
> --> (let ((a nil) (b nil) (c nil)))
>
> Now the problem is, How Do I make a macro that does exactly that above?
> The macro would be called inside function body:
> Now, how do I get there?
A macro is merely a function, only that it executes at compile time
instead of at run time. So:
(defmacro my-let (var-list &rest body)
(nconc
(list 'let)
(list
(mapcar
(function
(lambda (x)
(list x nil)))
var-list))
body))
(show (macroexpand '(my-let (a b c) (statement1) (statement2))))
==> (let ((a nil) (b nil) (c nil)) (statement1) (statement2))
Now, when you write macros (and sometimes in plain functions), you may
use with great benefit backquote/coma constructs. The backquote
introduce a "literal" construct, like the quote, only that inside it,
anything introduced by a coma is evaluated, and ,@ introduce the
elements of an evaluated list.
This allow you to write a result as a template with some values:
(defmacro my-let (var-list &rest body)
`(let ,(mapcar (lambda (x) (list x nil)) var-list)
,@body))
(show (macroexpand '(my-let (a b c) (statement1) (statement2))))
==> (let ((a nil) (b nil) (c nil)) (statement1) (statement2))
Note that it's (mapcar (lambda (x) (list x nil)) var-list) and the
symbol body that are evaluated. The mapcar returns a list that is
inserted as is, and the evaluation of body returns the list
((statement1) (statemet2)) of which the elements are inserted.
--
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------
Do not adjust your mind, there is a fault in reality.