]> gitweb.factorcode.org Git - factor.git/blob - core/words/words-docs.factor
Update actions, because Node.js 16 actions are deprecated, to Node.js 20
[factor.git] / core / words / words-docs.factor
1 USING: classes compiler.units definitions effects help.markup
2 help.syntax kernel parser quotations sequences strings vocabs ;
3 IN: words
4
5 ARTICLE: "interned-words" "Looking up and creating words"
6 "A word is said to be " { $emphasis "interned" } " if it is a member of the vocabulary named by its vocabulary slot. Otherwise, the word is " { $emphasis "uninterned" } "."
7 $nl
8 "Words whose names are known at parse time -- that is, most words making up your program -- can be referenced in source code by stating their name. However, the parser itself, and sometimes code you write, will need to look up words dynamically."
9 $nl
10 "Parsing words add definitions to the current vocabulary. When a source file is being parsed, the current vocabulary is initially set to " { $vocab-link "scratchpad" } ". The current vocabulary may be changed with the " { $link POSTPONE: IN: } " parsing word (see " { $link "word-search" } ")."
11 { $subsections
12     create-word
13     create-word-in
14     lookup-word
15 } ;
16
17 ARTICLE: "uninterned-words" "Uninterned words"
18 "A word that is not a member of any vocabulary is said to be " { $emphasis "uninterned" } "."
19 $nl
20 "There are several ways of creating an uninterned word:"
21 { $subsections
22     <word>
23     <uninterned-word>
24     gensym
25     define-temp
26 } ;
27
28 ARTICLE: "colon-definition" "Colon definitions"
29 "All words have associated definition " { $link "quotations" } ". A word's definition quotation is called when the word is executed. A " { $emphasis "colon definition" } " is a word where this quotation is supplied directly by the user. This is the simplest and most common type of word definition."
30 $nl
31 "Defining words at parse time:"
32 { $subsections
33     POSTPONE: :
34     POSTPONE: ;
35 }
36 "Defining words at run time:"
37 { $subsections
38     define
39     define-declared
40     define-inline
41 }
42 "Word definitions must declare their stack effect. See " { $link "effects" } "."
43 $nl
44 "All other types of word definitions, such as " { $link "words.symbol" } " and " { $link "generic" } ", are just special cases of the above." ;
45
46 ARTICLE: "primitives" "Primitives"
47 "Primitives are words defined in the Factor VM. They provide the essential low-level services to the rest of the system."
48 { $subsections
49     primitive
50     primitive?
51 } ;
52
53 ARTICLE: "deferred" "Deferred words and mutual recursion"
54 "Words cannot be referenced before they are defined; that is, source files must order definitions in a strictly bottom-up fashion. This is done to simplify the implementation, facilitate better parse time checking and remove some odd corner cases; it also encourages better coding style."
55 $nl
56 "Sometimes this restriction gets in the way, for example when defining mutually-recursive words; one way to get around this limitation is to make a forward definition."
57 { $subsections POSTPONE: DEFER: }
58 "The class of deferred word definitions:"
59 { $subsections
60     deferred
61     deferred?
62 }
63 "Deferred words throw an error when called:"
64 { $subsections undefined }
65 "Deferred words are just compound definitions in disguise. The following two lines are equivalent:"
66 { $code
67     "DEFER: foo"
68     ": foo ( -- * ) undefined ;"
69 } ;
70
71 ARTICLE: "declarations" "Compiler declarations"
72 "Compiler declarations are parsing words that set a word property in the most recently defined word. They appear after the final " { $link POSTPONE: ; } " of a word definition:"
73 { $code ": cubed ( x -- y ) dup dup * * ; foldable" }
74 "Compiler declarations assert that the word follows a certain contract, enabling certain optimizations that are not valid in general."
75 { $subsections
76     POSTPONE: inline
77     POSTPONE: foldable
78     POSTPONE: flushable
79     POSTPONE: recursive
80 }
81 "It is entirely up to the programmer to ensure that the word satisfies the contract of a declaration. Furthermore, if a generic word is declared " { $link POSTPONE: foldable } " or " { $link POSTPONE: flushable } ", all methods must satisfy the contract. Unspecified behavior may result if a word does not follow the contract of one of its declarations."
82 { $see-also "effects" } ;
83
84 ARTICLE: "word-props" "Word properties"
85 "Each word has a hashtable of properties."
86 { $subsections
87     word-prop
88     set-word-prop
89 }
90 "The stack effect of the above two words is designed so that it is most convenient when " { $snippet "name" } " is a literal pushed on the stack right before executing this word."
91 $nl
92 "The following are some of the properties used by the library:"
93 { $table
94   { { $strong "Property" } { $strong "Documentation" } }
95   {
96       { $snippet "\"declared-effect\"" } { $link "effects" }
97   }
98   {
99       {
100           { $snippet "\"inline\"" } ", "
101           { $snippet "\"foldable\"" } ", "
102           { $snippet "\"flushable\"" } ", "
103           { $snippet "\"recursive\"" }
104       }
105       { $link "declarations" }
106   }
107   {
108       {
109           { $snippet "\"help\"" } ", "
110           { $snippet "\"help-loc\"" } ", "
111           { $snippet "\"help-parent\"" }
112       }
113       { "Where word help is stored - " { $link "writing-help" } }
114   }
115   {
116       { $snippet "\"intrinsic\"" }
117       { "Quotation run by the compiler during cfg building to emit the word inline." }
118   }
119   {
120       { $snippet "\"loc\"" }
121       { "Location information - " { $link where } }
122   }
123   {
124       { { $snippet "\"methods\"" } ", " { $snippet "\"combination\"" } }
125       { "Set on generic words - " { $link "generic" } }
126   }
127   {
128       {
129           { $snippet "\"outputs\"" } ", "
130           { $snippet "\"input-classes\"" } ", "
131           { $snippet "\"default-output-classes\"" }
132       }
133       { "A bunch of metadata used during the value propagation step of the compilation to produce type-optimized code." }
134   }
135   {
136       { $snippet "\"parsing\"" }
137       { $link "parsing-words" }
138   }
139   {
140       { $snippet "\"predicating\"" }
141       "Set on class predicates, stores the corresponding class word."
142   }
143   {
144       { { $snippet "\"reading\"" } ", " { $snippet "\"writing\"" } }
145       { "Set on slot accessor words - " { $link "slots" } }
146   }
147   {
148       { $snippet "\"specializer\"" }
149       { $link "hints" }
150   }
151   {
152       {
153           { $snippet "\"dependencies\"" } ", "
154
155       }
156       { "Used by the optimizing compiler when forgetting words for fast dependency lookup. See " { $link "compilation-units" } "." }
157   }
158   {
159       { $snippet "\"generic-call-sites\"" }
160       { "Set on some generic words." }
161   }
162 }
163 "Properties which are defined for classes only:"
164 { $table
165     { { $strong "Property" } { $strong "Documentation" } }
166     { { $snippet "\"class\"" } { "A boolean indicating whether this word is a class - " { $link "classes" } } }
167
168     { { $snippet "\"coercer\"" } { "A quotation for converting the top of the stack to an instance of this class" } }
169
170     { { $snippet "\"constructor\"" } { $link "tuple-constructors" } }
171
172     { { $snippet "\"type\"" } { $link "builtin-classes" } }
173
174     { { { $snippet "\"superclass\"" } ", " { $snippet "\"predicate-definition\"" } } { $link "predicates" } }
175
176     { { $snippet "\"members\"" } { $link "unions" } { $link "maybes" } }
177     {
178         { $snippet "\"instances\"" }
179         { "Lists the instances of the mixin class and where they are defined - " { $link "mixins" } }
180     }
181     {
182         { $snippet "\"predicate\"" }
183         { "A quotation that tests if the top of the stack is an instance of this class - " { $link "class-predicates" } }
184     }
185     { { $snippet "\"slots\"" } { $link "slots" } }
186     {
187         {
188             { $snippet "\"superclass\"" } ", "
189             { $snippet "\"predicate-definition\"" }
190         }
191         { $link "predicates" }
192     }
193     { { $snippet "\"type\"" } { $link "builtin-classes" } }
194 } ;
195
196 ARTICLE: "word.private" "Word implementation details"
197 "The " { $snippet "def" } " slot of a word holds a " { $link quotation } " instance that is called when the word is executed."
198 $nl
199 "A primitive to get the memory range storing the machine code for a word:"
200 { $subsections word-code } ;
201
202 ARTICLE: "words.introspection" "Word introspection"
203 "Word introspection facilities and implementation details are found in the " { $vocab-link "words" } " vocabulary."
204 $nl
205 "Word objects contain several slots:"
206 { $table
207     { { $snippet "name" } "a word name" }
208     { { $snippet "vocabulary" } "a word vocabulary name" }
209     { { $snippet "def" } "a definition quotation" }
210     { { $snippet "props" } "an assoc of word properties, including documentation and other metadata" }
211 }
212 "Words are instances of a class."
213 { $subsections
214     word
215     word?
216 }
217 "Words implement the definition protocol; see " { $link "definitions" } "."
218 { $subsections
219     "interned-words"
220     "uninterned-words"
221     "word-props"
222     "word.private"
223 } ;
224
225 ARTICLE: "words" "Words"
226 "Words are the Factor equivalent of functions or procedures in other languages. Words are essentially named " { $link "quotations" } "."
227 $nl
228 "There are two ways of creating word definitions:"
229 { $list
230     "using parsing words at parse time."
231     "using defining words at run time."
232 }
233 "The latter is a more dynamic feature that can be used to implement code generation and such, and in fact parse time defining words are implemented in terms of run time defining words."
234 $nl
235 "Types of words:"
236 { $subsections
237     "colon-definition"
238     "words.symbol"
239     "words.alias"
240     "words.constant"
241     "primitives"
242 }
243 "Advanced topics:"
244 { $subsections
245     "deferred"
246     "declarations"
247     "words.introspection"
248     "word-props"
249 }
250 { $see-also "vocabularies" "vocabs.loader" "definitions" "see" } ;
251
252 ABOUT: "words"
253
254 HELP: changed-effect
255 { $values { "word" word } }
256 { $description "Signals to the compilation unit that the effect of the word has changed. It causes all words that depend on it to be recompiled in response." }
257 { $see-also changed-effects } ;
258
259 HELP: deferred
260 { $class-description "The class of deferred words created by " { $link POSTPONE: DEFER: } "." } ;
261
262 { deferred POSTPONE: DEFER: } related-words
263
264 HELP: undefined
265 { $error-description "This error is thrown in two cases, and the debugger's summary message reflects the cause:"
266     { $list
267         { "A word was executed before being compiled. For example, this can happen if a macro is defined in the same compilation unit where it was used. See " { $link "compilation-units" } " for a discussion." }
268         { "A word defined with " { $link POSTPONE: DEFER: } " was executed. Since this syntax is usually used for mutually-recursive word definitions, executing a deferred word usually indicates a programmer mistake." }
269     }
270 } ;
271
272 HELP: primitive
273 { $class-description "The class of primitive words." } ;
274
275 HELP: word-prop
276 { $values { "word" word } { "name" "a property name" } { "value" "a property value" } }
277 { $description "Retrieves a word property. Word property names are conventionally strings." } ;
278
279 HELP: set-word-prop
280 { $values { "word" word } { "value" "a property value" } { "name" "a property name" } }
281 { $description "Stores a word property. Word property names are conventionally strings." }
282 { $side-effects "word" } ;
283
284 HELP: remove-word-prop
285 { $values { "word" word } { "name" "a property name" } }
286 { $description "Removes a word property, so future lookups will output " { $link f } " until it is set again. Word property names are conventionally strings." }
287 { $side-effects "word" } ;
288
289 HELP: remove-word-props
290 { $values { "word" word } { "seq" { $sequence "word property names" } } }
291 { $description "Removes all listed word properties from the word." }
292 { $side-effects "word" } ;
293
294 HELP: word-code
295 { $values { "word" word } { "start" "the word's start address" } { "end" "the word's end address" } }
296 { $description "Outputs the memory range containing the word's machine code." } ;
297
298 HELP: define
299 { $values { "word" word } { "def" quotation } }
300 { $description "Defines the word to call a quotation when executed. This is the run time equivalent of " { $link POSTPONE: : } "." }
301 { $notes "This word must be called from inside " { $link with-compilation-unit } "." }
302 { $side-effects "word" } ;
303
304 HELP: reset-word
305 { $values { "word" word } }
306 { $description "Reset word declarations." }
307 $low-level-note
308 { $side-effects "word" } ;
309
310 HELP: reset-generic
311 { $values { "word" word } }
312 { $description "Reset word declarations and generic word properties." }
313 $low-level-note
314 { $side-effects "word" } ;
315
316 HELP: <word>
317 { $values { "name" string } { "vocab" string } { "word" word } }
318 { $description "Allocates a word with the specified name and vocabulary. User code should call " { $link <uninterned-word> } " to create uninterned words and " { $link create-word } " to create interned words, instead of calling this constructor directly." }
319 { $notes "This word must be called from inside " { $link with-compilation-unit } "." } ;
320
321 HELP: <uninterned-word>
322 { $values { "name" string } { "word" word } }
323 { $description "Creates an uninterned word with the specified name, that is not equal to any other word in the system." }
324 { $notes "Unlike " { $link create-word } ", this word does not have to be called from inside " { $link with-compilation-unit } "." } ;
325
326 HELP: gensym
327 { $values { "word" word } }
328 { $description "Creates an uninterned word that is not equal to any other word in the system." }
329 { $examples { $example "USING: prettyprint words ;"
330     "gensym ."
331     "( gensym )"
332     }
333 }
334 { $notes "Unlike " { $link create-word } ", this word does not have to be called from inside " { $link with-compilation-unit } "." } ;
335
336 HELP: bootstrapping?
337 { $var-description "Set by the library while bootstrap is in progress. Some parsing words need to behave differently during bootstrap." } ;
338
339 HELP: last-word
340 { $values { "word" word } }
341 { $description "Outputs the most recently defined word." } ;
342
343 HELP: word
344 { $class-description "The class of words. One notable subclass is " { $link class } ", the class of class words." } ;
345
346 { last-word set-last-word save-location } related-words
347
348 HELP: set-last-word
349 { $values { "word" word } }
350 { $description "Sets the recently defined word." } ;
351
352 HELP: lookup-word
353 { $values { "name" string } { "vocab" string } { "word" { $maybe word } } }
354 { $description "Looks up a word in the dictionary. If the vocabulary or the word is not defined, outputs " { $link f } "." } ;
355
356 HELP: reveal
357 { $values { "word" word } }
358 { $description "Adds a newly-created word to the dictionary. Usually this word does not need to be called directly, and is only called as part of " { $link create-word } "." } ;
359
360 HELP: check-create
361 { $values { "name" string } { "vocab" string } }
362 { $description "Throws a " { $link check-create } " error if " { $snippet "name" } " or " { $snippet "vocab" } " is not a string." }
363 { $error-description "Thrown if " { $link create-word } " is called with invalid parameters." } ;
364
365 HELP: create-word
366 { $values { "name" string } { "vocab" string } { "word" word } }
367 { $description "Creates a new word. If the vocabulary already contains a word with the requested name, outputs the existing word. The vocabulary must exist already; if it does not, you must call " { $link create-vocab } " first." }
368 { $notes "This word must be called from inside " { $link with-compilation-unit } ". Parsing words should call " { $link create-word-in } " instead of this word." } ;
369
370 { POSTPONE: FORGET: forget forget* forget-vocab } related-words
371
372 HELP: target-word
373 { $values { "word" word } { "target" word } }
374 { $description "Looks up a word with the same name and vocabulary as the given word. Used during bootstrap to transfer host words to the target dictionary." } ;
375
376 HELP: bootstrap-word
377 { $values { "word" word } { "target" word } }
378 { $description "Looks up a word with the same name and vocabulary as the given word, performing a transformation to handle parsing words in the target dictionary. Used during bootstrap to transfer host words to the target dictionary." } ;
379
380 HELP: parsing-word?
381 { $values { "object" object } { "?" boolean } }
382 { $description "Tests if an object is a parsing word declared by " { $link POSTPONE: SYNTAX: } "." }
383 { $notes "Outputs " { $link f } " if the object is not a word." } ;
384
385 HELP: define-declared
386 { $values { "word" word } { "def" quotation } { "effect" effect } }
387 { $description "Defines a word and declares its stack effect." }
388 { $notes "This word must be called from inside " { $link with-compilation-unit } "." }
389 { $side-effects "word" } ;
390
391 HELP: define-temp
392 { $values { "quot" quotation } { "effect" effect } { "word" word } }
393 { $description "Creates an uninterned word that will call " { $snippet "quot" } " when executed." }
394 { $notes
395     "The following phrases are equivalent:"
396     { $code "[ 2 2 + . ] call" }
397     { $code "[ 2 2 + . ] ( -- ) define-temp execute" }
398     "This word must be called from inside " { $link with-compilation-unit } "."
399 } ;
400
401 HELP: delimiter?
402 { $values { "obj" object } { "?" boolean } }
403 { $description "Tests if an object is a delimiter word declared by " { $link POSTPONE: delimiter } "." }
404 { $notes "Outputs " { $link f } " if the object is not a word." } ;
405
406 HELP: deprecated?
407 { $values { "obj" object } { "?" boolean } }
408 { $description "Tests if an object is " { $link POSTPONE: deprecated } "." }
409 { $notes "Outputs " { $link f } " if the object is not a word." } ;
410
411 HELP: inline?
412 { $values { "obj" object } { "?" boolean } }
413 { $description "Tests if an object is " { $link POSTPONE: inline } "." }
414 { $notes "Outputs " { $link f } " if the object is not a word." } ;
415
416 HELP: subwords
417 { $values { "word" word } { "seq" sequence } }
418 { $description "Lists all specializations for the given word." }
419 { $examples
420   { $example
421     "USING: math.functions prettyprint words ;"
422     "\\ sin subwords ."
423     "{ M\\ object sin M\\ complex sin M\\ real sin M\\ float sin }"
424   }
425 }
426 { $notes "Outputs " { $link f } " if the word isn't generic." } ;
427
428 HELP: make-deprecated
429 { $values { "word" word } }
430 { $description "Declares a word as " { $link POSTPONE: deprecated } "." }
431 { $side-effects "word" } ;
432
433 HELP: make-flushable
434 { $values { "word" word } }
435 { $description "Declares a word as " { $link POSTPONE: flushable } "." }
436 { $side-effects "word" } ;
437
438 HELP: make-foldable
439 { $values { "word" word } }
440 { $description "Declares a word as " { $link POSTPONE: foldable } "." }
441 { $side-effects "word" } ;
442
443 HELP: make-inline
444 { $values { "word" word } }
445 { $description "Declares a word as " { $link POSTPONE: inline } "." }
446 { $side-effects "word" } ;
447
448 HELP: define-inline
449 { $values { "word" word } { "def" quotation } { "effect" effect } }
450 { $description "Defines a word and makes it " { $link POSTPONE: inline } "." }
451 { $notes "This word must be called from inside " { $link with-compilation-unit } "." }
452 { $side-effects "word" } ;