From: Daniel Martin Date: 2006-07-28T05:30:59+09:00 Subject: Re: RLisp - Lisp naturally embedded in Ruby "Tomasz Wegrzanowski" writes: > So, how would such a macro look like ? Well, 1) This is ruby-talk, not comp.lang.lisp, and 2) I don't actually know lisp. But how hard can it be, right? .... (1.5 hours later) .... Okay, try this: (defun local-expander (bodylist) (cond ((null bodylist) '()) ((and (consp (car bodylist)) (eq (caar bodylist) 'local)) `((let ,(loop for x on (cdar bodylist) by #'cddr collect (list (car x) (cadr x))) ,@(local-expander (cdr bodylist))))) (t (cons (car bodylist) (local-expander (cdr bodylist)))))) (defmacro progn-with-local (&rest body) `(progn ,@(local-expander body))) (defmacro defun-with-local (name args &rest body) `(defun ,name ,args ,@(local-expander body))) Then, you can do: (defun-with-local pythag (x y) (local x2 (* x x)) (local y2 (* y y)) (local z2 (+ x2 y2)) (sqrt z2)) Actually, you could even shorten that slightly to: (defun-with-local pythag (x y) (local x2 (* x x) y2 (* y y)) (local z2 (+ x2 y2)) (sqrt z2)) But I think that hurts the readability. Note that you don't need to supply an initial value in the (local) bit. Also, a (local) declaration will shadow references that follow it, but not those that precede it. For example: * (defvar a 'top) A * a TOP * (progn-with-local (setf a 'before) (local a) (setf a 'after)) AFTER * a BEFORE