Matt,

Doug wrote a very detailed e-mail that explains everything; I'd just
like to add a couple of minor points.

If it wasn't for the compiler, then the following would be equivalent:

MACRO: foo ( x -- ) bar ;
: foo ( x -- ) bar call ;

What the compiler does, then, is if it encounters a call to a macro
where all parameters listed in the macro's stack effect are constants,
then it runs 'bar' at compile time, and compiles the quotation that it
emits instead of an actual call to the macro word.

Doug gave two examples -- ndrop and firstn -- and while they
demonstrate macros pretty well they're somewhat advanced in the sense
that these macros are mostly intended to be used by other macros, in
the expansions that they generate.

A very simple macro to look at is 'cleave'. It's already in the core
library, but you can re-implement it for fun.

{ [ A ] [ B ] [ C ] [ D ] } cleave

is equivalent to

[ A ] keep [ B ] keep [ C ] keep D

So cleave generalizes bi and tri.

First, notice that

[ A ] keep [ B ] keep [ C ] keep D

is equivalent to

[ A ] keep [ B ] keep [ C ] keep [ D ] keep drop

Suppose you have the array

{ [ A ] [ B ] [ C ] [ D ] }

on the stack. You can map over it and add keeps to each quotation,

{ [ A ] [ B ] [ C ] [ D ] } [ '[ _ keep ] ] map

And you get

{ [ [ A ] keep ] [ [ B ] keep ] [ [ C ] keep  ] [ [ D ] keep ] }

Now you can join them

[ ] join

and get

[ [ A ] keep [ B ] keep [ C ] keep [ D ] keep ]

Finally, add a drop,

[ drop ] append

So if you put this in a macro,

MACRO: cleave ( quots -- ) [ '[ _ keep ] ] map [ ] join [ drop ] append ;

Then whenever you write something like

{ [ red>> ] [ green>> ] [ blue>> ] [ alpha>> ] } cleave

The compiler will notice that the array of quotations is a literal,
and call the macro body on it, and slice the result into the compiled
code instead of a call to 'cleave'. 'keep' is not a macro, but rather
an inline word which calls a few other inline words and primitives; in
the end, after all optimizations are applied, the 'cleave' form is
compiled into reasonably efficient code where all stack manipulation
is done with inline assembly.

Slava

On Sun, Feb 15, 2009 at 12:06 AM, Matt Gushee <m...@gushee.net> wrote:
> Hi, all--
>
> Okay, so I am trying to understand how macros work in Factor. I wrote my
> first macro last night, which looks like this:
>
>   MACRO: print-with-suffix ( str -- ) append print ;
>
> Then I can define a word in terms of the macro:
>
>   : print-with-yeah ( str -- ) " yeah!" print-with-suffix ;
>
> But then if I try to use the word:
>
>   "Oh" print-with-yeah
>
> ... it prints "Oh yeah!" as expected, but also throws a Data Stack
> Underflow error.
>
> What am I doing wrong?
>
> Also, I would like to know the definition of a static stack effect--and
> how to know if a word's stack effect is static or not. Can anyone explain?
>
> Thanks in advance for your help!
>
> --
> Matt Gushee
> : Bantam - lightweight file manager : matt.gushee.net/software/bantam/ :
> : RASCL's A Simple Configuration Language :     matt.gushee.net/rascl/ :
>
> ------------------------------------------------------------------------------
> Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
> -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
> -Strategies to boost innovation and cut costs with open source participation
> -Receive a $600 discount off the registration fee with the source code: SFAD
> http://p.sf.net/sfu/XcvMzF8H
> _______________________________________________
> Factor-talk mailing list
> Factor-talk@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/factor-talk
>

------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Factor-talk mailing list
Factor-talk@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/factor-talk

Reply via email to