]> gitweb.factorcode.org Git - factor.git/blob - core/generic/generic-docs.factor
becd855653bf9789d3be7872f14854ab08d529eb
[factor.git] / core / generic / generic-docs.factor
1 USING: help.markup help.syntax words classes classes.algebra
2 definitions kernel alien sequences math quotations
3 generic.standard generic.math combinators ;
4 IN: generic
5
6 ARTICLE: "method-order" "Method precedence"
7 "Conceptually, method dispatch is implemented by testing the object against the predicate word for every class, in linear order (" { $link "class-linearization" } ")."
8 $nl
9 "Here is an example:"
10 { $code
11     "GENERIC: explain"
12     "M: object explain drop \"an object\" print ;"
13     "M: number explain drop \"a number\" print ;"
14     "M: sequence explain drop \"a sequence\" print ;"
15 }
16 "The linear order is the following, from least-specific to most-specific:"
17 { $code "{ object sequence number }" }
18 "Neither " { $link number } " nor " { $link sequence } " are subclasses of each other, yet their intersection is the non-empty " { $link integer } " class. Calling " { $snippet "explain" } " with an integer on the stack will print " { $snippet "a number" } " because " { $link number } " precedes " { $link sequence } " in the class linearization order. If this was not the desired outcome, define a method on the intersection:"
19 { $code "M: integer explain drop \"a sequence\" print ;" }
20 "Now, the linear order is the following, from least-specific to most-specific:"
21 { $code "{ object sequence number integer }" }
22 "The " { $link order } " word can be useful to clarify method dispatch order:"
23 { $subsection order } ;
24
25 ARTICLE: "generic-introspection" "Generic word introspection"
26 "In most cases, generic words and methods are defined at parse time with " { $link POSTPONE: GENERIC: } " (or some other parsing word) and " { $link POSTPONE: M: } "."
27 $nl
28 "Sometimes, generic words need to be inspected defined at run time; words for performing these tasks are found in the " { $vocab-link "generic" } " vocabulary."
29 $nl
30 "The set of generic words is a class which implements the " { $link "definition-protocol" } ":"
31 { $subsection generic }
32 { $subsection generic? }
33 "New generic words can be defined:"
34 { $subsection define-generic }
35 { $subsection define-simple-generic }
36 "Methods can be added to existing generic words:"
37 { $subsection create-method }
38 "Method definitions can be looked up:"
39 { $subsection method }
40 "Finding the most specific method for an object:"
41 { $subsection effective-method }
42 "A generic word contains methods; the list of methods specializing on a class can also be obtained:"
43 { $subsection implementors }
44 "Low-level word which rebuilds the generic word after methods are added or removed, or the method combination is changed:"
45 { $subsection make-generic }
46 "Low-level method constructor:"
47 { $subsection <method> }
48 "A " { $emphasis "method specifier" } " refers to a method and implements the " { $link "definition-protocol" } ":"
49 { $subsection method-spec } ;
50
51 ARTICLE: "method-combination" "Custom method combination"
52 "Abstractly, a generic word can be thought of as a big chain of type conditional tests applied to the top of the stack, with methods as the bodies of each test. The " { $emphasis "method combination" } " is this control flow glue between the set of methods, and several aspects of it can be customized:"
53 { $list
54     "which stack item(s) the generic word dispatches upon,"
55     "which methods out of the set of applicable methods are called"
56 }
57 "A table of built-in method combination defining words, and the method combinations themselves:"
58 { $table
59     { { $link POSTPONE: GENERIC: } { $link standard-combination } }
60     { { $link POSTPONE: GENERIC# } { $link standard-combination } }
61     { { $link POSTPONE: HOOK: } { $link hook-combination } }
62     { { $link POSTPONE: MATH: } { $link math-combination } }
63 }
64 "Developing a custom method combination requires that a parsing word calling " { $link define-generic } " be defined; additionally, it is a good idea to implement the definition protocol words " { $link definer } " and " { $link synopsis* } " on the class of words having this method combination, to properly support developer tools."
65 $nl
66 "The combination quotation passed to " { $link define-generic } " has stack effect " { $snippet "( word -- quot )" } ". It's job is to call various introspection words, including at least obtaining the set of methods defined on the generic word, then combining these methods in some way to produce a quotation."
67 { $see-also "generic-introspection" } ;
68
69 ARTICLE: "call-next-method" "Calling less-specific methods"
70 "If a generic word is called with an object and multiple methods specialize on classes that this object is an instance of, usually the most specific method is called (" { $link "method-order" } ")."
71 $nl
72 "Less-specific methods can be called directly:"
73 { $subsection POSTPONE: call-next-method }
74 "A lower-level word which the above expands into:"
75 { $subsection (call-next-method) }
76 "To look up the next applicable method reflectively:"
77 { $subsection next-method }
78 "Errors thrown by improper calls to " { $link POSTPONE: call-next-method } ":"
79 { $subsection inconsistent-next-method }
80 { $subsection no-next-method } ;
81
82 ARTICLE: "generic" "Generic words and methods"
83 "A " { $emphasis "generic word" } " is composed of zero or more " { $emphasis "methods" } " together with a " { $emphasis "method combination" } ". A method " { $emphasis "specializes" } " on a class; when a generic word executed, the method combination chooses the most appropriate method and calls its definition."
84 $nl
85 "A generic word behaves roughly like a long series of class predicate conditionals in a " { $link cond } " form, however methods can be defined in independent source files, reducing coupling and increasing extensibility. The method combination determines which object the generic word will " { $emphasis "dispatch" } " on; this could be the top of the stack, or some other value."
86 $nl
87 "Generic words which dispatch on the object at the top of the stack:"
88 { $subsection POSTPONE: GENERIC: }
89 "A method combination which dispatches on a specified stack position:"
90 { $subsection POSTPONE: GENERIC# }
91 "A method combination which dispatches on the value of a variable at the time the generic word is called:"
92 { $subsection POSTPONE: HOOK: }
93 "A method combination which dispatches on a pair of stack values, which must be numbers, and upgrades both to the same type of number:"
94 { $subsection POSTPONE: MATH: }
95 "Method definition:"
96 { $subsection POSTPONE: M: }
97 "Generic words must declare their stack effect in order to compile. See " { $link "effect-declaration" } "."
98 { $subsection "method-order" }
99 { $subsection "call-next-method" }
100 { $subsection "generic-introspection" }
101 { $subsection "method-combination" }
102 "Generic words specialize behavior based on the class of an object; sometimes behavior needs to be specialized on the object's " { $emphasis "structure" } "; this is known as " { $emphasis "pattern matching" } " and is implemented in the " { $vocab-link "match" } " vocabulary." ;
103
104 ABOUT: "generic"
105
106 HELP: generic
107 { $class-description "The class of generic words, documented in " { $link "generic" } "." } ;
108
109 { generic define-generic define-simple-generic POSTPONE: GENERIC: POSTPONE: GENERIC# POSTPONE: MATH: POSTPONE: HOOK: } related-words
110
111 HELP: make-generic
112 { $values { "word" generic } }
113 { $description "Regenerates the definition of a generic word by applying the method combination to the set of defined methods." }
114 $low-level-note ;
115
116 HELP: define-generic
117 { $values { "word" word } { "combination" "a method combination" } }
118 { $description "Defines a generic word. A method combination is an object which responds to the " { $link perform-combination } " generic word." }
119 { $contract "The method combination quotation is called each time the generic word has to be updated (for example, when a method is added), and thus must be side-effect free." } ;
120
121 HELP: method-spec
122 { $class-description "The class of method specifiers, which are two-element arrays consisting of a class word followed by a generic word." }
123 { $examples { $code "{ fixnum + }" "{ editor draw-gadget* }" } } ;
124
125 HELP: method-body
126 { $class-description "The class of method bodies, which are words with special word properties set." } ;
127
128 HELP: method
129 { $values { "class" class } { "generic" generic } { "method/f" "a " { $link method-body } " or " { $link f } } }
130 { $description "Looks up a method definition." } ;
131
132 { method create-method POSTPONE: M: } related-words
133
134 HELP: <method>
135 { $values { "class" class } { "generic" generic } { "method" "a new method definition" } }
136 { $description "Creates a new method." } ;
137
138 HELP: order
139 { $values { "generic" generic } { "seq" "a sequence of classes" } }
140 { $description "Outputs a sequence of classes for which methods have been defined on this generic word. The sequence is sorted in method dispatch order." } ;
141
142 HELP: check-method
143 { $values { "class" class } { "generic" generic } }
144 { $description "Asserts that " { $snippet "class" } " is a class word and " { $snippet "generic" } " is a generic word, throwing a " { $link check-method } " error if the assertion fails." }
145 { $error-description "Thrown if " { $link POSTPONE: M: } " or " { $link create-method } " is given an invalid class or generic word." } ;
146
147 HELP: with-methods
148 { $values { "class" class } { "generic" generic } { "quot" "a quotation with stack effect " { $snippet "( methods -- )" } } }
149 { $description "Applies a quotation to the generic word's methods hashtable, and regenerates the generic word's definition when the quotation returns." }
150 $low-level-note ;
151
152 HELP: create-method
153 { $values { "class" class } { "generic" generic } { "method" method-body } }
154 { $description "Creates a method or returns an existing one. This is the runtime equivalent of " { $link POSTPONE: M: } "." }
155 { $notes "To define a method, pass the output value to " { $link define } "." } ;
156
157 HELP: forget-methods
158 { $values { "class" class } }
159 { $description "Remove all method definitions which specialize on the class." } ;
160
161 { sort-classes order } related-words
162
163 HELP: (call-next-method)
164 { $values { "class" class } { "generic" generic } }
165 { $description "Low-level word implementing " { $link POSTPONE: call-next-method } "." }
166 { $notes "In most cases, " { $link POSTPONE: call-next-method } " should be used instead." } ;