 { $values { "objs..." "objects" } { "seq" "a sequence of quotations with stack effect " { $snippet "( x -- ... )" } } }
 { $description "Applies each quotation to the object in turn." }
 { $examples
-    "The " { $link bi* } " combinator takes two values and two quotations; the " { $link tri* } " combinator takes three values and three quotations. The " { $link spread } " combinator takes " { $snippet "n" } " values and " { $snippet "n" } " quotations, where " { $snippet "n" } " is the length of the input sequence, and is essentially equivalent to series of retain stack manipulations:"
+    "The " { $link bi* } " combinator takes two values and two quotations; the " { $link tri* } " combinator takes three values and three quotations. The " { $link spread } " combinator takes " { $snippet "n" } " values and " { $snippet "n" } " quotations, where " { $snippet "n" } " is the length of the input sequence, and is essentially equivalent to a nested series of " { $link dip } "s:"
     { $code
         "! Equivalent"
         "{ [ p ] [ q ] [ r ] [ s ] } spread"

"A pair of utility words built from " { $link bi@ } ":"
{ $subsections both? either? } ;

ARTICLE: "retainstack-combinators" "Retain stack combinators"
"Sometimes an additional storage area is needed to hold objects. The " { $emphasis "retain stack" } " is an auxilliary stack for this purpose. Objects can be moved between the data and retain stacks using a set of combinators."
$nl
"The dip combinators invoke the quotation at the top of the stack, hiding the values underneath:"
{ $subsections dip 2dip 3dip 4dip }
"The keep combinators invoke a quotation which takes a number of values off the stack, and then they restore those values:"
{ $subsections keep 2keep 3keep } ;

ARTICLE: "curried-dataflow" "Curried dataflow combinators"

{ $subsections call-effect-unsafe execute-effect-unsafe } ;

ARTICLE: "call" "Fundamental combinators"
"The most basic combinators are those that take either a quotation or word, and invoke it immediately. There are two sets of these fundamental combinators. They differ in whether the compiler is expected to determine the stack effect of the expression at compile time or the stack effect is declared and verified at run time."
$nl
{ $heading "Compile-time checked combinators" }
"With these combinators, the compiler attempts to determine the stack effect of the expression at compile time, rejecting the program if the effect cannot be determined. See " { $link "inference-combinators" } "."
{ $subsections call execute }
{ $heading "Run-time checked combinators" }
"With these combinators, the stack effect of the expression is checked at run time."
{ $subsections POSTPONE: call( POSTPONE: execute( }
"Note that the opening parenthesis is actually part of the word name for " { $snippet "call(" } " and " { $snippet "execute(" } "; they are parsing words, and they read a stack effect until the corresponding closing parenthesis. The underlying words are a bit more verbose, but they can be given non-constant stack effects:"
{ $subsections call-effect execute-effect }
{ $heading "Unchecked combinators" }
{ $subsections "call-unsafe" }
{ $see-also "effects" "inference" } ;

