"A variable is an entry in an assoc of bindings, where the assoc is implicit rather than passed on the stack. These assocs are termed " { $emphasis "namespaces" } ". Nesting of scopes is implemented with a search order on namespaces, defined by a " { $emphasis "namestack" } ". Since namespaces are just assoc, any object can be used as a variable, however by convention, variables are keyed by symbols (see " { $link "symbols" } ")."
$nl
"The " { $link get } " and " { $link set } " words read and write variable values. The " { $link get } " word searches up the chain of nested namespaces, while " { $link set } " always sets variable values in the current namespace only. Namespaces are dynamically scoped; when a quotation is called from a nested scope, any words called by the quotation also execute in that scope."
{ $subsection get }
{ $subsection set }
"Various utility words abstract away common variable access patterns:"
{ $subsection "namespaces-change" }
{ $subsection "namespaces-combinators" }
{ $subsection "namespaces-global" }
"Implementation details your code probably does not care about:"
{ $subsection "namespaces.private" }
"An alternative to dynamic scope is lexical scope. Lexically-scoped values and closures are implemented in the " { $vocab-link "locals" } " vocabulary.";
ABOUT: "namespaces"
HELP:get
{ $values { "variable""a variable, by convention a symbol" } { "value""the value, or " { $link f } } }
{ $description "Searches the name stack for a namespace containing the variable, and outputs the associated value. If no such namespace is found, outputs " { $link f } "." } ;
HELP:set
{ $values { "value""the new value" } { "variable""a variable, by convention a symbol" } }
{ $description "Assigns a value to the variable in the namespace at the top of the name stack." }
{ $side-effects "variable" } ;
HELP:off
{ $values { "variable""a variable, by convention a symbol" } }
{ $description "Assigns a value of " { $link f } " to the variable." }
{ $side-effects "variable" } ;
HELP:on
{ $values { "variable""a variable, by convention a symbol" } }
{ $description "Assigns a value of " { $link t } " to the variable." }
{ $side-effects "variable" } ;
HELP:change
{ $values { "variable""a variable, by convention a symbol" } { "quot""a quotation with stack effect " { $snippet "( old -- new )" } } }
{ $description "Applies the quotation to the old value of the variable, and assigns the resulting value to the variable." }
{ $side-effects "variable" } ;
HELP:+@
{ $values { "n""a number" } { "variable""a variable, by convention a symbol" } }
{ $description "Adds " { $snippet "n" } " to the value of the variable. A variable value of " { $link f } " is interpreted as being zero." }
{ $description "Calls the quotation in a new namespace of the same type as " { $snippet "exemplar" } ", and outputs this namespace when the quotation returns. Useful for quickly building assocs." } ;
{ $description "Calls the quotation in the dynamic scope of " { $snippet "ns" } ". When variables are looked up by the quotation, " { $snippet "ns" } " is checked first, and setting variables in the quotation stores them in " { $snippet "ns" } "." } ;
HELP:namespace
{ $values { "namespace""an assoc" } }
{ $description "Outputs the current namespace. Calls to " { $link set } " modify this namespace." } ;
HELP:global
{ $values { "g""an assoc" } }
{ $description "Outputs the global namespace. The global namespace is always checked last when looking up variable values." } ;
HELP:get-global
{ $values { "variable""a variable, by convention a symbol" } { "value""the value" } }
{ $description "Outputs the value of a variable in the global namespace." } ;
HELP:set-global
{ $values { "value""the new value" } { "variable""a variable, by convention a symbol" } }
{ $description "Assigns a value to the variable in the global namespace." }
{ $side-effects "variable" } ;
HELP:namestack*
{ $values { "namestack""a vector of assocs" } }
{ $description "Outputs the current name stack." } ;
HELP:namestack
{ $values { "namestack""a vector of assocs" } }
{ $description "Outputs a copy of the current name stack." } ;
HELP:set-namestack
{ $values { "namestack""a vector of assocs" } }
{ $description "Replaces the name stack with a copy of the given vector." } ;
HELP:>n
{ $values { "namespace""an assoc" } }
{ $description "Pushes a namespace on the name stack." } ;
HELP:ndrop
{ $description "Pops a namespace from the name stack." } ;