]> gitweb.factorcode.org Git - factor.git/blob - core/effects/effects-docs.factor
Fixes unused variable warning
[factor.git] / core / effects / effects-docs.factor
1 USING: arrays classes help.markup help.syntax kernel math
2 sequences strings words ;
3 IN: effects
4
5 ARTICLE: "effects" "Stack effect declarations"
6 "Word definition words such as " { $link POSTPONE: : } " and " { $link POSTPONE: GENERIC: } " have a " { $emphasis "stack effect declaration" } " as part of their syntax. A stack effect declaration takes the following form:"
7 { $code "( input1 input2 ... -- output1 ... )" }
8 "Stack elements in a stack effect are ordered so that the top of the stack is on the right side. Here is an example:"
9 { $synopsis + }
10 "Parameters which are quotations can be declared by suffixing the parameter name with " { $snippet ":" } " and then writing a nested stack effect declaration. If the number of inputs or outputs depends on the stack effects of quotation parameters, row variables can be declared:"
11 { $subsection "effects-variables" }
12 "Some examples of row-polymorphic combinators:"
13 { $synopsis while }
14 { $synopsis if* }
15 { $synopsis each }
16 "For words that are not " { $link POSTPONE: inline } ", only the number of inputs and outputs carries semantic meaning, and effect variables are ignored. However, nested quotation declarations are enforced for inline words. Nested quotation declarations are optional for non-recursive inline combinators and only provide better error messages. However, quotation inputs to " { $link POSTPONE: recursive } " combinators must have an effect declared. See " { $link "inference-recursive-combinators" } "."
17 $nl
18 "In concatenative code, input and output names are for documentation purposes only and certain conventions have been established to make them more descriptive. For code written with " { $link "locals" } ", stack values are bound to local variables named by the stack effect's input parameters."
19 $nl
20 "Inputs and outputs are typically named after some pun on their data type, or a description of the value's purpose if the type is very general. The following are some examples of value names:"
21 { $table
22     { { { $snippet "?" } } "a boolean" }
23     { { { $snippet "<=>" } } { "an ordering specifier; see " { $link "order-specifiers" } } }
24     { { { $snippet "elt" } } "an object which is an element of a sequence" }
25     { { { $snippet "m" } ", " { $snippet "n" } } "an integer" }
26     { { { $snippet "obj" } } "an object" }
27     { { { $snippet "quot" } } "a quotation" }
28     { { { $snippet "seq" } } "a sequence" }
29     { { { $snippet "assoc" } } "an associative mapping" }
30     { { { $snippet "str" } } "a string" }
31     { { { $snippet "x" } ", " { $snippet "y" } ", " { $snippet "z" } } "a number" }
32     { { $snippet "loc" } "a screen location specified as a two-element array holding x and y co-ordinates" }
33     { { $snippet "dim" } "a screen dimension specified as a two-element array holding width and height values" }
34     { { $snippet "*" } "when this symbol appears by itself in the list of outputs, it means the word unconditionally throws an error" }
35 }
36 "For reflection and metaprogramming, you can use " { $link "syntax-effects" } " to include literal stack effects in your code, or these constructor words to construct stack effect objects at runtime:"
37 { $subsections
38     <effect>
39     <terminated-effect>
40     <variable-effect>
41 }
42 { $see-also "inference" } ;
43
44 HELP: <effect>
45 { $values
46     { "in" "a sequence of strings or string–type pairs" }
47     { "out" "a sequence of strings or string–type pairs" }
48     { "effect" effect }
49 }
50 { $description "Constructs an " { $link effect } " object. Each element of " { $snippet "in" } " and " { $snippet "out" } " must be either a string, which is equivalent to a " { $snippet "name" } " in literal stack effect syntax, or a " { $link pair } " where the first element is a string and the second is either a " { $link class } " or effect, which is equivalent to " { $snippet "name: class" } " or " { $snippet "name: ( nested -- effect )" } " in the literal syntax. If the " { $snippet "out" } " array consists of a single string element " { $snippet "\"*\"" } ", a terminating stack effect will be constructed." }
51 { $notes "This word cannot construct effects with " { $link "effects-variables" } ". Use " { $link <variable-effect> } " to construct variable stack effects." }
52 { $examples
53 { $example "USING: effects prettyprint ;
54 { \"a\" \"b\" } { \"c\" } <effect> ." "( a b -- c )" }
55 { $example "USING: arrays effects prettyprint ;
56 { \"a\" { \"b\" array } } { \"c\" } <effect> ." "( a b: array -- c )" }
57 { $example "USING: effects prettyprint ;
58 { \"a\" { \"b\" ( x y -- z ) } } { \"c\" } <effect> ." "( a b: ( x y -- z ) -- c )" }
59 { $example "USING: effects prettyprint ;
60 { \"a\" { \"b\" ( x y -- z ) } } { \"*\" } <effect> ." "( a b: ( x y -- z ) -- * )" }
61 } ;
62
63 HELP: <terminated-effect>
64 { $values
65     { "in" "a sequence of strings or string–type pairs" }
66     { "out" "a sequence of strings or string–type pairs" }
67     { "terminated?" boolean }
68     { "effect" effect }
69 }
70 { $description "Constructs an " { $link effect } " object like " { $link <effect> } ". If " { $snippet "terminated?" } " is true, the value of " { $snippet "out" } " is ignored, and a terminating stack effect is constructed." }
71 { $notes "This word cannot construct effects with " { $link "effects-variables" } ". Use " { $link <variable-effect> } " to construct variable stack effects." }
72 { $examples
73 { $example "USING: effects prettyprint ;
74 { \"a\" { \"b\" ( x y -- z ) } } { \"c\" } f <terminated-effect> ." "( a b: ( x y -- z ) -- c )" }
75 { $example "USING: effects prettyprint ;
76 { \"a\" { \"b\" ( x y -- z ) } } { } t <terminated-effect> ." "( a b: ( x y -- z ) -- * )" }
77 } ;
78
79 HELP: <variable-effect>
80 { $values
81     { "in-var" { $maybe string } }
82     { "in" "a sequence of strings or string–type pairs" }
83     { "out-var" { $maybe string } }
84     { "out" "a sequence of strings or string–type pairs" }
85     { "effect" effect }
86 }
87 { $description "Constructs an " { $link effect } " object like " { $link <effect> } ". If " { $snippet "in-var" } " or " { $snippet "out-var" } " are not " { $link f } ", they are used as the names of the " { $link "effects-variables" } " for the inputs and outputs of the effect object." }
88 { $examples
89 { $example "USING: effects prettyprint ;
90 f { \"a\" \"b\" } f { \"c\" } <variable-effect> ." "( a b -- c )" }
91 { $example "USING: effects prettyprint ;
92 \"x\" { \"a\" \"b\" } \"y\" { \"c\" } <variable-effect> ." "( ..x a b -- ..y c )" }
93 { $example "USING: arrays effects prettyprint ;
94 \"y\" { \"a\" { \"b\" ( ..x -- ..y ) } } \"x\" { \"c\" } <variable-effect> ." "( ..y a b: ( ..x -- ..y ) -- ..x c )" }
95 { $example "USING: effects prettyprint ;
96 \".\" { \"a\" \"b\" } f { \"*\" } <variable-effect> ." "( ... a b -- * )" }
97 } ;
98
99
100 { <effect> <terminated-effect> <variable-effect> } related-words
101
102 ARTICLE: "effects-variables" "Stack effect row variables"
103 "The stack effect of many " { $link POSTPONE: inline } " combinators can have variable stack effects, depending on the effect of the quotation they call. For example, the quotation parameter to " { $link each } " receives an element from the input sequence each time it is called, but it can also manipulate values on the stack below the element as long as it leaves the same number of elements on the stack. (This is how " { $link reduce } " is implemented in terms of " { $snippet "each" } ".) The stack effect of an " { $snippet "each" } " expression thus depends on the stack effect of its input quotation:"
104 { $example
105  "USING: io sequences stack-checker ;
106 [ [ write ] each ] infer."
107 "( x -- )" }
108 { $example
109 "USING: sequences stack-checker ;
110 [ [ append ] each ] infer."
111 "( x x -- x )" }
112 "This feature is referred to as row polymorphism. Row-polymorphic combinators are declared by including row variables in their stack effect, which are indicated by names starting with " { $snippet ".." } ":"
113 { $synopsis each }
114 "Using the same variable name in both the inputs and outputs (in the above case of " { $snippet "each" } ", " { $snippet "..." } ") indicates that the number of additional inputs and outputs must be the same. Using different variable names indicates that they can be independent. In combinators with multiple quotation inputs, the number of inputs or outputs represented by a particular " { $snippet ".." } " name must match among all of the quotations. For example, the branches of " { $link if* } " can take a different number of inputs from outputs, as long as they both have the same stack height. The true branch receives the test value as an added input. This is declared as follows:"
115 { $synopsis if* }
116 "Stack effect variables can only occur as the first input or first output of a stack effect; names starting in " { $snippet ".." } " cause a syntax error if they occur elsewhere in the effect. For words that are not " { $link POSTPONE: inline } ", effect variables are currently ignored by the stack checker." ;
117
118 ABOUT: "effects"
119
120 HELP: effect
121 { $class-description "An object representing a stack effect. Holds a sequence of inputs, a sequence of outputs and a flag indicating if an error is thrown unconditionally." } ;
122
123 HELP: effect-height
124 { $values { "effect" effect } { "n" integer } }
125 { $description "Outputs the number of objects added to the data stack by the stack effect. This will be negative if the stack effect only removes objects from the stack." } ;
126
127 HELP: effect<=
128 { $values { "effect1" effect } { "effect2" effect } { "?" boolean } }
129 { $description "Tests if " { $snippet "effect1" } " is substitutable for " { $snippet "effect2" } ". What this means is that both stack effects change the stack height by the same amount, the first takes a smaller or equal number of inputs as the second, and either both or neither one terminate execution by throwing an error." } ;
130
131 HELP: effect=
132 { $values { "effect1" effect } { "effect2" effect } { "?" boolean } }
133 { $description "Tests if " { $snippet "effect1" } " and " { $snippet "effect2" } " represent the same stack transformation, without looking parameter names." }
134 { $examples
135   { $example "USING: effects prettyprint ;" "( a -- b ) ( x -- y ) effect= ." "t" }
136 } ;
137
138 HELP: effect>string
139 { $values { "obj" object } { "str" string } }
140 { $description "Turns a stack effect object into a string mnemonic." }
141 { $examples
142     { $example "USING: effects io ;" "{ \"x\" } { \"y\" \"z\" } <effect> effect>string print" "( x -- y z )" }
143 } ;
144
145 HELP: stack-effect
146 { $values { "word" word } { "effect/f" { $maybe effect } } }
147 { $description "Outputs the stack effect of a word; either a stack effect declared with " { $link POSTPONE: ( } ", or an inferred stack effect (see " { $link "inference" } ")." } ;