Hi Matt,

You don't need a macro to do what you're doing:

: print-with-suffix ( str -- ) append print ;

is correct as is.  Macros are for expanding code at compile-time.  In  
the UI, do "macros" about and read the docs. Some good examples of  
macros are in basis/generalizations and basis/combinators/smart.

For example, ndrop:

MACRO: ndrop ( n -- )
     [ drop ] n*quot ;

This has to be a macro because we want a static stack effect at  
compile-time.

10 20 30 40 50 60 6 ndrop

If we did this at runtime, the ndrop word could have any arbitrary  
stack effect, in this case, something like ( a b c d e f -- )

At compile-time, however, it expands into:

drop drop drop drop drop drop

which is well-known to drop six things.  Thus, the compiler can  
optimize it and there is a static stack effect.  If there is no  
constant passed to ndrop, for example

: dumb-nndrop ( n -- )
     ndrop ; inline

then Factor can still run this code, but it won't be compiled with the  
optimizing compiler because the stack effect is not known at runtime.

Another example of a non-static stack effect, which leaves things on  
the stack:

[ ] each

{ 1 2 3 } [ ] each ->
1
2
3


{ 1 2 3 4 5 } [ ] each ->
1
2
3
4
5

If your word is like this:

: seq>stack ( seq -- ... )
     [ ] each ;

then it can't compile, as shown above, since the output leaves n items  
on the stack, where n is the length of the sequence and unknown.

However, we can write a macro:

MACRO: firstn ( n -- )
     dup zero? [ drop [ drop ] ] [
         [ [ '[ [ _ ] dip nth-unsafe ] ] map ]
         [ 1- '[ [ _ ] dip bounds-check 2drop ] ]
         bi prefix '[ _ cleave ]
     ] if ;

This takes a sequence literal (like { 1 2 3 4 } ) and expands the code  
to grab n things at compile-time, in this case something like:

  { [ 0 swap nth ] [ 1 swap nth ] [ 2 swap nth ] [ 3 swap nth ] } cleave

So the compiler can optimize it and all is well, but only if you pass  
a literal at compile-time.

I hope my examples made sense -- welcome to the community!

Doug



On Feb 15, 2009, at 12:06 AM, Matt Gushee 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