Documentation fixes

db4
Slava Pestov 2008-03-29 23:11:45 -05:00
parent c22af5c7a6
commit 48501f1f6e
5 changed files with 322 additions and 54 deletions

View File

@ -10,18 +10,54 @@ ARTICLE: "combinators-quot" "Quotation construction utilities"
{ $subsection alist>quot } ;
ARTICLE: "combinators" "Additional combinators"
"The " { $vocab-link "combinators" } " vocabulary is usually used because it provides two combinators which abstract out nested chains of " { $link if } ":"
"The " { $vocab-link "combinators" } " vocabulary provides generalizations of certain combinators from the " { $vocab-link "kernel" } " vocabulary."
$nl
"Generalization of " { $link bi } " and " { $link tri } ":"
{ $subsection cleave }
"Generalization of " { $link bi* } " and " { $link tri* } ":"
{ $subsection spread }
"Two combinators which abstract out nested chains of " { $link if } ":"
{ $subsection cond }
{ $subsection case }
"The " { $vocab-link "combinators" } " also provides some less frequently-used features."
$nl
"A combinator which can help with implementing methods on " { $link hashcode* } ":"
{ $subsection recursive-hashcode }
"An oddball combinator:"
{ $subsection with-datastack }
{ $subsection "combinators-quot" }
{ $see-also "quotations" "basic-combinators" } ;
{ $see-also "quotations" "dataflow" } ;
ABOUT: "combinators"
HELP: cleave
{ $values { "x" object } { "seq" "a sequence of quotations with stack effect " { $snippet "( x -- ... )" } } }
{ $description "Applies each quotation to the object in turn." }
{ $examples
"The " { $link bi } " combinator takes one value and two quotations; the " { $link tri } " combinator takes one value and three quotations. The " { $link cleave } " combinator takes one value and any number of quotations, and is essentially equivalent to a chain of " { $link keep } " forms:"
{ $code
"! Equivalent"
"{ [ p ] [ q ] [ r ] [ s ] } cleave"
"[ p ] keep [ q ] keep [ r ] keep s"
}
} ;
{ bi tri cleave } related-words
HELP: spread
{ $values { "obj..." "objects" } { "seq" "a sequence of quotations with stack effect " { $snippet "( x -- ... )" } } }
{ $description "Applies each quotation to the object in turn." }
{ $examples
"The " { $link bi* } " combinator takes two values and two quotations; the " { $link tri* } " combinator takes three values and three quotations. The " { $link spread } " combinator takes " { $snippet "n" } " values and " { $snippet "n" } " quotations, where " { $snippet "n" } " is the length of the input sequence, and is essentially equivalent to series of retain stack manipulations:"
{ $code
"! Equivalent"
"{ [ p ] [ q ] [ r ] [ s ] } spread"
">r >r >r p r> q r> r r> s"
}
} ;
{ bi* tri* spread } related-words
HELP: alist>quot
{ $values { "default" "a quotation" } { "assoc" "a sequence of quotation pairs" } { "quot" "a new quotation" } }
{ $description "Constructs a quotation which calls the first quotation in each pair of " { $snippet "assoc" } " until one of them outputs a true value, and then calls the second quotation in the corresponding pair. Quotations are called in reverse order, and if no quotation outputs a true value then " { $snippet "default" } " is called." }

View File

@ -32,14 +32,28 @@ $nl
{ $code "H{ } clone" }
"To convert an assoc to a hashtable:"
{ $subsection >hashtable }
"Further topics:"
{ $subsection "hashtables.keys" }
{ $subsection "hashtables.utilities" }
{ $subsection "hashtables.private" } ;
ARTICLE: "hashtables.keys" "Hashtable keys"
"Hashtables rely on the " { $link hashcode } " word to rapidly locate values associated with keys. The objects used as keys in a hashtable must obey certain restrictions."
$nl
"The " { $link hashcode } " of a key is a function of the its slot values, and if the hashcode changes then the hashtable will be left in an inconsistent state. The easiest way to avoid this problem is to never mutate objects used as hashtable keys."
$nl
"In certain advanced applications, this cannot be avoided and the best design involves mutating hashtable keys. In this case, a custom " { $link hashcode* } " method must be defined which only depends on immutable slots."
$nl
"In addition, the " { $link equal? } " and " { $link hashcode* } " methods must be congruent, and if one is defined the other should be defined also. This is documented in detail in the documentation for these respective words." ;
ARTICLE: "hashtables.utilities" "Hashtable utilities"
"Utility words to create a new hashtable from a single key/value pair:"
{ $subsection associate }
{ $subsection ?set-at }
"The final two words pertain to sequences but use a hashtable internally. Removing duplicate elements from a sequence in linear time, using a hashtable:"
{ $subsection prune }
"Test if a sequence contains duplicates in linear time:"
{ $subsection all-unique? }
{ $subsection "hashtables.private" } ;
{ $subsection all-unique? } ;
ABOUT: "hashtables"

View File

@ -43,29 +43,86 @@ $nl
"An alternative to using " { $link >r } " and " { $link r> } " is the following:"
{ $subsection dip } ;
ARTICLE: "basic-combinators" "Basic combinators"
"The following pair of words invoke words and quotations reflectively:"
{ $subsection call }
{ $subsection execute }
"These words are used to implement " { $emphasis "combinators" } ", which are words that take code from the stack. Note that combinator definitions must be followed by the " { $link POSTPONE: inline } " declaration in order to compile in the optimizing compiler; for example:"
{ $code
": keep ( x quot -- x )"
" over >r call r> ; inline"
}
"Word inlining is documented in " { $link "declarations" } "."
ARTICLE: "cleave-combinators" "Cleave combinators"
"The cleave combinators apply multiple quotations to a single value."
$nl
"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 }
"Two quotations:"
{ $subsection bi }
{ $subsection 2bi }
"Three quotations:"
{ $subsection tri }
{ $subsection 2tri }
"Technically, the cleave combinators are redundant because they can be simulated using shuffle words and other combinators, and in addition, they do not reduce token counts by much, if at all. However, they can make code more readable by expressing intention and exploiting any inherent symmetry. For example, a piece of code which performs three operations on the top of the stack can be written in one of two ways:"
{ $code
"! First alternative; uses keep"
"[ 1 + ] keep"
"[ 1 - ] keep"
"2 *"
"! Second alternative: uses tri"
"[ 1 + ]"
"[ 1 - ]"
"[ 2 * ] tri"
}
"The latter is more aesthetically pleasing than the former."
$nl
"A generalization of the above combinators to any number of quotations can be found in " { $link "combinators" } "."
$nl
"From the Merriam-Webster Dictionary: "
$nl
{ $strong "cleave" }
{ $list
{ $emphasis "To divide by or as if by a cutting blow" }
{ $emphasis "To separate into distinct parts and especially into groups having divergent views" }
} ;
ARTICLE: "spread-combinators" "Spread combinators"
"The spread combinators apply multiple quotations to multiple values. The " { $snippet "*" } " suffix signifies spreading."
$nl
"Two quotations:"
{ $subsection bi* }
{ $subsection 2bi* }
"Three quotations:"
{ $subsection tri* }
"Technically, the spread combinators are redundant because they can be simulated using shuffle words and other combinators, and in addition, they do not reduce token counts by much, if at all. However, they can make code more readable by expressing intention and exploiting any inherent symmetry. For example, a piece of code which performs three operations on three related values can be written in one of two ways:"
{ $code
"! First alternative; uses retain stack explicitly"
">r >r 1 +"
"r> 1 -"
"r> 2 *"
"! Second alternative: uses tri*"
"[ 1 + ]"
"[ 1 - ]"
"[ 2 * ] tri*"
}
$nl
"A generalization of the above combinators to any number of quotations can be found in " { $link "combinators" } "." ;
ARTICLE: "apply-combinators" "Apply combinators"
"The apply combinators apply multiple quotations to multiple values. The " { $snippet "@" } " suffix signifies application."
$nl
"Two quotations:"
{ $subsection bi@ }
{ $subsection 2bi@ }
"Three quotations:"
{ $subsection tri@ }
"A pair of utility words built from " { $link bi@ } ":"
{ $subsection both? }
{ $subsection either? }
"A looping combinator:"
{ $subsection while }
{ $subsection either? } ;
ARTICLE: "slip-keep-combinators" "The slip and keep combinators"
"The slip combinators invoke a quotation further down on the stack. They are most useful for implementing other combinators:"
{ $subsection slip }
{ $subsection 2slip }
{ $subsection 3slip }
"The dip combinator invokes the quotation at the top of the stack, hiding the value underneath:"
{ $subsection dip }
"The keep combinators invoke a quotation which takes a number of values off the stack, and then they restore those values:"
{ $subsection keep }
{ $subsection 2keep }
{ $subsection 3keep } ;
ARTICLE: "compositional-combinators" "Compositional combinators"
"Quotations can be composed using efficient quotation-specific operations:"
{ $subsection curry }
{ $subsection 2curry }
@ -73,8 +130,21 @@ $nl
{ $subsection with }
{ $subsection compose }
{ $subsection 3compose }
"Quotations also implement the sequence protocol, and can be manipulated with sequence words; see " { $link "quotations" } "."
{ $see-also "combinators" } ;
"Quotations also implement the sequence protocol, and can be manipulated with sequence words; see " { $link "quotations" } "." ;
ARTICLE: "implementing-combinators" "Implementing combinators"
"The following pair of words invoke words and quotations reflectively:"
{ $subsection call }
{ $subsection execute }
"These words are used to implement combinators. Note that combinator definitions must be followed by the " { $link POSTPONE: inline } " declaration in order to compile in the optimizing compiler; for example:"
{ $code
": keep ( x quot -- x )"
" over >r call r> ; inline"
}
"Word inlining is documented in " { $link "declarations" } "."
$nl
"A looping combinator:"
{ $subsection while } ;
ARTICLE: "booleans" "Booleans"
"In Factor, any object that is not " { $link f } " has a true value, and " { $link f } " has a false value. The " { $link t } " object is the canonical true value."
@ -115,15 +185,13 @@ ARTICLE: "conditionals" "Conditionals and logic"
{ $subsection ?if }
"Sometimes instead of branching, you just need to pick one of two values:"
{ $subsection ? }
"Forms which abstract away common patterns involving multiple nested branches:"
{ $subsection cond }
{ $subsection case }
"There are some logical operations on booleans:"
{ $subsection >boolean }
{ $subsection not }
{ $subsection and }
{ $subsection or }
{ $subsection xor }
"See " { $link "combinators" } " for forms which abstract away common patterns involving multiple nested branches."
{ $see-also "booleans" "bitwise-arithmetic" both? either? } ;
ARTICLE: "equality" "Equality and comparison testing"
@ -146,7 +214,23 @@ $nl
"An object can be cloned; the clone has distinct identity but equal value:"
{ $subsection clone } ;
! Defined in handbook.factor
ARTICLE: "dataflow" "Data and control flow"
{ $subsection "evaluator" }
{ $subsection "words" }
{ $subsection "effects" }
{ $subsection "booleans" }
{ $subsection "shuffle-words" }
"A central concept in Factor is that of a " { $emphasis "combinator" } ", which is a word taking code as input."
{ $subsection "cleave-combinators" }
{ $subsection "spread-combinators" }
{ $subsection "apply-combinators" }
{ $subsection "slip-keep-combinators" }
{ $subsection "conditionals" }
{ $subsection "combinators" }
"Advanced topics:"
{ $subsection "implementing-combinators" }
{ $subsection "continuations" } ;
ABOUT: "dataflow"
HELP: eq? ( obj1 obj2 -- ? )
@ -242,6 +326,8 @@ HELP: equal?
{ { $snippet "a = b" } " implies " { $snippet "b = a" } }
{ { $snippet "a = b" } " and " { $snippet "b = c" } " implies " { $snippet "a = c" } }
}
$nl
"If a class defines a custom equality comparison test, it should also define a compatible method for the " { $link hashcode* } " generic word."
}
{ $examples
"To define a tuple class such that two instances are only equal if they are both the same instance, we can add a method to " { $link equal? } " which always returns " { $link f } ". Since " { $link = } " handles the case where the two objects are " { $link eq? } ", this method will never be called with two " { $link eq? } " objects, so such a definition is valid:"
@ -376,9 +462,152 @@ HELP: 3keep
{ $values { "quot" "a quotation with stack effect " { $snippet "( x y z -- )" } } { "x" object } { "y" object } { "z" object } }
{ $description "Call a quotation with three values on the stack, restoring the values when the quotation returns." } ;
HELP: bi
{ $values { "x" object } { "p" "a quotation with stack effect " { $snippet "( x -- ... )" } } { "q" "a quotation with stack effect " { $snippet "( x -- ... )" } } }
{ $description "Applies " { $snippet "p" } " to " { $snippet "x" } ", then applies " { $snippet "q" } " to " { $snippet "x" } "." }
{ $examples
"If " { $snippet "[ p ]" } " and " { $snippet "[ q ]" } " have stack effect " { $snippet "( x -- )" } ", then the following two lines are equivalent:"
{ $code
"[ p ] [ q ] bi"
"dup p q"
}
"If " { $snippet "[ p ]" } " and " { $snippet "[ q ]" } " have stack effect " { $snippet "( x -- y )" } ", then the following two lines are equivalent:"
{ $code
"[ p ] [ q ] bi"
"dup p swap q"
}
"In general, the following two lines are equivalent:"
{ $code
"[ p ] [ q ] bi"
"[ p ] keep q"
}
} ;
HELP: 2bi
{ $values { "x" object } { "y" object } { "p" "a quotation with stack effect " { $snippet "( x y -- ... )" } } { "q" "a quotation with stack effect " { $snippet "( x y -- ... )" } } }
{ $description "Applies " { $snippet "p" } " to the two input values, then applies " { $snippet "q" } " to the two input values." }
{ $examples
"If " { $snippet "[ p ]" } " and " { $snippet "[ q ]" } " have stack effect " { $snippet "( x y -- )" } ", then the following two lines are equivalent:"
{ $code
"[ p ] [ q ] 2bi"
"2dup p q"
}
"If " { $snippet "[ p ]" } " and " { $snippet "[ q ]" } " have stack effect " { $snippet "( x y -- z )" } ", then the following two lines are equivalent:"
{ $code
"[ p ] [ q ] 2bi"
"2dup p swap q"
}
"In general, the following two lines are equivalent:"
{ $code
"[ p ] [ q ] 2bi"
"[ p ] 2keep q"
}
} ;
HELP: tri
{ $values { "x" object } { "p" "a quotation with stack effect " { $snippet "( x -- ... )" } } { "q" "a quotation with stack effect " { $snippet "( x -- ... )" } } { "r" "a quotation with stack effect " { $snippet "( x -- ... )" } } }
{ $description "Applies " { $snippet "p" } " to " { $snippet "x" } ", then applies " { $snippet "q" } " to " { $snippet "x" } ", and finally applies " { $snippet "r" } " to " { $snippet "x" } "." }
{ $examples
"If " { $snippet "[ p ]" } ", " { $snippet "[ q ]" } " and " { $snippet "[ r ]" } " have stack effect " { $snippet "( x -- )" } ", then the following two lines are equivalent:"
{ $code
"[ p ] [ q ] [ r ] tri"
"dup p dup q r"
}
"If " { $snippet "[ p ]" } ", " { $snippet "[ q ]" } " and " { $snippet "[ r ]" } " have stack effect " { $snippet "( x -- y )" } ", then the following two lines are equivalent:"
{ $code
"[ p ] [ q ] [ r ] tri"
"dup p over q rot r"
}
"In general, the following two lines are equivalent:"
{ $code
"[ p ] [ q ] [ r ] tri"
"[ p ] keep [ q ] keep r"
}
} ;
HELP: 2tri
{ $values { "x" object } { "y" object } { "p" "a quotation with stack effect " { $snippet "( x y -- ... )" } } { "q" "a quotation with stack effect " { $snippet "( x y -- ... )" } } { "r" "a quotation with stack effect " { $snippet "( x y -- ... )" } } }
{ $description "Applies " { $snippet "p" } " to the two input values, then applies " { $snippet "q" } " to the two input values, and finally applies " { $snippet "r" } " to the two input values." }
{ $examples
"If " { $snippet "[ p ]" } ", " { $snippet "[ q ]" } " and " { $snippet "[ r ]" } " have stack effect " { $snippet "( x y -- )" } ", then the following two lines are equivalent:"
{ $code
"[ p ] [ q ] [ r ] 2tri"
"2dup p 2dup q r"
}
"In general, the following two lines are equivalent:"
{ $code
"[ p ] [ q ] [ r ] 2tri"
"[ p ] 2keep [ q ] 2keep r"
}
} ;
HELP: bi*
{ $values { "x" object } { "y" object } { "p" "a quotation with stack effect " { $snippet "( x -- ... )" } } { "q" "a quotation with stack effect " { $snippet "( y -- ... )" } } }
{ $description "Applies " { $snippet "p" } " to " { $snippet "x" } ", then applies " { $snippet "q" } " to " { $snippet "y" } "." }
{ $examples
"The following two lines are equivalent:"
{ $code
"[ p ] [ q ] bi*"
">r p r> q"
}
} ;
HELP: 2bi*
{ $values { "w" object } { "x" object } { "y" object } { "z" object } { "p" "a quotation with stack effect " { $snippet "( w x -- ... )" } } { "q" "a quotation with stack effect " { $snippet "( y z -- ... )" } } }
{ $description "Applies " { $snippet "p" } " to " { $snippet "w" } " and " { $snippet "x" } ", then applies " { $snippet "q" } " to " { $snippet "y" } " and " { $snippet "z" } "." }
{ $examples
"The following two lines are equivalent:"
{ $code
"[ p ] [ q ] 2bi*"
">r >r q r> r> q"
}
} ;
HELP: tri*
{ $values { "x" object } { "y" object } { "z" object } { "p" "a quotation with stack effect " { $snippet "( x -- ... )" } } { "q" "a quotation with stack effect " { $snippet "( y -- ... )" } } { "r" "a quotation with stack effect " { $snippet "( z -- ... )" } } }
{ $description "Applies " { $snippet "p" } " to " { $snippet "x" } ", then applies " { $snippet "q" } " to " { $snippet "y" } ", and finally applies " { $snippet "r" } " to " { $snippet "z" } "." }
{ $examples
"The following two lines are equivalent:"
{ $code
"[ p ] [ q ] [ r ] tri*"
">r >r q r> q r> r"
}
} ;
HELP: bi@
{ $values { "quot" "a quotation with stack effect " { $snippet "( obj -- )" } } { "x" object } { "y" object } }
{ $description "Applies the quotation to " { $snippet "x" } ", then to " { $snippet "y" } "." } ;
{ $values { "x" object } { "y" object } { "quot" "a quotation with stack effect " { $snippet "( obj -- )" } } }
{ $description "Applies the quotation to " { $snippet "x" } ", then to " { $snippet "y" } "." }
{ $examples
"The following two lines are equivalent:"
{ $code
"[ p ] bi@"
">r p r> p"
}
} ;
HELP: 2bi@
{ $values { "w" object } { "x" object } { "y" object } { "z" object } { "quot" "a quotation with stack effect " { $snippet "( obj1 obj2 -- )" } } }
{ $description "Applies the quotation to " { $snippet "w" } " and " { $snippet "x" } ", then to " { $snippet "y" } " and " { $snippet "z" } "." }
{ $examples
"The following two lines are equivalent:"
{ $code
"[ p ] 2bi@"
">r >r p r> r> p"
}
} ;
HELP: tri@
{ $values { "x" object } { "y" object } { "z" object } { "quot" "a quotation with stack effect " { $snippet "( obj -- )" } } }
{ $description "Applies the quotation to " { $snippet "x" } ", then to " { $snippet "y" } ", and finally to " { $snippet "z" } "." }
{ $examples
"The following two lines are equivalent:"
{ $code
"[ p ] tri@"
">r >r p r> p r> p"
}
} ;
HELP: if ( cond true false -- )
{ $values { "cond" "a generalized boolean" } { "true" quotation } { "false" quotation } }

View File

@ -66,46 +66,46 @@ DEFER: if
>r 3dup r> -roll 3slip ; inline
! Cleavers
: bi ( x p q -- p[x] q[x] )
: bi ( x p q -- )
>r keep r> call ; inline
: tri ( x p q r -- p[x] q[x] r[x] )
: tri ( x p q r -- )
>r pick >r bi r> r> call ; inline
! Double cleavers
: 2bi ( x y p q -- p[x,y] q[x,y] )
: 2bi ( x y p q -- )
>r 2keep r> call ; inline
: 2tri ( x y p q r -- p[x,y] q[x,y] r[x,y] )
: 2tri ( x y p q r -- )
>r >r 2keep r> 2keep r> call ; inline
! Triple cleavers
: 3bi ( x y z p q -- p[x,y,z] q[x,y,z] )
: 3bi ( x y z p q -- )
>r 3keep r> call ; inline
: 3tri ( x y z p q r -- p[x,y,z] q[x,y,z] r[x,y,z] )
: 3tri ( x y z p q r -- )
>r >r 3keep r> 3keep r> call ; inline
! Spreaders
: bi* ( x y p q -- p[x] q[y] )
: bi* ( x y p q -- )
>r swap slip r> call ; inline
: tri* ( x y z p q r -- p[x] q[y] r[z] )
: tri* ( x y z p q r -- )
>r rot >r bi* r> r> call ; inline
! Double spreaders
: 2bi* ( w x y z p q -- p[w,x] q[y,z] )
: 2bi* ( w x y z p q -- )
>r -rot 2slip r> call ; inline
! Appliers
: bi@ ( x y p -- p[x] p[y] )
: bi@ ( x y p -- )
tuck 2slip call ; inline
: tri@ ( x y z p -- p[x] p[y] p[z] )
: tri@ ( x y z p -- )
tuck >r bi@ r> call ; inline
! Double appliers
: 2bi@ ( w x y z p -- p[w,x] p[y,z] )
: 2bi@ ( w x y z p -- )
dup -roll 3slip call ; inline
: while ( pred body tail -- )

View File

@ -68,17 +68,6 @@ ARTICLE: "evaluator" "Evaluation semantics"
"If the last action performed is the execution of a word, the current quotation is not saved on the call stack; this is known as " { $snippet "tail-recursion" } " and allows iterative algorithms to execute without incurring unbounded call stack usage."
{ $see-also "compiler" } ;
ARTICLE: "dataflow" "Data and control flow"
{ $subsection "evaluator" }
{ $subsection "words" }
{ $subsection "effects" }
{ $subsection "shuffle-words" }
{ $subsection "booleans" }
{ $subsection "conditionals" }
{ $subsection "basic-combinators" }
{ $subsection "combinators" }
{ $subsection "continuations" } ;
USING: concurrency.combinators
concurrency.messaging
concurrency.promises