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
> [email protected]
> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/factor-talk