unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Difficult macro question: Doing custom `let'
@ 2003-08-18 17:43 Jari Aalto+mail.emacs
  2003-08-18 17:57 ` Barry Margolin
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Jari Aalto+mail.emacs @ 2003-08-18 17:43 UTC (permalink / raw)



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)

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:

    (defun my-test ()
      (my-let-transform list
         (message "It worked.")))

Which should be after macroexpand:

    (defun my-test ()
        (let (a
              b
              b)
          (message "It worked.")))

Now, how do I get there?

Jari

^ permalink raw reply	[flat|nested] 5+ messages in thread
* Re: Difficult macro question: Doing custom `let'
@ 2003-08-18 18:20 lawrence mitchell
  0 siblings, 0 replies; 5+ messages in thread
From: lawrence mitchell @ 2003-08-18 18:20 UTC (permalink / raw)


Jari Aalto+mail.emacs wrote:

[...] given list => '(a b c), get (let (a b c) ...)

> Now the problem is, How Do I make a macro that does exactly that above?
> The macro would be called inside function body:

>     (defun my-test ()
>       (my-let-transform list
>          (message "It worked.")))

> Which should be after macroexpand:

>     (defun my-test ()
>         (let (a
>               b
>               b)
>           (message "It worked.")))

If you do (require 'cl), you can try something like this:

(defmacro* my-transform-list ((&rest vars) &body body)
  ;; If VARS is a variable, assume we wanted its value.
  ;; otherwise, we just take it as a literal list.
  ;; This means that both (my-transform-list (a b) ...)
  ;; and (my-transform-list foo ...) work (assuming foo is boundp).
  (ignore-errors 
    (setq vars (symbol-value vars)))
  `(let ,vars
      ,@body))

(macroexpand '(my-transform-list (a b c) (message "It works.")))
  => (let (a b c)
       (message "It works."))

but also:
(setf list '(a b c))

(macroexpand '(my-transform-list list (message "It works.")))
  => (let (a b c)
       (message "It works."))

Note that there is no need to quote the list of variables if you
give them literally.

-- 
lawrence mitchell <wence@gmx.li>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2003-08-18 21:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-08-18 17:43 Difficult macro question: Doing custom `let' Jari Aalto+mail.emacs
2003-08-18 17:57 ` Barry Margolin
2003-08-18 18:00 ` Johan Bockgård
2003-08-18 21:20 ` Pascal Bourguignon
  -- strict thread matches above, loose matches on Subject: below --
2003-08-18 18:20 lawrence mitchell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).