Consider printing the same message ten times:

if we wanted to abstract out the message into a parameter, we could keep it on the stack between iterations:

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:

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:

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:

Since this pattern comes up often, with encapsulates it:

See also

Examples of fried quotations

: 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:

: subtract-n ( seq n -- seq' ) [ - ] curry map ;
{ 10 20 30 } 5 subtract-n .

{ 5 15 25 }

{ 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 }

{ 20 10 0 }

See also

Examples of fried quotations