factor/doc/handbook/dataflow.facts

168 lines
7.9 KiB
Plaintext
Raw Normal View History

2006-05-17 14:55:46 -04:00
USING: errors help kernel namespaces threads words ;
ARTICLE: "dataflow" "Data and control flow"
{ $subsection "shuffle-words" }
{ $subsection "quotations" }
{ $subsection "combinators" }
{ $subsection "conditionals" }
{ $subsection "continuations" } ;
ARTICLE: "shuffle-words" "Shuffle words"
"Shuffle words rearrange items at the top of the data stack. They control the flow of data between words that perform actions."
$terpri
"Removing stack elements:"
{ $subsection drop }
{ $subsection 2drop }
{ $subsection 3drop }
{ $subsection nip }
{ $subsection 2nip }
"Duplicating stack elements:"
{ $subsection dup }
{ $subsection 2dup }
{ $subsection 3dup }
{ $subsection dupd }
{ $subsection over }
{ $subsection pick }
{ $subsection tuck }
"Permuting stack elements:"
{ $subsection swap }
{ $subsection rot }
{ $subsection -rot }
{ $subsection 2swap }
{ $subsection swapd }
"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 the following two words:"
{ $subsection >r }
{ $subsection r> }
"The top of the data stack is ``hidden'' between " { $link >r } " and " { $link r> } ":"
{ $example "1 2 3 >r .s r>" "2\n1" }
"Words must not leave objects on the retain stack, nor expect values to be there on entry. The retain stack is for local storage within a word only, and occurrences of " { $link >r } " and " { $link r> } " must be balanced inside a single quotation. One exception is the following trick involving " { $link if } "; values may be pushed on the retain stack before the condition value is computed, as long as both branches of the " { $link if } " pop the values off the retain stack before returning:"
{ $code
": foo ( m ? n -- m+n/n )"
" >r [ r> + ] [ drop r> ] if ; ! This is OK"
} ;
ARTICLE: "quotations" "Quotations"
"A quotation is a sequence of objects, some of which may be words. When evaluating a quotation, the interpreter looks at each element in turn, and executes words while pushing other types of objects on the stack."
$terpri
"Quotation literal syntax is documented in " { $link "quotation-syntax" } "."
$terpri
"More precisely, the interpreter runs in a loop which repeatedly performs the following steps:"
{ $list
{ "If the end of the current quotation has been reached, the parent quotation is popped from the call stack and execution resumes from the saved location" }
{ "Otherwise, the interpreter performs an action depending on the type of the object at the instruction pointer:"
{ $list
{ { $emphasis "Symbol word" } " - pushed on the datastack. See " { $link "symbols" } }
{ { $emphasis "Compound word" } " - the associated quotation is called. See " { $link "colon-definition" } }
{ { $emphasis "Compiled or primitive word" } " - the interpreter jumps to machine code. See " { $link "primitives" } }
{ { $emphasis "Undefined word" } " - an error is raised. See " { $link "deferred" } }
{ { $emphasis "Wrapper" } " - the wrapped object is pushed on the data stack. Wrappers are used to push word objects directly on the stack when they would otherwise execute. See the " { $link POSTPONE: \ } " parsing word." }
{ "All other types of objects are pushed on the data stack." }
}
}
}
"At each stage, the instruction pointer is advanced by one position."
$terpri
"If the instruction pointer is at the end of a quotation when a nested quotation is called, the quotation which just finished executing is not pushed on the call stack. Therefore the last call in a quotation does not grow the call stack, and tail recursion executes in bounded space."
$terpri
"The compiler generates machine code which perform the steps in a more efficient manner than the interpreter, however the observable semantics remain the same." ;
ARTICLE: "combinators" "Combinators"
"The following pair of words invoke the interpreter reflectively:"
{ $subsection call }
{ $subsection execute }
"These words are used to implement " { $emphasis "combinators" } ", which are words that take code from the stack. Combinator definitions must be followed by the " { $link POSTPONE: inline } " declaration in order to compile; for example:"
{ $code
": keep ( x quot -- x | quot: x -- )"
" over >r call r> ; inline"
}
"Word inlining is documented in " { $link "declarations" } "."
$terpri
"There are some words that combine shuffle words with " { $link call } ". They are useful for implementing higher-level combinators."
{ $subsection slip }
{ $subsection 2slip }
{ $subsection keep }
{ $subsection 2keep }
{ $subsection 3keep }
{ $subsection 2apply } ;
ARTICLE: "conditionals" "Conditionals and boolean logic"
"In Factor, any object that is not " { $link f } " has a true boolean value, and " { $link f } " has a false boolean value."
$terpri
"The basic conditionals:"
{ $subsection if }
{ $subsection when }
{ $subsection unless }
"A form encapsulating a common stack shuffle pattern:"
{ $subsection if* }
{ $subsection when* }
{ $subsection unless* }
"Another form encapsulating a common stack shuffle pattern:"
{ $subsection ?if }
"A form used when multiple conditional tests are to be performed:"
{ $subsection cond }
"Sometimes instead of executing one of two quotations, you just need to pick one of two values:"
{ $subsection ? }
"There are some logical operations on booleans:"
{ $subsection >boolean }
{ $subsection and }
{ $subsection or } ;
ARTICLE: "continuations" "Continuations"
"At any point in the execution of a program, the " { $emphasis "current continuation" } " represents the future of the computation. This object can be reified with the following two words:"
{ $subsection callcc0 }
{ $subsection callcc1 }
"Another two words resume continuations:"
{ $subsection continue }
{ $subsection continue-with }
"Continuations serve as the building block for a number of higher-level abstractions."
{ $subsection "errors" }
{ $subsection "threads" }
{ $subsection "continuations-internals" } ;
ARTICLE: "errors" "Error handling"
"Support for handling exceptional situations such as bad user input, implementation bugs, and input/output errors is provided by a set of words built using continuations."
$terpri
"Two words raise an error in the innermost error handler for the current dynamic extent:"
{ $subsection throw }
{ $subsection rethrow }
"A set of words establish an error handler:"
{ $subsection cleanup }
{ $subsection recover }
{ $subsection catch }
"Caught errors can be logged in human-readable form:"
{ $subsection error. }
2006-01-07 20:09:54 -05:00
{ $subsection try }
"Information relating to the most recently thrown error is stored in a pair of global variables:"
{ $subsection error }
{ $subsection error-continuation }
"Support for recoverable errors is built on top of the basic error handling facility. The following word signals a recoverable error:"
{ $subsection condition }
"Unhandled errors are reported in the listener and can be debugged using various tools. See " { $link "debugger" } "." ;
ARTICLE: "threads" "Multitasking"
"Continuations are used to implements co-operative multitasking, where the runtime switches between threads during I/O calls, and explicit yields."
{ $subsection in-thread }
{ $subsection yield }
{ $subsection sleep }
{ $subsection stop }
"Multitasking relies on a very simple round-robin scheduler:"
{ $subsection run-queue }
{ $subsection sleep-queue }
{ $subsection schedule-thread }
{ $subsection next-thread } ;
ARTICLE: "continuations-internals" "Continuation implementation details"
"A continuation is simply a tuple holding the contents of the four stacks:"
{ $subsection continuation }
"The five stacks can be read and written:"
{ $subsection datastack }
{ $subsection set-datastack }
{ $subsection retainstack }
{ $subsection set-retainstack }
{ $subsection callstack }
{ $subsection set-callstack }
{ $subsection namestack }
{ $subsection set-namestack }
{ $subsection catchstack }
{ $subsection set-catchstack } ;