Consider printing the same message ten times:
: print-10 ( -- ) 10 [ "Hello, world." print ] times ;
if we wanted to abstract out the message into a parameter, we could keep it on the stack between iterations:
: print-10 ( message -- ) 10 [ dup print ] times drop ;
However, keeping loop-invariant values on the stack doesn't always work out nicely. For example, a word to subtract a value from each element of a sequence:
: subtract-n ( seq n -- seq' ) swap [ over - ] map nip ;
Three shuffle words are required to pass the value around. Instead, the loop-invariant value can be partially applied to a quotation using
curry, yielding a new quotation that is passed to
map:
USING: sequences prettyprint ;
: subtract-n ( seq n -- seq' ) [ - ] curry map ;
{ 10 20 30 } 5 subtract-n .
{ 5 15 25 }
Now consider the word that is dual to the one above; instead of subtracting
n from each stack element, it subtracts each element from
n.
One way to write this is with a pair of
swaps:
: n-subtract ( n seq -- seq' ) swap [ swap - ] curry map ;
Since this pattern comes up often,
with encapsulates it:
: n-subtract ( n seq -- seq' ) [ - ] with map ;
30 { 10 20 30 } n-subtract .
{ 20 10 0 }
See alsoExamples of fried quotations