Reputation: 15343
I'm playing with Factor trying to get a little understanding of concatenative programming. Writing a word to square a number is trivial:
: square ( n -- n ) dup * ;
But for the life of me I can't seem to figure out how to cube a number:
: cube ( n -- n ) * * ; ! Form a
Doesn't work because the inferred stack effect is ( x x x -- x )
Similarly
: cube ( n -- n ) dup * * ; ! Form b
also fails.
If I were to hard code a cube I would do something like this:
3 3 * 3 *
Which is why my naive guess would be form b.
As I say I'm just playing with Factor and would love to know what I'm missing here--but it's mostly for my curiosity.
Upvotes: 2
Views: 185
Reputation: 751
This might be interesting to you:
: double ( n -- n ) dup + ; ! add 2 times
: square ( n -- n ) dup * ; ! multiply 2 times
So what about 3 times?
: triple ( n -- n ) dup dup + + ; ! add 3 times
: cube ( n -- n ) dup dup * * ; ! multiply 3 times
(I wonder if there is a way to generalize the pattern [..a a a b b b..]
)
What about the next higher order operation: Tetration:
: tetrate2 ( n -- n ) dup ^ ; ! raise to power twice
: tetrate3 ( n -- n ) dup dup ^ ^ ; ! raise to power thrice
You could probably also generalize the other way, implementing hyper-operations like Knuth's up arrow.
It's not immediately apparent to me how one would go about doing that,
but Björn's answer seems to hint at it.
The actual source has a lot of abstraction layers optimizing for the different datatypes.
Clicking thru until it reaches (^fixnum)
gives something similar
Upvotes: 3
Reputation: 20400
There is a builtin word for that:
IN: scratchpad 3 3 ^ .
27
Or if you want to write the word yourself:
: pow ( x n -- y ) 1 - over '[ _ * ] times ;
IN: scratchpad 5 3 pow .
125
You could also formulate cube
using square
:
: cube ( n -- n' ) dup square * ;
IN: scratchpad 6 cube .
216
Upvotes: 3
Reputation: 15343
In case anyone else runs across this and wants to know how to do this:
: cube ( n -- n ) dup dup * * ;
The dup dup
will add the value to the top of the stack twice and then the * *
will multiply twice. I'd bet there's a less hacky way to do this but, as I say, in case anyone else is curious.
Upvotes: 3