docs: updated some docs to use new markup
parent
d552ce8ef6
commit
bea4aa7662
|
@ -3,17 +3,13 @@ IN: grouping
|
||||||
|
|
||||||
ARTICLE: "grouping" "Groups and clumps"
|
ARTICLE: "grouping" "Groups and clumps"
|
||||||
"Splitting a sequence into disjoint, fixed-length subsequences:"
|
"Splitting a sequence into disjoint, fixed-length subsequences:"
|
||||||
{ $subsection group }
|
{ $subsections group }
|
||||||
"A virtual sequence for splitting a sequence into disjoint, fixed-length subsequences:"
|
"A virtual sequence for splitting a sequence into disjoint, fixed-length subsequences:"
|
||||||
{ $subsection groups }
|
{ $subsections groups <groups> <sliced-groups> }
|
||||||
{ $subsection <groups> }
|
|
||||||
{ $subsection <sliced-groups> }
|
|
||||||
"Splitting a sequence into overlapping, fixed-length subsequences:"
|
"Splitting a sequence into overlapping, fixed-length subsequences:"
|
||||||
{ $subsection clump }
|
{ $subsections clump }
|
||||||
"A virtual sequence for splitting a sequence into overlapping, fixed-length subsequences:"
|
"A virtual sequence for splitting a sequence into overlapping, fixed-length subsequences:"
|
||||||
{ $subsection clumps }
|
{ $subsections clumps <clumps> <sliced-clumps> }
|
||||||
{ $subsection <clumps> }
|
|
||||||
{ $subsection <sliced-clumps> }
|
|
||||||
"The difference can be summarized as the following:"
|
"The difference can be summarized as the following:"
|
||||||
{ $list
|
{ $list
|
||||||
{ "With groups, the subsequences form the original sequence when concatenated:"
|
{ "With groups, the subsequences form the original sequence when concatenated:"
|
||||||
|
@ -29,11 +25,11 @@ ARTICLE: "grouping" "Groups and clumps"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$nl
|
||||||
"A combinator built using clumps:"
|
"A combinator built using clumps:"
|
||||||
{ $subsection monotonic? }
|
{ $subsections monotonic? }
|
||||||
"Testing how elements are related:"
|
"Testing how elements are related:"
|
||||||
{ $subsection all-eq? }
|
{ $subsections all-eq? all-equal? } ;
|
||||||
{ $subsection all-equal? } ;
|
|
||||||
|
|
||||||
ABOUT: "grouping"
|
ABOUT: "grouping"
|
||||||
|
|
||||||
|
|
|
@ -3,102 +3,95 @@ sequences quotations math.functions.private ;
|
||||||
IN: math.functions
|
IN: math.functions
|
||||||
|
|
||||||
ARTICLE: "integer-functions" "Integer functions"
|
ARTICLE: "integer-functions" "Integer functions"
|
||||||
{ $subsection align }
|
{ $subsections
|
||||||
{ $subsection gcd }
|
align
|
||||||
{ $subsection log2 }
|
gcd
|
||||||
{ $subsection next-power-of-2 }
|
log2
|
||||||
|
next-power-of-2
|
||||||
|
}
|
||||||
"Modular exponentiation:"
|
"Modular exponentiation:"
|
||||||
{ $subsection ^mod }
|
{ $subsections ^mod mod-inv }
|
||||||
{ $subsection mod-inv }
|
|
||||||
"Tests:"
|
"Tests:"
|
||||||
{ $subsection power-of-2? }
|
{ $subsections
|
||||||
{ $subsection even? }
|
power-of-2?
|
||||||
{ $subsection odd? }
|
even?
|
||||||
{ $subsection divisor? } ;
|
odd?
|
||||||
|
divisor?
|
||||||
|
} ;
|
||||||
|
|
||||||
ARTICLE: "arithmetic-functions" "Arithmetic functions"
|
ARTICLE: "arithmetic-functions" "Arithmetic functions"
|
||||||
"Computing additive and multiplicative inverses:"
|
"Computing additive and multiplicative inverses:"
|
||||||
{ $subsection neg }
|
{ $subsections neg recip }
|
||||||
{ $subsection recip }
|
|
||||||
"Complex conjugation:"
|
"Complex conjugation:"
|
||||||
{ $subsection conjugate }
|
{ $subsections conjugate }
|
||||||
"Tests:"
|
"Tests:"
|
||||||
{ $subsection zero? }
|
{ $subsections zero? between? }
|
||||||
{ $subsection between? }
|
|
||||||
"Control flow:"
|
"Control flow:"
|
||||||
{ $subsection if-zero }
|
{ $subsections
|
||||||
{ $subsection when-zero }
|
if-zero
|
||||||
{ $subsection unless-zero }
|
when-zero
|
||||||
|
unless-zero
|
||||||
|
}
|
||||||
"Sign:"
|
"Sign:"
|
||||||
{ $subsection sgn }
|
{ $subsections sgn }
|
||||||
"Rounding:"
|
"Rounding:"
|
||||||
{ $subsection ceiling }
|
{ $subsections
|
||||||
{ $subsection floor }
|
ceiling
|
||||||
{ $subsection truncate }
|
floor
|
||||||
{ $subsection round }
|
truncate
|
||||||
|
round
|
||||||
|
}
|
||||||
"Inexact comparison:"
|
"Inexact comparison:"
|
||||||
{ $subsection ~ }
|
{ $subsections ~ }
|
||||||
"Numbers implement the " { $link "math.order" } ", therefore operations such as " { $link min } " and " { $link max } " can be used with numbers." ;
|
"Numbers implement the " { $link "math.order" } ", therefore operations such as " { $link min } " and " { $link max } " can be used with numbers." ;
|
||||||
|
|
||||||
ARTICLE: "power-functions" "Powers and logarithms"
|
ARTICLE: "power-functions" "Powers and logarithms"
|
||||||
"Squares:"
|
"Squares:"
|
||||||
{ $subsection sq }
|
{ $subsections sq sqrt }
|
||||||
{ $subsection sqrt }
|
|
||||||
"Exponential and natural logarithm:"
|
"Exponential and natural logarithm:"
|
||||||
{ $subsection exp }
|
{ $subsections
|
||||||
{ $subsection cis }
|
exp
|
||||||
{ $subsection log }
|
cis
|
||||||
{ $subsection log1+ }
|
log
|
||||||
{ $subsection log10 }
|
log1+
|
||||||
|
log10
|
||||||
|
}
|
||||||
"Raising a number to a power:"
|
"Raising a number to a power:"
|
||||||
{ $subsection ^ }
|
{ $subsections ^ 10^ }
|
||||||
{ $subsection 10^ }
|
|
||||||
"Converting between rectangular and polar form:"
|
"Converting between rectangular and polar form:"
|
||||||
{ $subsection abs }
|
{ $subsections
|
||||||
{ $subsection absq }
|
abs
|
||||||
{ $subsection arg }
|
absq
|
||||||
{ $subsection >polar }
|
arg
|
||||||
{ $subsection polar> } ;
|
>polar
|
||||||
|
polar>
|
||||||
|
} ;
|
||||||
|
|
||||||
ARTICLE: "trig-hyp-functions" "Trigonometric and hyperbolic functions"
|
ARTICLE: "trig-hyp-functions" "Trigonometric and hyperbolic functions"
|
||||||
"Trigonometric functions:"
|
"Trigonometric functions:"
|
||||||
{ $subsection cos }
|
{ $subsections cos sin tan }
|
||||||
{ $subsection sin }
|
|
||||||
{ $subsection tan }
|
|
||||||
"Reciprocals:"
|
"Reciprocals:"
|
||||||
{ $subsection sec }
|
{ $subsections sec cosec cot }
|
||||||
{ $subsection cosec }
|
|
||||||
{ $subsection cot }
|
|
||||||
"Inverses:"
|
"Inverses:"
|
||||||
{ $subsection acos }
|
{ $subsections acos asin atan }
|
||||||
{ $subsection asin }
|
|
||||||
{ $subsection atan }
|
|
||||||
"Inverse reciprocals:"
|
"Inverse reciprocals:"
|
||||||
{ $subsection asec }
|
{ $subsections asec acosec acot }
|
||||||
{ $subsection acosec }
|
|
||||||
{ $subsection acot }
|
|
||||||
"Hyperbolic functions:"
|
"Hyperbolic functions:"
|
||||||
{ $subsection cosh }
|
{ $subsections cosh sinh tanh }
|
||||||
{ $subsection sinh }
|
|
||||||
{ $subsection tanh }
|
|
||||||
"Reciprocals:"
|
"Reciprocals:"
|
||||||
{ $subsection sech }
|
{ $subsections sech cosech coth }
|
||||||
{ $subsection cosech }
|
|
||||||
{ $subsection coth }
|
|
||||||
"Inverses:"
|
"Inverses:"
|
||||||
{ $subsection acosh }
|
{ $subsections acosh asinh atanh }
|
||||||
{ $subsection asinh }
|
|
||||||
{ $subsection atanh }
|
|
||||||
"Inverse reciprocals:"
|
"Inverse reciprocals:"
|
||||||
{ $subsection asech }
|
{ $subsections asech acosech acoth } ;
|
||||||
{ $subsection acosech }
|
|
||||||
{ $subsection acoth } ;
|
|
||||||
|
|
||||||
ARTICLE: "math-functions" "Mathematical functions"
|
ARTICLE: "math-functions" "Mathematical functions"
|
||||||
{ $subsection "integer-functions" }
|
{ $subsections
|
||||||
{ $subsection "arithmetic-functions" }
|
"integer-functions"
|
||||||
{ $subsection "power-functions" }
|
"arithmetic-functions"
|
||||||
{ $subsection "trig-hyp-functions" } ;
|
"power-functions"
|
||||||
|
"trig-hyp-functions"
|
||||||
|
} ;
|
||||||
|
|
||||||
ABOUT: "math-functions"
|
ABOUT: "math-functions"
|
||||||
|
|
||||||
|
|
|
@ -18,20 +18,21 @@ ARTICLE: "regexp.combinators.intro" "Regular expression combinator rationale"
|
||||||
|
|
||||||
ARTICLE: "regexp.combinators" "Regular expression combinators"
|
ARTICLE: "regexp.combinators" "Regular expression combinators"
|
||||||
"The " { $vocab-link "regexp.combinators" } " vocabulary defines combinators which can be used to build up regular expressions to match strings. This complements the traditional syntax defined in the " { $vocab-link "regexp" } " vocabulary."
|
"The " { $vocab-link "regexp.combinators" } " vocabulary defines combinators which can be used to build up regular expressions to match strings. This complements the traditional syntax defined in the " { $vocab-link "regexp" } " vocabulary."
|
||||||
{ $subsection "regexp.combinators.intro" }
|
{ $subsections "regexp.combinators.intro" }
|
||||||
"Basic combinators:"
|
"Basic combinators:"
|
||||||
{ $subsection <literal> }
|
{ $subsections <literal> <nothing> }
|
||||||
{ $subsection <nothing> }
|
|
||||||
"Higher-order combinators for building new regular expressions from existing ones:"
|
"Higher-order combinators for building new regular expressions from existing ones:"
|
||||||
{ $subsection <or> }
|
{ $subsections
|
||||||
{ $subsection <and> }
|
<or>
|
||||||
{ $subsection <not> }
|
<and>
|
||||||
{ $subsection <sequence> }
|
<not>
|
||||||
{ $subsection <zero-or-more> }
|
<sequence>
|
||||||
|
<zero-or-more>
|
||||||
|
}
|
||||||
"Derived combinators implemented in terms of the above:"
|
"Derived combinators implemented in terms of the above:"
|
||||||
{ $subsection <one-or-more> }
|
{ $subsections <one-or-more> }
|
||||||
"Setting options:"
|
"Setting options:"
|
||||||
{ $subsection <option> } ;
|
{ $subsections <option> } ;
|
||||||
|
|
||||||
HELP: <literal>
|
HELP: <literal>
|
||||||
{ $values { "string" string } { "regexp" regexp } }
|
{ $values { "string" string } { "regexp" regexp } }
|
||||||
|
|
|
@ -8,18 +8,22 @@ ABOUT: "regexp"
|
||||||
|
|
||||||
ARTICLE: "regexp" "Regular expressions"
|
ARTICLE: "regexp" "Regular expressions"
|
||||||
"The " { $vocab-link "regexp" } " vocabulary provides word for creating and using regular expressions."
|
"The " { $vocab-link "regexp" } " vocabulary provides word for creating and using regular expressions."
|
||||||
{ $subsection { "regexp" "intro" } }
|
{ $subsections { "regexp" "intro" } }
|
||||||
"The class of regular expressions:"
|
"The class of regular expressions:"
|
||||||
{ $subsection regexp }
|
{ $subsections regexp }
|
||||||
"Basic usage:"
|
"Basic usage:"
|
||||||
{ $subsection { "regexp" "syntax" } }
|
{ $subsections
|
||||||
{ $subsection { "regexp" "options" } }
|
{ "regexp" "syntax" }
|
||||||
{ $subsection { "regexp" "construction" } }
|
{ "regexp" "options" }
|
||||||
{ $subsection { "regexp" "operations" } }
|
{ "regexp" "construction" }
|
||||||
|
{ "regexp" "operations" }
|
||||||
|
}
|
||||||
"Advanced topics:"
|
"Advanced topics:"
|
||||||
{ $vocab-subsection "Regular expression combinators" "regexp.combinators" }
|
{ $vocab-subsection "Regular expression combinators" "regexp.combinators" }
|
||||||
{ $subsection { "regexp" "theory" } }
|
{ $subsections
|
||||||
{ $subsection { "regexp" "deploy" } } ;
|
{ "regexp" "theory" }
|
||||||
|
{ "regexp" "deploy" }
|
||||||
|
} ;
|
||||||
|
|
||||||
ARTICLE: { "regexp" "intro" } "A quick introduction to regular expressions"
|
ARTICLE: { "regexp" "intro" } "A quick introduction to regular expressions"
|
||||||
"Regular expressions are a terse way to do certain simple string processing tasks. For example, to replace all instances of " { $snippet "foo" } " in one string with " { $snippet "bar" } ", the following can be used:"
|
"Regular expressions are a terse way to do certain simple string processing tasks. For example, to replace all instances of " { $snippet "foo" } " in one string with " { $snippet "bar" } ", the following can be used:"
|
||||||
|
@ -36,10 +40,9 @@ ARTICLE: { "regexp" "intro" } "A quick introduction to regular expressions"
|
||||||
|
|
||||||
ARTICLE: { "regexp" "construction" } "Constructing regular expressions"
|
ARTICLE: { "regexp" "construction" } "Constructing regular expressions"
|
||||||
"Most of the time, regular expressions are literals and the parsing word should be used, to construct them at parse time. This ensures that they are only compiled once, and gives parse time syntax checking."
|
"Most of the time, regular expressions are literals and the parsing word should be used, to construct them at parse time. This ensures that they are only compiled once, and gives parse time syntax checking."
|
||||||
{ $subsection POSTPONE: R/ }
|
{ $subsections POSTPONE: R/ }
|
||||||
"Sometimes, regular expressions need to be constructed at run time instead; for example, in a text editor, the user might input a regular expression to search for in a document."
|
"Sometimes, regular expressions need to be constructed at run time instead; for example, in a text editor, the user might input a regular expression to search for in a document."
|
||||||
{ $subsection <regexp> }
|
{ $subsections <regexp> <optioned-regexp> }
|
||||||
{ $subsection <optioned-regexp> }
|
|
||||||
"Another approach is to use " { $vocab-link "regexp.combinators" } "." ;
|
"Another approach is to use " { $vocab-link "regexp.combinators" } "." ;
|
||||||
|
|
||||||
ARTICLE: { "regexp" "syntax" } "Regular expression syntax"
|
ARTICLE: { "regexp" "syntax" } "Regular expression syntax"
|
||||||
|
@ -167,18 +170,19 @@ ARTICLE: { "regexp" "theory" } "The theory of regular expressions"
|
||||||
|
|
||||||
ARTICLE: { "regexp" "operations" } "Matching operations with regular expressions"
|
ARTICLE: { "regexp" "operations" } "Matching operations with regular expressions"
|
||||||
"Testing if a string matches a regular expression:"
|
"Testing if a string matches a regular expression:"
|
||||||
{ $subsection matches? }
|
{ $subsections matches? }
|
||||||
"Finding a match inside a string:"
|
"Finding a match inside a string:"
|
||||||
{ $subsection re-contains? }
|
{ $subsections re-contains? first-match }
|
||||||
{ $subsection first-match }
|
|
||||||
"Finding all matches inside a string:"
|
"Finding all matches inside a string:"
|
||||||
{ $subsection count-matches }
|
{ $subsections
|
||||||
{ $subsection all-matching-slices }
|
count-matches
|
||||||
{ $subsection all-matching-subseqs }
|
all-matching-slices
|
||||||
|
all-matching-subseqs
|
||||||
|
}
|
||||||
"Splitting a string into tokens delimited by a regular expression:"
|
"Splitting a string into tokens delimited by a regular expression:"
|
||||||
{ $subsection re-split }
|
{ $subsections re-split }
|
||||||
"Replacing occurrences of a regular expression with a string:"
|
"Replacing occurrences of a regular expression with a string:"
|
||||||
{ $subsection re-replace } ;
|
{ $subsections re-replace } ;
|
||||||
|
|
||||||
ARTICLE: { "regexp" "deploy" } "Regular expressions and the deploy tool"
|
ARTICLE: { "regexp" "deploy" } "Regular expressions and the deploy tool"
|
||||||
"The " { $link "tools.deploy" } " tool has the option to strip out the optimizing compiler from the resulting image. Since regular expressions compile to Factor code, this creates a minor performance-related caveat."
|
"The " { $link "tools.deploy" } " tool has the option to strip out the optimizing compiler from the resulting image. Since regular expressions compile to Factor code, this creates a minor performance-related caveat."
|
||||||
|
|
|
@ -29,17 +29,12 @@ ARTICLE: "cleave-combinators" "Cleave combinators"
|
||||||
"The cleave combinators apply multiple quotations to a single value."
|
"The cleave combinators apply multiple quotations to a single value."
|
||||||
$nl
|
$nl
|
||||||
"Two quotations:"
|
"Two quotations:"
|
||||||
{ $subsection bi }
|
{ $subsections bi 2bi 3bi }
|
||||||
{ $subsection 2bi }
|
|
||||||
{ $subsection 3bi }
|
|
||||||
"Three quotations:"
|
"Three quotations:"
|
||||||
{ $subsection tri }
|
{ $subsections tri 2tri 3tri }
|
||||||
{ $subsection 2tri }
|
|
||||||
{ $subsection 3tri }
|
|
||||||
"An array of quotations:"
|
"An array of quotations:"
|
||||||
{ $subsection cleave }
|
{ $subsection cleave 2cleave 3cleave }
|
||||||
{ $subsection 2cleave }
|
$nl
|
||||||
{ $subsection 3cleave }
|
|
||||||
"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:"
|
"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
|
{ $code
|
||||||
"! First alternative; uses keep"
|
"! First alternative; uses keep"
|
||||||
|
@ -52,6 +47,7 @@ $nl
|
||||||
"[ 2 * ] tri"
|
"[ 2 * ] tri"
|
||||||
}
|
}
|
||||||
"The latter is more aesthetically pleasing than the former."
|
"The latter is more aesthetically pleasing than the former."
|
||||||
|
$nl
|
||||||
{ $subsection "cleave-shuffle-equivalence" } ;
|
{ $subsection "cleave-shuffle-equivalence" } ;
|
||||||
|
|
||||||
ARTICLE: "spread-shuffle-equivalence" "Expressing shuffle words with spread combinators"
|
ARTICLE: "spread-shuffle-equivalence" "Expressing shuffle words with spread combinators"
|
||||||
|
@ -88,13 +84,11 @@ ARTICLE: "spread-combinators" "Spread combinators"
|
||||||
"The spread combinators apply multiple quotations to multiple values. The " { $snippet "*" } " suffix signifies spreading."
|
"The spread combinators apply multiple quotations to multiple values. The " { $snippet "*" } " suffix signifies spreading."
|
||||||
$nl
|
$nl
|
||||||
"Two quotations:"
|
"Two quotations:"
|
||||||
{ $subsection bi* }
|
{ $subsections bi* 2bi* }
|
||||||
{ $subsection 2bi* }
|
|
||||||
"Three quotations:"
|
"Three quotations:"
|
||||||
{ $subsection tri* }
|
{ $subsections tri* 2tri* }
|
||||||
{ $subsection 2tri* }
|
|
||||||
"An array of quotations:"
|
"An array of quotations:"
|
||||||
{ $subsection spread }
|
{ $subsections spread }
|
||||||
"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:"
|
"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
|
{ $code
|
||||||
"! First alternative; uses dip"
|
"! First alternative; uses dip"
|
||||||
|
@ -103,44 +97,34 @@ $nl
|
||||||
"[ 1 + ] [ 1 - ] [ 2 * ] tri*"
|
"[ 1 + ] [ 1 - ] [ 2 * ] tri*"
|
||||||
}
|
}
|
||||||
"A generalization of the above combinators to any number of quotations can be found in " { $link "combinators" } "."
|
"A generalization of the above combinators to any number of quotations can be found in " { $link "combinators" } "."
|
||||||
|
$nl
|
||||||
{ $subsection "spread-shuffle-equivalence" } ;
|
{ $subsection "spread-shuffle-equivalence" } ;
|
||||||
|
|
||||||
ARTICLE: "apply-combinators" "Apply combinators"
|
ARTICLE: "apply-combinators" "Apply combinators"
|
||||||
"The apply combinators apply a single quotation to multiple values. The " { $snippet "@" } " suffix signifies application."
|
"The apply combinators apply a single quotation to multiple values. The " { $snippet "@" } " suffix signifies application."
|
||||||
$nl
|
$nl
|
||||||
"Two quotations:"
|
"Two quotations:"
|
||||||
{ $subsection bi@ }
|
{ $subsections bi@ 2bi@ }
|
||||||
{ $subsection 2bi@ }
|
|
||||||
"Three quotations:"
|
"Three quotations:"
|
||||||
{ $subsection tri@ }
|
{ $subsections tri@ 2tri@ }
|
||||||
{ $subsection 2tri@ }
|
|
||||||
"A pair of utility words built from " { $link bi@ } ":"
|
"A pair of utility words built from " { $link bi@ } ":"
|
||||||
{ $subsection both? }
|
{ $subsections both? either? } ;
|
||||||
{ $subsection either? } ;
|
|
||||||
|
|
||||||
ARTICLE: "retainstack-combinators" "Retain stack combinators"
|
ARTICLE: "retainstack-combinators" "Retain stack combinators"
|
||||||
"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 a set of combinators."
|
"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 a set of combinators."
|
||||||
$nl
|
$nl
|
||||||
"The dip combinators invoke the quotation at the top of the stack, hiding the values underneath:"
|
"The dip combinators invoke the quotation at the top of the stack, hiding the values underneath:"
|
||||||
{ $subsection dip }
|
{ $subsections dip 2dip 3dip 4dip }
|
||||||
{ $subsection 2dip }
|
|
||||||
{ $subsection 3dip }
|
|
||||||
{ $subsection 4dip }
|
|
||||||
"The keep combinators invoke a quotation which takes a number of values off the stack, and then they restore those values:"
|
"The keep combinators invoke a quotation which takes a number of values off the stack, and then they restore those values:"
|
||||||
{ $subsection keep }
|
{ $subsections keep 2keep 3keep } ;
|
||||||
{ $subsection 2keep }
|
|
||||||
{ $subsection 3keep } ;
|
|
||||||
|
|
||||||
ARTICLE: "curried-dataflow" "Curried dataflow combinators"
|
ARTICLE: "curried-dataflow" "Curried dataflow combinators"
|
||||||
"Curried cleave combinators:"
|
"Curried cleave combinators:"
|
||||||
{ $subsection bi-curry }
|
{ $subsections bi-curry tri-curry }
|
||||||
{ $subsection tri-curry }
|
|
||||||
"Curried spread combinators:"
|
"Curried spread combinators:"
|
||||||
{ $subsection bi-curry* }
|
{ $subsections bi-curry* tri-curry* }
|
||||||
{ $subsection tri-curry* }
|
|
||||||
"Curried apply combinators:"
|
"Curried apply combinators:"
|
||||||
{ $subsection bi-curry@ }
|
{ $subsections bi-curry@ tri-curry@ }
|
||||||
{ $subsection tri-curry@ }
|
|
||||||
{ $see-also "dataflow-combinators" } ;
|
{ $see-also "dataflow-combinators" } ;
|
||||||
|
|
||||||
ARTICLE: "compositional-examples" "Examples of compositional combinator usage"
|
ARTICLE: "compositional-examples" "Examples of compositional combinator usage"
|
||||||
|
@ -170,33 +154,30 @@ $nl
|
||||||
|
|
||||||
ARTICLE: "compositional-combinators" "Compositional combinators"
|
ARTICLE: "compositional-combinators" "Compositional combinators"
|
||||||
"Certain combinators transform quotations to produce a new quotation."
|
"Certain combinators transform quotations to produce a new quotation."
|
||||||
{ $subsection "compositional-examples" }
|
{ $subsections "compositional-examples" }
|
||||||
"Fundamental operations:"
|
"Fundamental operations:"
|
||||||
{ $subsection curry }
|
{ $subsections curry compose }
|
||||||
{ $subsection compose }
|
|
||||||
"Derived operations:"
|
"Derived operations:"
|
||||||
{ $subsection 2curry }
|
{ $subsections 2curry 3curry with prepose }
|
||||||
{ $subsection 3curry }
|
|
||||||
{ $subsection with }
|
|
||||||
{ $subsection prepose }
|
|
||||||
"These operations run in constant time, and in many cases are optimized out altogether by the " { $link "compiler" } ". " { $link "fry" } " are an abstraction built on top of these operations, and code that uses this abstraction is often clearer than direct calls to the below words."
|
"These operations run in constant time, and in many cases are optimized out altogether by the " { $link "compiler" } ". " { $link "fry" } " are an abstraction built on top of these operations, and code that uses this abstraction is often clearer than direct calls to the below words."
|
||||||
$nl
|
$nl
|
||||||
"Curried dataflow combinators can be used to build more complex dataflow by combining cleave, spread and apply patterns in various ways."
|
"Curried dataflow combinators can be used to build more complex dataflow by combining cleave, spread and apply patterns in various ways."
|
||||||
{ $subsection "curried-dataflow" }
|
{ $subsections "curried-dataflow" }
|
||||||
"Quotations also implement the sequence protocol, and can be manipulated with sequence words; see " { $link "quotations" } ". However, such runtime quotation manipulation will not be optimized by the optimizing compiler." ;
|
"Quotations also implement the sequence protocol, and can be manipulated with sequence words; see " { $link "quotations" } ". However, such runtime quotation manipulation will not be optimized by the optimizing compiler." ;
|
||||||
|
|
||||||
ARTICLE: "booleans" "Booleans"
|
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."
|
"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."
|
||||||
{ $subsection f }
|
{ $subsections f t }
|
||||||
{ $subsection t }
|
|
||||||
"A union class of the above:"
|
"A union class of the above:"
|
||||||
{ $subsection boolean }
|
{ $subsections boolean }
|
||||||
"There are some logical operations on booleans:"
|
"There are some logical operations on booleans:"
|
||||||
{ $subsection >boolean }
|
{ $subsections
|
||||||
{ $subsection not }
|
>boolean
|
||||||
{ $subsection and }
|
not
|
||||||
{ $subsection or }
|
and
|
||||||
{ $subsection xor }
|
or
|
||||||
|
xor
|
||||||
|
}
|
||||||
"Boolean values are most frequently used for " { $link "conditionals" } "."
|
"Boolean values are most frequently used for " { $link "conditionals" } "."
|
||||||
{ $heading "The f object and f class" }
|
{ $heading "The f object and f class" }
|
||||||
"The " { $link f } " object is the unique instance of the " { $link f } " class; the two are distinct objects. The latter is also a parsing word which adds the " { $link f } " object to the parse tree at parse time. To refer to the class itself you must use " { $link POSTPONE: POSTPONE: } " or " { $link POSTPONE: \ } " to prevent the parsing word from executing."
|
"The " { $link f } " object is the unique instance of the " { $link f } " class; the two are distinct objects. The latter is also a parsing word which adds the " { $link f } " object to the parse tree at parse time. To refer to the class itself you must use " { $link POSTPONE: POSTPONE: } " or " { $link POSTPONE: \ } " to prevent the parsing word from executing."
|
||||||
|
@ -231,41 +212,35 @@ $nl
|
||||||
|
|
||||||
ARTICLE: "conditionals" "Conditional combinators"
|
ARTICLE: "conditionals" "Conditional combinators"
|
||||||
"The basic conditionals:"
|
"The basic conditionals:"
|
||||||
{ $subsection if }
|
{ $subsections if when unless }
|
||||||
{ $subsection when }
|
|
||||||
{ $subsection unless }
|
|
||||||
"Forms abstracting a common stack shuffle pattern:"
|
"Forms abstracting a common stack shuffle pattern:"
|
||||||
{ $subsection if* }
|
{ $subsections if* when* unless* }
|
||||||
{ $subsection when* }
|
|
||||||
{ $subsection unless* }
|
|
||||||
"Another form abstracting a common stack shuffle pattern:"
|
"Another form abstracting a common stack shuffle pattern:"
|
||||||
{ $subsection ?if }
|
{ $subsections ?if }
|
||||||
"Sometimes instead of branching, you just need to pick one of two values:"
|
"Sometimes instead of branching, you just need to pick one of two values:"
|
||||||
{ $subsection ? }
|
{ $subsections ? }
|
||||||
"Two combinators which abstract out nested chains of " { $link if } ":"
|
"Two combinators which abstract out nested chains of " { $link if } ":"
|
||||||
{ $subsection cond }
|
{ $subsections cond case }
|
||||||
{ $subsection case }
|
|
||||||
{ $subsection "conditionals-boolean-equivalence" }
|
{ $subsection "conditionals-boolean-equivalence" }
|
||||||
{ $see-also "booleans" "bitwise-arithmetic" both? either? } ;
|
{ $see-also "booleans" "bitwise-arithmetic" both? either? } ;
|
||||||
|
|
||||||
ARTICLE: "dataflow-combinators" "Data flow combinators"
|
ARTICLE: "dataflow-combinators" "Data flow combinators"
|
||||||
"Data flow combinators pass values between quotations:"
|
"Data flow combinators pass values between quotations:"
|
||||||
{ $subsection "retainstack-combinators" }
|
{ $subsections
|
||||||
{ $subsection "cleave-combinators" }
|
"retainstack-combinators"
|
||||||
{ $subsection "spread-combinators" }
|
"cleave-combinators"
|
||||||
{ $subsection "apply-combinators" }
|
"spread-combinators"
|
||||||
|
"apply-combinators"
|
||||||
|
}
|
||||||
{ $see-also "curried-dataflow" } ;
|
{ $see-also "curried-dataflow" } ;
|
||||||
|
|
||||||
ARTICLE: "combinators-quot" "Quotation construction utilities"
|
ARTICLE: "combinators-quot" "Quotation construction utilities"
|
||||||
"Some words for creating quotations which can be useful for implementing method combinations and compiler transforms:"
|
"Some words for creating quotations which can be useful for implementing method combinations and compiler transforms:"
|
||||||
{ $subsection cond>quot }
|
{ $subsections cond>quot case>quot alist>quot } ;
|
||||||
{ $subsection case>quot }
|
|
||||||
{ $subsection alist>quot } ;
|
|
||||||
|
|
||||||
ARTICLE: "call-unsafe" "Unsafe combinators"
|
ARTICLE: "call-unsafe" "Unsafe combinators"
|
||||||
"Unsafe calls declare an effect statically without any runtime checking:"
|
"Unsafe calls declare an effect statically without any runtime checking:"
|
||||||
{ $subsection call-effect-unsafe }
|
{ $subsections call-effect-unsafe execute-effect-unsafe } ;
|
||||||
{ $subsection execute-effect-unsafe } ;
|
|
||||||
|
|
||||||
ARTICLE: "call" "Fundamental combinators"
|
ARTICLE: "call" "Fundamental combinators"
|
||||||
"The most basic combinators are those that take either a quotation or word, and invoke it immediately."
|
"The most basic combinators are those that take either a quotation or word, and invoke it immediately."
|
||||||
|
@ -273,30 +248,29 @@ $nl
|
||||||
"There are two sets of combinators; they differ in whether or not the stack effect of the expected code is declared."
|
"There are two sets of combinators; they differ in whether or not the stack effect of the expected code is declared."
|
||||||
$nl
|
$nl
|
||||||
"The simplest combinators do not take an effect declaration. The compiler checks the stack effect at compile time, rejecting the program if this cannot be done:"
|
"The simplest combinators do not take an effect declaration. The compiler checks the stack effect at compile time, rejecting the program if this cannot be done:"
|
||||||
{ $subsection call }
|
{ $subsections call execute }
|
||||||
{ $subsection execute }
|
|
||||||
"The second set of combinators takes an effect declaration. Note that the opening parenthesis is actually part of the word name; these are parsing words, and they read a stack effect until the corresponding closing parenthesis. The stack effect of the quotation or word is then checked at runtime:"
|
"The second set of combinators takes an effect declaration. Note that the opening parenthesis is actually part of the word name; these are parsing words, and they read a stack effect until the corresponding closing parenthesis. The stack effect of the quotation or word is then checked at runtime:"
|
||||||
{ $subsection POSTPONE: call( }
|
{ $subsections POSTPONE: call( POSTPONE: execute( }
|
||||||
{ $subsection POSTPONE: execute( }
|
|
||||||
"The above are syntax sugar. The underlying words are a bit more verbose but allow non-constant effects to be passed in:"
|
"The above are syntax sugar. The underlying words are a bit more verbose but allow non-constant effects to be passed in:"
|
||||||
{ $subsection call-effect }
|
{ $subsections call-effect execute-effect }
|
||||||
{ $subsection execute-effect }
|
|
||||||
"The combinator variants that do not take an effect declaration can only be used if the compiler is able to infer the stack effect by other means. See " { $link "inference-combinators" } "."
|
"The combinator variants that do not take an effect declaration can only be used if the compiler is able to infer the stack effect by other means. See " { $link "inference-combinators" } "."
|
||||||
{ $subsection "call-unsafe" }
|
{ $subsection "call-unsafe" }
|
||||||
{ $see-also "effects" "inference" } ;
|
{ $see-also "effects" "inference" } ;
|
||||||
|
|
||||||
ARTICLE: "combinators" "Combinators"
|
ARTICLE: "combinators" "Combinators"
|
||||||
"A central concept in Factor is that of a " { $emphasis "combinator" } ", which is a word taking code as input."
|
"A central concept in Factor is that of a " { $emphasis "combinator" } ", which is a word taking code as input."
|
||||||
{ $subsection "call" }
|
{ $subsections
|
||||||
{ $subsection "dataflow-combinators" }
|
"call"
|
||||||
{ $subsection "conditionals" }
|
"dataflow-combinators"
|
||||||
{ $subsection "looping-combinators" }
|
"conditionals"
|
||||||
{ $subsection "compositional-combinators" }
|
"looping-combinators"
|
||||||
{ $subsection "combinators.short-circuit" }
|
"compositional-combinators"
|
||||||
{ $subsection "combinators.smart" }
|
"combinators.short-circuit"
|
||||||
|
"combinators.smart"
|
||||||
|
"combinators-quot"
|
||||||
|
"generalizations"
|
||||||
|
}
|
||||||
"More combinators are defined for working on data structures, such as " { $link "sequences-combinators" } " and " { $link "assocs-combinators" } "."
|
"More combinators are defined for working on data structures, such as " { $link "sequences-combinators" } " and " { $link "assocs-combinators" } "."
|
||||||
{ $subsection "combinators-quot" }
|
|
||||||
{ $subsection "generalizations" }
|
|
||||||
{ $see-also "quotations" } ;
|
{ $see-also "quotations" } ;
|
||||||
|
|
||||||
ABOUT: "combinators"
|
ABOUT: "combinators"
|
||||||
|
|
|
@ -8,17 +8,21 @@ $nl
|
||||||
"Integers can be converted to and from arbitrary bases. Floating point numbers can only be converted to and from base 10 and 16."
|
"Integers can be converted to and from arbitrary bases. Floating point numbers can only be converted to and from base 10 and 16."
|
||||||
$nl
|
$nl
|
||||||
"Converting numbers to strings:"
|
"Converting numbers to strings:"
|
||||||
{ $subsection number>string }
|
{ $subsections
|
||||||
{ $subsection >bin }
|
number>string
|
||||||
{ $subsection >oct }
|
>bin
|
||||||
{ $subsection >hex }
|
>oct
|
||||||
{ $subsection >base }
|
>hex
|
||||||
|
>base
|
||||||
|
}
|
||||||
"Converting strings to numbers:"
|
"Converting strings to numbers:"
|
||||||
{ $subsection string>number }
|
{ $subsections
|
||||||
{ $subsection bin> }
|
string>number
|
||||||
{ $subsection oct> }
|
bin>
|
||||||
{ $subsection hex> }
|
oct>
|
||||||
{ $subsection base> }
|
hex>
|
||||||
|
base>
|
||||||
|
}
|
||||||
"You can also input literal numbers in a different base (" { $link "syntax-integers" } ")."
|
"You can also input literal numbers in a different base (" { $link "syntax-integers" } ")."
|
||||||
{ $see-also "prettyprint-numbers" } ;
|
{ $see-also "prettyprint-numbers" } ;
|
||||||
|
|
||||||
|
|
|
@ -1336,49 +1336,39 @@ $nl
|
||||||
|
|
||||||
ARTICLE: "sequence-protocol" "Sequence protocol"
|
ARTICLE: "sequence-protocol" "Sequence protocol"
|
||||||
"All sequences must be instances of a mixin class:"
|
"All sequences must be instances of a mixin class:"
|
||||||
{ $subsection sequence }
|
{ $subsections sequence sequence? }
|
||||||
{ $subsection sequence? }
|
|
||||||
"All sequences must know their length:"
|
"All sequences must know their length:"
|
||||||
{ $subsection length }
|
{ $subsections length }
|
||||||
"At least one of the following two generic words must have a method for accessing elements; the " { $link sequence } " mixin has default definitions which are mutually recursive:"
|
"At least one of the following two generic words must have a method for accessing elements; the " { $link sequence } " mixin has default definitions which are mutually recursive:"
|
||||||
{ $subsection nth }
|
{ $subsections nth nth-unsafe }
|
||||||
{ $subsection nth-unsafe }
|
|
||||||
"Note that sequences are always indexed starting from zero."
|
"Note that sequences are always indexed starting from zero."
|
||||||
$nl
|
$nl
|
||||||
"At least one of the following two generic words must have a method for storing elements; the " { $link sequence } " mixin has default definitions which are mutually recursive:"
|
"At least one of the following two generic words must have a method for storing elements; the " { $link sequence } " mixin has default definitions which are mutually recursive:"
|
||||||
{ $subsection set-nth }
|
{ $subsections set-nth set-nth-unsafe }
|
||||||
{ $subsection set-nth-unsafe }
|
"If your sequence is immutable, then you must implement either " { $link set-nth } " or " { $link set-nth-unsafe } " to simply call " { $link immutable } " to signal an error."
|
||||||
"Note that even if the sequence is immutable, at least one of the generic words must be specialized, otherwise calling them will result in an infinite recursion. There is a standard word which throws an error indicating a sequence is immutable:"
|
$nl
|
||||||
{ $subsection immutable }
|
|
||||||
"The following two generic words are optional, as not all sequences are resizable:"
|
"The following two generic words are optional, as not all sequences are resizable:"
|
||||||
{ $subsection set-length }
|
{ $subsections set-length lengthen }
|
||||||
{ $subsection lengthen }
|
|
||||||
"An optional generic word for creating sequences of the same class as a given sequence:"
|
"An optional generic word for creating sequences of the same class as a given sequence:"
|
||||||
{ $subsection like }
|
{ $subsections like }
|
||||||
"Optional generic words for optimization purposes:"
|
"Optional generic words for optimization purposes:"
|
||||||
{ $subsection new-sequence }
|
{ $subsections new-sequence new-resizable }
|
||||||
{ $subsection new-resizable }
|
|
||||||
{ $see-also "sequences-unsafe" } ;
|
{ $see-also "sequences-unsafe" } ;
|
||||||
|
|
||||||
ARTICLE: "virtual-sequences-protocol" "Virtual sequence protocol"
|
ARTICLE: "virtual-sequences-protocol" "Virtual sequence protocol"
|
||||||
"Virtual sequences must know their length:"
|
"Virtual sequences must know their length:"
|
||||||
{ $subsection length }
|
{ $subsections length }
|
||||||
"The underlying sequence to look up a value in:"
|
"The underlying sequence to look up a value in:"
|
||||||
{ $subsection virtual-seq }
|
{ $subsections virtual-seq }
|
||||||
"The index of the value in the underlying sequence:"
|
"The index of the value in the underlying sequence:"
|
||||||
{ $subsection virtual@ } ;
|
{ $subsections virtual@ } ;
|
||||||
|
|
||||||
ARTICLE: "virtual-sequences" "Virtual sequences"
|
ARTICLE: "virtual-sequences" "Virtual sequences"
|
||||||
"A virtual sequence is an implementation of the " { $link "sequence-protocol" } " which does not store its own elements, and instead computes them, either from scratch or by retrieving them from another sequence."
|
"A virtual sequence is an implementation of the " { $link "sequence-protocol" } " which does not store its own elements, and instead computes them, either from scratch or by retrieving them from another sequence."
|
||||||
$nl
|
$nl
|
||||||
"Implementations include the following:"
|
"Implementations include the following:"
|
||||||
{ $list
|
{ $subsections reversed slice iota }
|
||||||
{ $link reversed }
|
"Virtual sequences can be implemented with the " { $link "virtual-sequences-protocol" } ", by translating an index in the virtual sequence into an index in another sequence." ;
|
||||||
{ $link slice }
|
|
||||||
{ $link iota }
|
|
||||||
}
|
|
||||||
"Virtual sequences can be implemented with the " { $link "virtual-sequences-protocol" } ", by translating an index in the virtual sequence into an index in another sequence:"
|
|
||||||
{ $subsection "virtual-sequences-protocol" } ;
|
|
||||||
|
|
||||||
ARTICLE: "sequences-integers" "Counted loops"
|
ARTICLE: "sequences-integers" "Counted loops"
|
||||||
"Integers support the sequence protocol in a trivial fashion; a non-negative integer presents its non-negative predecessors as elements. For example, the integer 3, when viewed as a sequence, contains the elements 0, 1, and 2. This is very useful for performing counted loops."
|
"Integers support the sequence protocol in a trivial fashion; a non-negative integer presents its non-negative predecessors as elements. For example, the integer 3, when viewed as a sequence, contains the elements 0, 1, and 2. This is very useful for performing counted loops."
|
||||||
|
@ -1395,59 +1385,50 @@ ARTICLE: "sequences-if" "Control flow with sequences"
|
||||||
"To reduce the boilerplate of checking if a sequence is empty, several combinators are provided."
|
"To reduce the boilerplate of checking if a sequence is empty, several combinators are provided."
|
||||||
$nl
|
$nl
|
||||||
"Checking if a sequence is empty:"
|
"Checking if a sequence is empty:"
|
||||||
{ $subsection if-empty }
|
{ $subsections if-empty when-empty unless-empty } ;
|
||||||
{ $subsection when-empty }
|
|
||||||
{ $subsection unless-empty } ;
|
|
||||||
|
|
||||||
ARTICLE: "sequences-access" "Accessing sequence elements"
|
ARTICLE: "sequences-access" "Accessing sequence elements"
|
||||||
{ $subsection ?nth }
|
"Element access by index, without raising exceptions:"
|
||||||
|
{ $subsections ?nth }
|
||||||
"Concise way of extracting one of the first four elements:"
|
"Concise way of extracting one of the first four elements:"
|
||||||
{ $subsection first }
|
{ $subsections first second third fourth }
|
||||||
{ $subsection second }
|
|
||||||
{ $subsection third }
|
|
||||||
{ $subsection fourth }
|
|
||||||
"Extracting the last element:"
|
"Extracting the last element:"
|
||||||
{ $subsection last }
|
{ $subsections last }
|
||||||
"Unpacking sequences:"
|
"Unpacking sequences:"
|
||||||
{ $subsection first2 }
|
{ $subsections first2 first3 first4 }
|
||||||
{ $subsection first3 }
|
|
||||||
{ $subsection first4 }
|
|
||||||
{ $see-also nth } ;
|
{ $see-also nth } ;
|
||||||
|
|
||||||
ARTICLE: "sequences-add-remove" "Adding and removing sequence elements"
|
ARTICLE: "sequences-add-remove" "Adding and removing sequence elements"
|
||||||
"Adding elements:"
|
"Adding elements:"
|
||||||
{ $subsection prefix }
|
{ $subsections prefix suffix }
|
||||||
{ $subsection suffix }
|
|
||||||
"Removing elements:"
|
"Removing elements:"
|
||||||
{ $subsection remove }
|
{ $subsections remove remq remove-nth } ;
|
||||||
{ $subsection remq }
|
|
||||||
{ $subsection remove-nth } ;
|
|
||||||
|
|
||||||
ARTICLE: "sequences-reshape" "Reshaping sequences"
|
ARTICLE: "sequences-reshape" "Reshaping sequences"
|
||||||
"A " { $emphasis "repetition" } " is a virtual sequence consisting of a single element repeated multiple times:"
|
"A " { $emphasis "repetition" } " is a virtual sequence consisting of a single element repeated multiple times:"
|
||||||
{ $subsection repetition }
|
{ $subsections repetition <repetition> }
|
||||||
{ $subsection <repetition> }
|
|
||||||
"Reversing a sequence:"
|
"Reversing a sequence:"
|
||||||
{ $subsection reverse }
|
{ $subsections reverse }
|
||||||
"A " { $emphasis "reversal" } " presents a reversed view of an underlying sequence:"
|
"A " { $emphasis "reversal" } " presents a reversed view of an underlying sequence:"
|
||||||
{ $subsection reversed }
|
{ $subsections reversed <reversed> }
|
||||||
{ $subsection <reversed> }
|
|
||||||
"Transposing a matrix:"
|
"Transposing a matrix:"
|
||||||
{ $subsection flip } ;
|
{ $subsections flip } ;
|
||||||
|
|
||||||
ARTICLE: "sequences-appending" "Appending sequences"
|
ARTICLE: "sequences-appending" "Appending sequences"
|
||||||
{ $subsection append }
|
"Basic append operations:"
|
||||||
{ $subsection append-as }
|
{ $subsections
|
||||||
{ $subsection prepend }
|
append
|
||||||
{ $subsection 3append }
|
append-as
|
||||||
{ $subsection 3append-as }
|
prepend
|
||||||
{ $subsection surround }
|
3append
|
||||||
{ $subsection glue }
|
3append-as
|
||||||
{ $subsection concat }
|
surround
|
||||||
{ $subsection join }
|
glue
|
||||||
|
}
|
||||||
|
"Collapse a sequence unto itself:"
|
||||||
|
{ $subsections concat join }
|
||||||
"A pair of words useful for aligning strings:"
|
"A pair of words useful for aligning strings:"
|
||||||
{ $subsection pad-head }
|
{ $subsections pad-head pad-tail } ;
|
||||||
{ $subsection pad-tail } ;
|
|
||||||
|
|
||||||
ARTICLE: "sequences-slices" "Subsequences and slices"
|
ARTICLE: "sequences-slices" "Subsequences and slices"
|
||||||
"There are two ways to extract a subrange of elements from a sequence. The first approach creates a new sequence of the same type as the input, which does not share storage with the underlying sequence. This takes time proportional to the number of elements being extracted. The second approach creates a " { $emphasis "slice" } ", which is a virtual sequence (see " { $link "virtual-sequences" } ") sharing storage with the original sequence. Slices are constructed in constant time."
|
"There are two ways to extract a subrange of elements from a sequence. The first approach creates a new sequence of the same type as the input, which does not share storage with the underlying sequence. This takes time proportional to the number of elements being extracted. The second approach creates a " { $emphasis "slice" } ", which is a virtual sequence (see " { $link "virtual-sequences" } ") sharing storage with the original sequence. Slices are constructed in constant time."
|
||||||
|
@ -1461,119 +1442,125 @@ $nl
|
||||||
}
|
}
|
||||||
{ $heading "Subsequence operations" }
|
{ $heading "Subsequence operations" }
|
||||||
"Extracting a subsequence:"
|
"Extracting a subsequence:"
|
||||||
{ $subsection subseq }
|
{ $subsections
|
||||||
{ $subsection head }
|
subseq
|
||||||
{ $subsection tail }
|
head
|
||||||
{ $subsection head* }
|
tail
|
||||||
{ $subsection tail* }
|
head*
|
||||||
|
tail*
|
||||||
|
}
|
||||||
"Removing the first or last element:"
|
"Removing the first or last element:"
|
||||||
{ $subsection rest }
|
{ $subsections rest but-last }
|
||||||
{ $subsection but-last }
|
|
||||||
"Taking a sequence apart into a head and a tail:"
|
"Taking a sequence apart into a head and a tail:"
|
||||||
{ $subsection unclip }
|
{ $subsections
|
||||||
{ $subsection unclip-last }
|
unclip
|
||||||
{ $subsection cut }
|
unclip-last
|
||||||
{ $subsection cut* }
|
cut
|
||||||
|
cut*
|
||||||
|
}
|
||||||
{ $heading "Slice operations" }
|
{ $heading "Slice operations" }
|
||||||
"The slice data type:"
|
"The slice data type:"
|
||||||
{ $subsection slice }
|
{ $subsections slice slice? }
|
||||||
{ $subsection slice? }
|
|
||||||
"Extracting a slice:"
|
"Extracting a slice:"
|
||||||
{ $subsection <slice> }
|
{ $subsections
|
||||||
{ $subsection head-slice }
|
<slice>
|
||||||
{ $subsection tail-slice }
|
head-slice
|
||||||
{ $subsection head-slice* }
|
tail-slice
|
||||||
{ $subsection tail-slice* }
|
head-slice*
|
||||||
|
tail-slice*
|
||||||
|
}
|
||||||
"Removing the first or last element:"
|
"Removing the first or last element:"
|
||||||
{ $subsection rest-slice }
|
{ $subsections rest-slice but-last-slice }
|
||||||
{ $subsection but-last-slice }
|
|
||||||
"Taking a sequence apart into a head and a tail:"
|
"Taking a sequence apart into a head and a tail:"
|
||||||
{ $subsection unclip-slice }
|
{ $subsections unclip-slice unclip-last-slice cut-slice }
|
||||||
{ $subsection unclip-last-slice }
|
|
||||||
{ $subsection cut-slice }
|
|
||||||
"A utility for words which use slices as iterators:"
|
"A utility for words which use slices as iterators:"
|
||||||
{ $subsection <flat-slice> }
|
{ $subsections <flat-slice> }
|
||||||
"Replacing slices with new elements:"
|
"Replacing slices with new elements:"
|
||||||
{ $subsection replace-slice } ;
|
{ $subsections replace-slice } ;
|
||||||
|
|
||||||
ARTICLE: "sequences-combinators" "Sequence combinators"
|
ARTICLE: "sequences-combinators" "Sequence combinators"
|
||||||
"Iteration:"
|
"Iteration:"
|
||||||
{ $subsection each }
|
{ $subsections
|
||||||
{ $subsection each-index }
|
each
|
||||||
{ $subsection reduce }
|
each-index
|
||||||
{ $subsection interleave }
|
reduce
|
||||||
{ $subsection replicate }
|
interleave
|
||||||
{ $subsection replicate-as }
|
replicate
|
||||||
|
replicate-as
|
||||||
|
}
|
||||||
"Mapping:"
|
"Mapping:"
|
||||||
{ $subsection map }
|
{ $subsections
|
||||||
{ $subsection map-as }
|
map
|
||||||
{ $subsection map-index }
|
map-as
|
||||||
{ $subsection map-reduce }
|
map-index
|
||||||
{ $subsection accumulate }
|
map-reduce
|
||||||
{ $subsection produce }
|
accumulate
|
||||||
{ $subsection produce-as }
|
produce
|
||||||
|
produce-as
|
||||||
|
}
|
||||||
"Filtering:"
|
"Filtering:"
|
||||||
{ $subsection filter }
|
{ $subsections
|
||||||
{ $subsection partition }
|
filter
|
||||||
|
partition
|
||||||
|
}
|
||||||
"Testing if a sequence contains elements satisfying a predicate:"
|
"Testing if a sequence contains elements satisfying a predicate:"
|
||||||
{ $subsection any? }
|
{ $subsections
|
||||||
{ $subsection all? }
|
any?
|
||||||
|
all?
|
||||||
|
}
|
||||||
|
{ $heading "Related Articles" }
|
||||||
{ $subsection "sequence-2combinators" }
|
{ $subsection "sequence-2combinators" }
|
||||||
{ $subsection "sequence-3combinators" } ;
|
{ $subsection "sequence-3combinators" } ;
|
||||||
|
|
||||||
ARTICLE: "sequence-2combinators" "Pair-wise sequence combinators"
|
ARTICLE: "sequence-2combinators" "Pair-wise sequence combinators"
|
||||||
"There is a set of combinators which traverse two sequences pairwise. If one sequence is shorter than the other, then only the prefix having the length of the minimum of the two is examined."
|
"There is a set of combinators which traverse two sequences pairwise. If one sequence is shorter than the other, then only the prefix having the length of the minimum of the two is examined."
|
||||||
{ $subsection 2each }
|
{ $subsections
|
||||||
{ $subsection 2reduce }
|
2each
|
||||||
{ $subsection 2map }
|
2reduce
|
||||||
{ $subsection 2map-as }
|
2map
|
||||||
{ $subsection 2map-reduce }
|
2map-as
|
||||||
{ $subsection 2all? } ;
|
2map-reduce
|
||||||
|
2all?
|
||||||
|
} ;
|
||||||
|
|
||||||
ARTICLE: "sequence-3combinators" "Triple-wise sequence combinators"
|
ARTICLE: "sequence-3combinators" "Triple-wise sequence combinators"
|
||||||
"There is a set of combinators which traverse three sequences triple-wise. If one sequence is shorter than the others, then only the prefix having the length of the minimum of the three is examined."
|
"There is a set of combinators which traverse three sequences triple-wise. If one sequence is shorter than the others, then only the prefix having the length of the minimum of the three is examined."
|
||||||
{ $subsection 3each }
|
{ $subsections 3each 3map 3map-as } ;
|
||||||
{ $subsection 3map }
|
|
||||||
{ $subsection 3map-as } ;
|
|
||||||
|
|
||||||
ARTICLE: "sequences-tests" "Testing sequences"
|
ARTICLE: "sequences-tests" "Testing sequences"
|
||||||
"Testing for an empty sequence:"
|
"Testing for an empty sequence:"
|
||||||
{ $subsection empty? }
|
{ $subsections empty? }
|
||||||
"Testing indices:"
|
"Testing indices:"
|
||||||
{ $subsection bounds-check? }
|
{ $subsections bounds-check? }
|
||||||
"Testing if a sequence contains an object:"
|
"Testing if a sequence contains an object:"
|
||||||
{ $subsection member? }
|
{ $subsections member? memq? }
|
||||||
{ $subsection memq? }
|
|
||||||
"Testing if a sequence contains a subsequence:"
|
"Testing if a sequence contains a subsequence:"
|
||||||
{ $subsection head? }
|
{ $subsections head? tail? subseq? } ;
|
||||||
{ $subsection tail? }
|
|
||||||
{ $subsection subseq? } ;
|
|
||||||
|
|
||||||
ARTICLE: "sequences-search" "Searching sequences"
|
ARTICLE: "sequences-search" "Searching sequences"
|
||||||
"Finding the index of an element:"
|
"Finding the index of an element:"
|
||||||
{ $subsection index }
|
{ $subsections
|
||||||
{ $subsection index-from }
|
index
|
||||||
{ $subsection last-index }
|
index-from
|
||||||
{ $subsection last-index-from }
|
last-index
|
||||||
|
last-index-from
|
||||||
|
}
|
||||||
"Finding the start of a subsequence:"
|
"Finding the start of a subsequence:"
|
||||||
{ $subsection start }
|
{ $subsections start start* }
|
||||||
{ $subsection start* }
|
|
||||||
"Finding the index of an element satisfying a predicate:"
|
"Finding the index of an element satisfying a predicate:"
|
||||||
{ $subsection find }
|
{ $subsections
|
||||||
{ $subsection find-from }
|
find
|
||||||
{ $subsection find-last }
|
find-from
|
||||||
{ $subsection find-last-from }
|
find-last
|
||||||
{ $subsection map-find } ;
|
find-last-from
|
||||||
|
map-find
|
||||||
|
} ;
|
||||||
|
|
||||||
ARTICLE: "sequences-trimming" "Trimming sequences"
|
ARTICLE: "sequences-trimming" "Trimming sequences"
|
||||||
"Trimming words:"
|
"Trimming words:"
|
||||||
{ $subsection trim }
|
{ $subsections trim trim-head trim-tail }
|
||||||
{ $subsection trim-head }
|
|
||||||
{ $subsection trim-tail }
|
|
||||||
"Potentially more efficient trim:"
|
"Potentially more efficient trim:"
|
||||||
{ $subsection trim-slice }
|
{ $subsections trim-slice trim-head-slice trim-tail-slice } ;
|
||||||
{ $subsection trim-head-slice }
|
|
||||||
{ $subsection trim-tail-slice } ;
|
|
||||||
|
|
||||||
ARTICLE: "sequences-destructive-discussion" "When to use destructive operations"
|
ARTICLE: "sequences-destructive-discussion" "When to use destructive operations"
|
||||||
"Constructive (non-destructive) operations should be preferred where possible because code without side-effects is usually more re-usable and easier to reason about. There are two main reasons to use destructive operations:"
|
"Constructive (non-destructive) operations should be preferred where possible because code without side-effects is usually more re-usable and easier to reason about. There are two main reasons to use destructive operations:"
|
||||||
|
@ -1584,24 +1571,25 @@ ARTICLE: "sequences-destructive-discussion" "When to use destructive operations"
|
||||||
"The second reason is much weaker than the first one. In particular, many combinators (see " { $link map } ", " { $link produce } " and " { $link "namespaces-make" } ") as well as more advanced data structures (such as " { $vocab-link "persistent.vectors" } ") alleviate the need for explicit use of side effects." ;
|
"The second reason is much weaker than the first one. In particular, many combinators (see " { $link map } ", " { $link produce } " and " { $link "namespaces-make" } ") as well as more advanced data structures (such as " { $vocab-link "persistent.vectors" } ") alleviate the need for explicit use of side effects." ;
|
||||||
|
|
||||||
ARTICLE: "sequences-destructive" "Destructive operations"
|
ARTICLE: "sequences-destructive" "Destructive operations"
|
||||||
"These words modify their input, instead of creating a new sequence."
|
|
||||||
{ $subsection "sequences-destructive-discussion" }
|
|
||||||
"Changing elements:"
|
"Changing elements:"
|
||||||
{ $subsection change-each }
|
{ $subsections change-each change-nth }
|
||||||
{ $subsection change-nth }
|
|
||||||
"Deleting elements:"
|
"Deleting elements:"
|
||||||
{ $subsection delete }
|
{ $subsections
|
||||||
{ $subsection delq }
|
delete
|
||||||
{ $subsection delete-nth }
|
delq
|
||||||
{ $subsection delete-slice }
|
delete-nth
|
||||||
{ $subsection delete-all }
|
delete-slice
|
||||||
{ $subsection filter-here }
|
delete-all
|
||||||
|
filter-here
|
||||||
|
}
|
||||||
"Other destructive words:"
|
"Other destructive words:"
|
||||||
{ $subsection reverse-here }
|
{ $subsections
|
||||||
{ $subsection push-all }
|
reverse-here
|
||||||
{ $subsection move }
|
push-all
|
||||||
{ $subsection exchange }
|
move
|
||||||
{ $subsection copy }
|
exchange
|
||||||
|
copy
|
||||||
|
}
|
||||||
"Many operations have constructive and destructive variants:"
|
"Many operations have constructive and destructive variants:"
|
||||||
{ $table
|
{ $table
|
||||||
{ "Constructive" "Destructive" }
|
{ "Constructive" "Destructive" }
|
||||||
|
@ -1616,21 +1604,24 @@ ARTICLE: "sequences-destructive" "Destructive operations"
|
||||||
{ { $link map } { $link change-each } }
|
{ { $link map } { $link change-each } }
|
||||||
{ { $link filter } { $link filter-here } }
|
{ { $link filter } { $link filter-here } }
|
||||||
}
|
}
|
||||||
{ $see-also set-nth push pop "sequences-stacks" } ;
|
{ $heading "Related Articles" }
|
||||||
|
{ $subsection "sequences-destructive-discussion" }
|
||||||
|
{ $subsection "sequences-stacks" }
|
||||||
|
{ $see-also set-nth push pop } ;
|
||||||
|
|
||||||
ARTICLE: "sequences-stacks" "Treating sequences as stacks"
|
ARTICLE: "sequences-stacks" "Treating sequences as stacks"
|
||||||
"The classical stack operations, modifying a sequence in place:"
|
"The classical stack operations, modifying a sequence in place:"
|
||||||
{ $subsection push }
|
{ $subsections push pop pop* }
|
||||||
{ $subsection pop }
|
|
||||||
{ $subsection pop* }
|
|
||||||
{ $see-also empty? } ;
|
{ $see-also empty? } ;
|
||||||
|
|
||||||
ARTICLE: "sequences-comparing" "Comparing sequences"
|
ARTICLE: "sequences-comparing" "Comparing sequences"
|
||||||
"Element equality testing:"
|
"Element equality testing:"
|
||||||
{ $subsection sequence= }
|
{ $subsections
|
||||||
{ $subsection mismatch }
|
sequence=
|
||||||
{ $subsection drop-prefix }
|
mismatch
|
||||||
{ $subsection assert-sequence= }
|
drop-prefix
|
||||||
|
assert-sequence=
|
||||||
|
}
|
||||||
"The " { $link <=> } " generic word performs lexicographic comparison when applied to sequences." ;
|
"The " { $link <=> } " generic word performs lexicographic comparison when applied to sequences." ;
|
||||||
|
|
||||||
ARTICLE: "sequences-f" "The f object as a sequence"
|
ARTICLE: "sequences-f" "The f object as a sequence"
|
||||||
|
@ -1640,33 +1631,39 @@ ARTICLE: "sequences" "Sequence operations"
|
||||||
"A " { $emphasis "sequence" } " is a finite, linearly-ordered collection of elements. Words for working with sequences are in the " { $vocab-link "sequences" } " vocabulary."
|
"A " { $emphasis "sequence" } " is a finite, linearly-ordered collection of elements. Words for working with sequences are in the " { $vocab-link "sequences" } " vocabulary."
|
||||||
$nl
|
$nl
|
||||||
"Sequences implement a protocol:"
|
"Sequences implement a protocol:"
|
||||||
{ $subsection "sequence-protocol" }
|
{ $subsections
|
||||||
{ $subsection "sequences-f" }
|
"sequence-protocol"
|
||||||
|
"sequences-f"
|
||||||
|
}
|
||||||
"Sequence utility words can operate on any object whose class implements the sequence protocol. Most implementations are backed by storage. Some implementations obtain their elements from an underlying sequence, or compute them on the fly. These are known as " { $link "virtual-sequences" } "."
|
"Sequence utility words can operate on any object whose class implements the sequence protocol. Most implementations are backed by storage. Some implementations obtain their elements from an underlying sequence, or compute them on the fly. These are known as " { $link "virtual-sequences" } "."
|
||||||
{ $subsection "sequences-access" }
|
{ $subsections
|
||||||
{ $subsection "sequences-combinators" }
|
"sequences-access"
|
||||||
{ $subsection "sequences-add-remove" }
|
"sequences-combinators"
|
||||||
{ $subsection "sequences-appending" }
|
"sequences-add-remove"
|
||||||
{ $subsection "sequences-slices" }
|
"sequences-appending"
|
||||||
{ $subsection "sequences-reshape" }
|
"sequences-slices"
|
||||||
{ $subsection "sequences-tests" }
|
"sequences-reshape"
|
||||||
{ $subsection "sequences-search" }
|
"sequences-tests"
|
||||||
{ $subsection "sequences-comparing" }
|
"sequences-search"
|
||||||
{ $subsection "sequences-split" }
|
"sequences-comparing"
|
||||||
{ $subsection "grouping" }
|
"sequences-split"
|
||||||
{ $subsection "sequences-destructive" }
|
"grouping"
|
||||||
{ $subsection "sequences-stacks" }
|
"sequences-destructive"
|
||||||
{ $subsection "sequences-sorting" }
|
"sequences-stacks"
|
||||||
{ $subsection "binary-search" }
|
"sequences-sorting"
|
||||||
{ $subsection "sets" }
|
"binary-search"
|
||||||
{ $subsection "sequences-trimming" }
|
"sets"
|
||||||
{ $subsection "sequences.deep" }
|
"sequences-trimming"
|
||||||
|
"sequences.deep"
|
||||||
|
}
|
||||||
"Using sequences for looping:"
|
"Using sequences for looping:"
|
||||||
{ $subsection "sequences-integers" }
|
{ $subsections
|
||||||
{ $subsection "math.ranges" }
|
"sequences-integers"
|
||||||
|
"math.ranges"
|
||||||
|
}
|
||||||
"Using sequences for control flow:"
|
"Using sequences for control flow:"
|
||||||
{ $subsection "sequences-if" }
|
{ $subsections "sequences-if" }
|
||||||
"For inner loops:"
|
"For inner loops:"
|
||||||
{ $subsection "sequences-unsafe" } ;
|
{ $subsections "sequences-unsafe" } ;
|
||||||
|
|
||||||
ABOUT: "sequences"
|
ABOUT: "sequences"
|
||||||
|
|
|
@ -10,13 +10,15 @@ $nl
|
||||||
"Sorting combinators all take comparator quotations with stack effect " { $snippet "( elt1 elt2 -- <=> )" } ", where the output value is one of the three " { $link "order-specifiers" } "."
|
"Sorting combinators all take comparator quotations with stack effect " { $snippet "( elt1 elt2 -- <=> )" } ", where the output value is one of the three " { $link "order-specifiers" } "."
|
||||||
$nl
|
$nl
|
||||||
"Sorting a sequence with a custom comparator:"
|
"Sorting a sequence with a custom comparator:"
|
||||||
{ $subsection sort }
|
{ $subsections sort }
|
||||||
"Sorting a sequence with common comparators:"
|
"Sorting a sequence with common comparators:"
|
||||||
{ $subsection sort-with }
|
{ $subsections
|
||||||
{ $subsection inv-sort-with }
|
sort-with
|
||||||
{ $subsection natural-sort }
|
inv-sort-with
|
||||||
{ $subsection sort-keys }
|
natural-sort
|
||||||
{ $subsection sort-values } ;
|
sort-keys
|
||||||
|
sort-values
|
||||||
|
} ;
|
||||||
|
|
||||||
ABOUT: "sequences-sorting"
|
ABOUT: "sequences-sorting"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue