From: ·······@gmail.com
Subject: macroexpand why
Date: 
Message-ID: <1187134220.492225.185630@q75g2000hsh.googlegroups.com>
Hi!

The first macroexpand works:
(macroexpand-1 '(testing (+ 1 1) 2 (+ 1 2) 4))
> (PROGN (TEST-FUNCTION (+ 1 1) 2) (TESTING (+ 1 2) 4))
> T

but the second one is nil:
(macroexpand-1 '(PROGN (TEST-FUNCTION (+ 1 1) 2) (TESTING (+ 1 2) 4)))
> (PROGN (TEST-FUNCTION (+ 1 1) 2) (TESTING (+ 1 2) 4))
> NIL

Why doesn't the second work?
I'm a newbie, so the chance that I don't know sg fundamental(?)
Have sbcl 1.08.

Very thx.


;; macros for testing
(defmacro test-function (func valid)
 (let ((g (gensym)))
   `(print (let ((,g ,func))
     (if (equalp ,g ,valid)
         (format t "valid.. ~A~%" ',func)
         (format t "FAIL...  ~A : ~A  instead of  ~A~%)" ',func ,g
',valid ))))))

(defmacro testing (func valid &rest body)
 (if body
     `(progn
       (test-function ,func ,valid)
       (testing ,@body))
     `(test-function ,func ,valid)))

I would use it as here:
(testing (+ 1 1) 2
   (+ 2 2) 4
   (list 1 2) '(1 2))

From: Geoff Wozniak
Subject: Re: macroexpand why
Date: 
Message-ID: <1187143098.077114.187880@x35g2000prf.googlegroups.com>
On Aug 14, 7:30 pm, ········@gmail.com" <·······@gmail.com> wrote:
> Why doesn't the second work?
> I'm a newbie, so the chance that I don't know sg fundamental(?)
> Have sbcl 1.08.
>

As others have mentioned, you need a code walker to see the full
expansion of subforms.

In Slime, this is done with macroexpand-all (bound to C-c RET by
default, although you may have to position point to just inside the
end of the form).

If you aren't using Slime, you can call some no-so-well-known
functions.  In SBCL, this is SB-WALKER:WALK-FORM, but in order for it
to work the way you want, you must set/bind SB-WALKER:*WALK-FORM-
EXPAND-MACROS-P* to T.

  (let ((sb-walker:*walk-form-expand-macros-p* t))
    (sb-walker:walk-form '(defun foo (x) (+ x x))))

In Allegro CL, it's EXCL::WALK.

In LispWorks Personal 5.0.1, look at the Expression > Walk and
Expression > Macroexpand menu options (be sure to place the cursor at
the beginning of the form.
From: Rob Warnock
Subject: Re: macroexpand why
Date: 
Message-ID: <VN6dnbMj2rSY-V_bnZ2dnUVZ_gKdnZ2d@speakeasy.net>
Geoff Wozniak  <·············@gmail.com> wrote:
+---------------
| If you aren't using Slime, you can call some no-so-well-known
| functions.  In SBCL, this is SB-WALKER:WALK-FORM, but in order for it
| to work the way you want, you must set/bind SB-WALKER:*WALK-FORM-
| EXPAND-MACROS-P* to T.
| 
|   (let ((sb-walker:*walk-form-expand-macros-p* t))
|     (sb-walker:walk-form '(defun foo (x) (+ x x))))
| 
| In Allegro CL, it's EXCL::WALK.
| 
| In LispWorks Personal 5.0.1, look at the Expression > Walk and
| Expression > Macroexpand menu options (be sure to place the cursor at
| the beginning of the form.
+---------------

In CMUCL, the parent of SBCL, it's WALKER:MACROEXPAND-ALL.


-Rob

p.s. But they're not really all that different, since
WALKER:MACROEXPAND-ALL is defined as follows:  ;-}  ;-}

    (defun walker:macroexpand-all (form &optional environment)
      (let ((walker:walk-form-expand-macros-p t))
	  (walker:walk-form form environment)))

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Tobias C. Rittweiler
Subject: Re: macroexpand why
Date: 
Message-ID: <87vebhxok6.fsf@freebits.de>
Geoff Wozniak <·············@gmail.com> writes:

> In Slime, this is done with macroexpand-all (bound to C-c RET by
> default, although you may have to position point to just inside the
> end of the form).

Small typo: macroexpand-all is bound to `C-c M-m'. 

(`C-c C-m' is bound to macroexpand-1 and is usually prefered to its alias
`C-c RET'.)

Also note that in Slime's Macroexpansion Buffer, it's possible to use
`C-c C-m' recursively by hand to descend into macros that are results
from previous macro expansions---and it's possible to "go back" by undo,
e.g. `C-_') Comes in quite handy!

Last but not least, you can call SWANK::MACROEXPAND-ALL directly at the
REPL which is implemented on almost all Lisp implementations.

  -T.
From: Mate Toth
Subject: Re: macroexpand why
Date: 
Message-ID: <1187169956.245843.251240@k79g2000hse.googlegroups.com>
Thank you Rainer, Pascal, Geoff, Rob and Tobias!

It's amazing. I just wake up and everything is here .)

I use slime.


Thx again!
From: Geoff Wozniak
Subject: Re: macroexpand why
Date: 
Message-ID: <1187143784.947645.32030@g12g2000prg.googlegroups.com>
If this a repeat (or close to it), I apologize.  It would seem Google
Groups ate my post.

On Aug 14, 7:30 pm, ········@gmail.com" <·······@gmail.com> wrote:
> Why doesn't the second work?
> I'm a newbie, so the chance that I don't know sg fundamental(?)
> Have sbcl 1.08.
>

As Ranier and Pascal have mentioned, you need a code walker to expand
the subforms.  You can do this in clisp (as Pascal mentioned) and you
can do it in other Lisps as well.

SBCL: Use SB-WALKER:WALK-FORM with SB-WALKER:*WALK-FORM-EXPAND-MACROS-
P* bound to T.

Example:

CL-USER>  (let ((sb-walker:*walk-form-expand-macros-p* t))
                    (sb-walker:walk-form '(progn (push x my-list)
(setf y 6))))
(PROGN
 (LET* ((#:G1989 X) (#:G1988 (CONS #:G1989 MY-LIST)))
   (SETQ MY-LIST #:G1988))
 (SETQ Y 6))

Allegro: See EXCL::WALK.

LispWorks: See the Expression menu (Walk and Macroexpand, depending on
what you want).

In Slime, you can call macroexpand-all, which is bound to C-c RET by
default.  (You may have to put point just inside the end of the form
for it to work.)
From: Rainer Joswig
Subject: Re: macroexpand why
Date: 
Message-ID: <joswig-4016B3.02302515082007@news-europe.giganews.com>
In article <························@q75g2000hsh.googlegroups.com>,
 ········@gmail.com" <·······@gmail.com> wrote:

> Hi!
> 
> The first macroexpand works:
> (macroexpand-1 '(testing (+ 1 1) 2 (+ 1 2) 4))
> > (PROGN (TEST-FUNCTION (+ 1 1) 2) (TESTING (+ 1 2) 4))
> > T
> 
> but the second one is nil:
> (macroexpand-1 '(PROGN (TEST-FUNCTION (+ 1 1) 2) (TESTING (+ 1 2) 4)))
> > (PROGN (TEST-FUNCTION (+ 1 1) 2) (TESTING (+ 1 2) 4))
> > NIL
> 

PROGN is no macro.

MACROEXPAND-1 usually does not expand subforms.
You would need a 'code walker' to expand a
form and its subforms...

> Why doesn't the second work?
> I'm a newbie, so the chance that I don't know sg fundamental(?)
> Have sbcl 1.08.
> 
> Very thx.
> 
> 
> ;; macros for testing
> (defmacro test-function (func valid)
>  (let ((g (gensym)))
>    `(print (let ((,g ,func))
>      (if (equalp ,g ,valid)
>          (format t "valid.. ~A~%" ',func)
>          (format t "FAIL...  ~A : ~A  instead of  ~A~%)" ',func ,g
> ',valid ))))))
> 
> (defmacro testing (func valid &rest body)
>  (if body
>      `(progn
>        (test-function ,func ,valid)
>        (testing ,@body))
>      `(test-function ,func ,valid)))
> 
> I would use it as here:
> (testing (+ 1 1) 2
>    (+ 2 2) 4
>    (list 1 2) '(1 2))
From: Pascal Bourguignon
Subject: Re: macroexpand why
Date: 
Message-ID: <87eji561p3.fsf@thalassa.informatimago.com>
········@gmail.com" <·······@gmail.com> writes:

> Hi!
>
> The first macroexpand works:
> (macroexpand-1 '(testing (+ 1 1) 2 (+ 1 2) 4))
>> (PROGN (TEST-FUNCTION (+ 1 1) 2) (TESTING (+ 1 2) 4))
>> T
>
> but the second one is nil:
> (macroexpand-1 '(PROGN (TEST-FUNCTION (+ 1 1) 2) (TESTING (+ 1 2) 4)))
>> (PROGN (TEST-FUNCTION (+ 1 1) 2) (TESTING (+ 1 2) 4))
>> NIL
>
> Why doesn't the second work?

As indicated by Rainer, you need a code walker because PROGN is a
special operator.


> I'm a newbie, so the chance that I don't know sg fundamental(?)
> Have sbcl 1.08.

If you had clisp, you could use EXT:EXPAND-FORM

C/USER[91]> (ext:expand-form '(PROGN (TEST-FUNCTION (+ 1 1) 2) (TESTING (+ 1 2) 4)))
(PROGN (PRINT (LET ((#1=#:G10565 #2=(+ 1 1)))
                (IF (EQUALP #1# 2)
                  (FORMAT T #3="valid.. ~A~%" '#2#)
                  (FORMAT T #4="FAIL...  ~A : ~A  instead of  ~A~%)" '#2# #1# '2))))
 (PRINT (LET ((#5=#:G10566 #6=(+ 1 2)))
            (IF (EQUALP #5# 4)
                (FORMAT T #3# '#6#)
                (FORMAT T #4# '#6# #5# '4))))) ;
T


Note that one advantage of Common Lisp over ruby, python, perl, etc,
is that it's a language specified by a standard, and that has several
implementations.   Don't be afraid to use clisp (or any other
implementation) to help debugging your sbcl programs...

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.