]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' into smarter_error_list
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Mon, 6 Apr 2009 18:27:06 +0000 (13:27 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Mon, 6 Apr 2009 18:27:06 +0000 (13:27 -0500)
64 files changed:
basis/alien/syntax/tags.txt [new file with mode: 0644]
basis/bootstrap/stage2.factor
basis/combinators/short-circuit/smart/tags.txt [new file with mode: 0644]
basis/combinators/short-circuit/tags.txt [new file with mode: 0644]
basis/combinators/smart/smart-docs.factor
basis/combinators/smart/tags.txt [new file with mode: 0644]
basis/compiler/tree/debugger/debugger.factor
basis/editors/editors-docs.factor
basis/help/cookbook/cookbook.factor
basis/help/handbook/handbook.factor
basis/help/home/home-docs.factor
basis/help/syntax/tags.txt [new file with mode: 0644]
basis/hints/hints.factor
basis/interpolate/tags.txt [new file with mode: 0644]
basis/locals/locals-docs.factor
basis/locals/locals-tests.factor
basis/math/ranges/ranges-docs.factor
basis/models/arrow/smart/smart-docs.factor [new file with mode: 0644]
basis/peg/ebnf/tags.txt
basis/prettyprint/backend/backend.factor
basis/prettyprint/prettyprint-tests.factor
basis/see/see-docs.factor
basis/see/see.factor
basis/tools/annotations/annotations-tests.factor
basis/tools/annotations/annotations.factor
basis/tools/deploy/shaker/shaker.factor
basis/tools/disassembler/disassembler-tests.factor
basis/tools/disassembler/disassembler.factor
basis/ui/tools/browser/history/history-tests.factor
basis/ui/tools/tools-docs.factor
basis/ui/traverse/traverse-docs.factor [new file with mode: 0644]
basis/ui/traverse/traverse-tests.factor
basis/unicode/unicode-docs.factor
basis/values/values-docs.factor
basis/xml/syntax/tags.txt
core/bootstrap/syntax.factor
core/classes/classes.factor
core/classes/tuple/tuple-tests.factor
core/combinators/combinators-docs.factor
core/definitions/definitions-docs.factor
core/definitions/definitions-tests.factor
core/definitions/definitions.factor
core/effects/effects-docs.factor
core/generic/generic-docs.factor
core/generic/generic-tests.factor
core/generic/generic.factor
core/generic/math/math-docs.factor
core/io/encodings/encodings-docs.factor
core/kernel/kernel-docs.factor
core/math/math-docs.factor
core/math/order/order-docs.factor
core/namespaces/namespaces-docs.factor
core/parser/parser-docs.factor
core/quotations/quotations-docs.factor
core/sequences/sequences-docs.factor
core/slots/slots-docs.factor
core/syntax/syntax-docs.factor
core/syntax/syntax.factor
core/words/constant/constant-tests.factor
core/words/constant/constant.factor
core/words/symbol/symbol.factor
extra/descriptive/tags.txt [new file with mode: 0644]
extra/multi-methods/tags.txt [new file with mode: 0644]
extra/peg-lexer/tags.txt

diff --git a/basis/alien/syntax/tags.txt b/basis/alien/syntax/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
index 6c824b6155745e7b1cdac3be454ae76a128c896d..12741f2170fba9dbb826481b26664cabdfc58b11 100644 (file)
@@ -45,11 +45,18 @@ SYMBOL: bootstrap-time
     [ optimized>> ] count-words " compiled words" print
     [ symbol? ] count-words " symbol words" print
     [ ] count-words " words total" print
-
+    
     "Bootstrapping is complete." print
     "Now, you can run Factor:" print
     vm write " -i=" write "output-image" get print flush ;
 
+: save/restore-error ( quot -- )
+    error get-global
+    error-continuation get-global
+    [ call ] 2dip
+    error-continuation set-global
+    error set-global ; inline
+
 [
     ! We time bootstrap
     millis
@@ -104,6 +111,7 @@ SYMBOL: bootstrap-time
     drop
     [
         load-help? off
-        "vocab:bootstrap/bootstrap-error.factor" run-file
+        [ "vocab:bootstrap/bootstrap-error.factor" parse-file ] save/restore-error
+        call
     ] with-scope
 ] recover
diff --git a/basis/combinators/short-circuit/smart/tags.txt b/basis/combinators/short-circuit/smart/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
diff --git a/basis/combinators/short-circuit/tags.txt b/basis/combinators/short-circuit/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
index 75f83c1a5576ac46185c98bb069d7e96e817c20b..679b5877594d7af40cdfb0b1b6bca227ee0e92f5 100644 (file)
@@ -108,17 +108,19 @@ HELP: append-outputs-as
 
 
 ARTICLE: "combinators.smart" "Smart combinators"
-"The " { $vocab-link "combinators.smart" } " vocabulary implements " { $emphasis "smart combinators" } ". A smart combinator is one whose behavior depends on the static stack effect of an input quotation." $nl
-"Smart inputs from a sequence:"
+"The macros in the " { $vocab-link "combinators.smart" } " vocabulary look at the static stack effects of input quotations and generate code which produces or consumes the relevant number of stack values." $nl
+"Call a quotation and discard all output values:"
+{ $subsection drop-outputs }
+"Take all input values from a sequence:"
 { $subsection input<sequence }
-"Smart outputs to a sequence:"
+"Store all output values to a sequence:"
 { $subsection output>sequence }
 { $subsection output>array }
-"Reducing the output of a quotation:"
+"Reducing the set of output values:"
 { $subsection reduce-outputs }
-"Summing the output of a quotation:"
+"Summing output values:"
 { $subsection sum-outputs }
-"Appending the results of a quotation:"
+"Concatenating output values:"
 { $subsection append-outputs }
 { $subsection append-outputs-as } ;
 
diff --git a/basis/combinators/smart/tags.txt b/basis/combinators/smart/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
index 430424291ebc19c338c5441ccbd32e915c0bc58a..8e102e0ea3cc9bc6da4dd3b768ad5d9ac1d852ad 100644 (file)
@@ -130,8 +130,6 @@ M: node node>quot drop ;
 
 GENERIC: optimized. ( quot/word -- )
 
-M: method-spec optimized. first2 method optimized. ;
-
 M: word optimized. specialized-def optimized. ;
 
 M: callable optimized. build-tree optimize-tree nodes>quot . ;
index 0f50e40eb404f25d65061abd0a10c7710ba7d94d..e3961aef80dbab80e76181fe54fdf46f3b73e02e 100644 (file)
@@ -22,7 +22,7 @@ HELP: edit
     "A word's documentation:"
     { $code "\\ foo >link edit" }
     "A method definition:"
-    { $code "{ editor draw-gadget* } edit" }
+    { $code "M\\ fixnum + edit" }
     "A help article:"
     { $code "\"handbook\" >link edit" }
 } ;
index 2cc19f87ddc2f857760aa68bec6d6ac1db57f8b8..867f3732098b8d855683b0f934624b3160e5651f 100644 (file)
@@ -117,7 +117,7 @@ $nl
 }
 { $references
     { "Since quotations are objects, they can be constructed and taken apart at will. You can write code that writes code. Arrays are just one of the various types of sequences, and the sequence operations such as " { $link each } " and " { $link map } " operate on all types of sequences. There are many more sequence iteration operations than the ones above, too." }
-    "dataflow"
+    "combinators"
     "sequences"
 } ;
 
index ed2a14a2f2acf19294ada9ff4b7516a5dda68e92..b2a0e56c0a8a5626efce120cc5f50364e5398505 100644 (file)
@@ -5,7 +5,7 @@ math system strings sbufs vectors byte-arrays quotations
 io.streams.byte-array classes.builtin parser lexer
 classes.predicate classes.union classes.intersection
 classes.singleton classes.tuple help.vocabs math.parser
-accessors ;
+accessors definitions ;
 IN: help.handbook
 
 ARTICLE: "conventions" "Conventions"
@@ -49,7 +49,7 @@ $nl
     { "associative mapping" { "an object whose class implements the " { $link "assocs-protocol" } } }
     { "boolean"               { { $link t } " or " { $link f } } }
     { "class"                 { "a set of objects identified by a " { $emphasis "class word" } " together with a discriminating predicate. See " { $link "classes" } } }
-    { "definition specifier"  { "a " { $link word } ", " { $link method-spec } ", " { $link link } ", vocabulary specifier, or any other object whose class implements the " { $link "definition-protocol" } } }
+    { "definition specifier"  { "an instance of " { $link definition } " which implements the " { $link "definition-protocol" } } }
     { "generalized boolean"   { "an object interpreted as a boolean; a value of " { $link f } " denotes false and anything else denotes true" } }
     { "generic word"          { "a word whose behavior depends can be specialized on the class of one of its inputs. See " { $link "generic" } } }
     { "method"                { "a specialized behavior of a generic word on a class. See " { $link "generic" } } }
@@ -70,7 +70,7 @@ ARTICLE: "tail-call-opt" "Tail-call optimization"
 $nl
 "Tail-call optimization allows iterative algorithms to be implemented in an efficient manner using recursion, without the need for any kind of primitive looping construct in the language. However, in practice, most iteration is performed via combinators such as " { $link while } ", " { $link each } ", " { $link map } ", " { $link assoc-each } ", and so on. The definitions of these combinators do bottom-out in recursive words, however." ;
 
-ARTICLE: "evaluator" "Evaluation semantics"
+ARTICLE: "evaluator" "Stack machine model"
 { $link "quotations" } " are evaluated sequentially from beginning to end. When the end is reached, the quotation returns to its caller. As each object in the quotation is evaluated in turn, an action is taken based on its type:"
 { $list
     { "a " { $link word } " - the word's definition quotation is called. See " { $link "words" } }
@@ -84,12 +84,13 @@ ARTICLE: "objects" "Objects"
 "An " { $emphasis "object" } " is any datum which may be identified. All values are objects in Factor. Each object carries type information, and types are checked at runtime; Factor is dynamically typed."
 { $subsection "equality" }
 { $subsection "math.order" }
-{ $subsection "destructors" }
 { $subsection "classes" }
 { $subsection "tuples" }
 { $subsection "generic" }
-{ $subsection "slots" }
-{ $subsection "mirrors" } ;
+"Advanced features:"
+{ $subsection "delegate" }
+{ $subsection "mirrors" }
+{ $subsection "slots" } ;
 
 ARTICLE: "numbers" "Numbers"
 { $subsection "arithmetic" }
@@ -118,9 +119,9 @@ ARTICLE: "collections" "Collections"
 "Fixed-length sequences:"
 { $subsection "arrays" }
 { $subsection "quotations" }
-"Fixed-length specialized sequences:"
 { $subsection "strings" }
 { $subsection "byte-arrays" }
+{ $subsection "specialized-arrays" }
 "Resizable sequences:"
 { $subsection "vectors" }
 { $subsection "byte-vectors" }
@@ -128,7 +129,8 @@ ARTICLE: "collections" "Collections"
 { $subsection "growable" }
 { $heading "Associative mappings" }
 { $subsection "assocs" }
-{ $subsection "namespaces" }
+{ $subsection "linked-assocs" }
+{ $subsection "biassocs" }
 { $subsection "refs" }
 "Implementations:"
 { $subsection "hashtables" }
@@ -140,26 +142,29 @@ ARTICLE: "collections" "Collections"
 { $subsection "dlists" }
 { $subsection "search-deques" }
 { $heading "Other collections" }
-{ $subsection "boxes" }
+{ $subsection "lists" }
+{ $subsection "disjoint-sets" }
+{ $subsection "interval-maps" }
 { $subsection "heaps" }
+{ $subsection "boxes" }
 { $subsection "graphs" }
 { $subsection "buffers" }
 "There are also many other vocabularies tagged " { $link T{ vocab-tag { name "collections" } } } " in the library." ;
 
-USING: io.encodings.utf8 io.encodings.utf16 io.encodings.binary io.encodings.ascii io.files ;
+USING: io.encodings.utf8 io.encodings.binary io.files ;
 
 ARTICLE: "encodings-introduction" "An introduction to encodings"
 "In order to express text in terms of binary, some sort of encoding has to be used. In a modern context, this is understood as a two-way mapping between Unicode code points (characters) and some amount of binary. Since English isn't the only language in the world, ASCII is not sufficient as a mapping from binary to Unicode; it can't even express em-dashes or curly quotes. Unicode was designed as a universal character set that could potentially represent everything." $nl
 "Not all encodings can represent all Unicode code points, but Unicode can represent basically everything that exists in modern encodings. Some encodings are language-specific, and some can represent everything in Unicode. Though the world is moving toward Unicode and UTF-8, the reality today is that there are several encodings which must be taken into account." $nl
-"Factor uses a system of encoding descriptors to denote encodings. Encoding descriptors are objects which describe encodings. Examples are " { $link utf8 } ", " { $link ascii } " and " { $link binary } ". Encoding descriptors can be passed around independently. Each encoding descriptor has some method for constructing an encoded or decoded stream, and the resulting stream has an encoding descriptor stored which has methods for reading or writing characters." $nl
+"Factor uses a system of encoding descriptors to denote encodings. Encoding descriptors are objects which describe encodings. Examples are " { $link utf8 } " and " { $link binary } ". Encoding descriptors can be passed around independently. Each encoding descriptor has some method for constructing an encoded or decoded stream, and the resulting stream has an encoding descriptor stored which has methods for reading or writing characters." $nl
 "Constructors for streams which deal with bytes usually take an encoding as an explicit parameter. For example, to open a text file for reading whose contents are in UTF-8, use the following"
 { $code "\"file.txt\" utf8 <file-reader>" }
 "If there is an error in the encoded stream, a replacement character (0xFFFD) will be inserted. To throw an exception upon error, use a strict encoding as follows"
 { $code "\"file.txt\" utf8 strict <file-reader>" }
 "In a similar way, encodings can be specified when opening a file for writing."
-{ $code "\"file.txt\" ascii <file-writer>" }
+{ $code "USE: io.encodings.ascii" "\"file.txt\" ascii <file-writer>" }
 "An encoding is also needed for some words that don't return streams, such as " { $link file-contents } ", for example"
-{ $code "\"file.txt\" utf16 file-contents" }
+{ $code "USE: io.encodings.utf16" "\"file.txt\" utf16 file-contents" }
 "Encoding descriptors are also used by " { $link "io.streams.byte-array" } " and taken by combinators like " { $link with-file-writer } " and " { $link with-byte-reader } " which deal with streams. It is " { $emphasis "not" } " used with " { $link "io.streams.string" } " because these deal with abstract text."
 $nl
 "When the " { $link binary } " encoding is used, a " { $link byte-array } " is expected for writing and returned for reading, since the stream deals with bytes. All other encodings deal with strings, since they are used to represent text." ;
@@ -239,40 +244,57 @@ ARTICLE: "class-index" "Class index"
 { $heading "Predicate classes" }
 { $index [ classes [ predicate-class? ] filter ] } ;
 
-ARTICLE: "program-org" "Program organization"
-{ $subsection "definitions" }
-{ $subsection "vocabularies" }
-{ $subsection "parser" }
-{ $subsection "vocabs.loader" }
-{ $subsection "source-files" } ;
-
 USING: help.cookbook help.tutorial ;
 
 ARTICLE: "handbook-language-reference" "Language reference"
+"Fundamentals:"
 { $subsection "conventions" }
 { $subsection "syntax" }
-{ $subsection "dataflow" }
-{ $subsection "objects" }
-{ $subsection "program-org" }
+{ $subsection "effects" }
+"Data types:"
+{ $subsection "booleans" }
 { $subsection "numbers" }
 { $subsection "collections" }
-{ $subsection "io" }
+"Evaluation semantics:"
+{ $subsection "evaluator" }
+{ $subsection "words" }
+{ $subsection "shuffle-words" }
+{ $subsection "combinators" }
+{ $subsection "errors" }
+{ $subsection "continuations" }
+"Named values:"
+{ $subsection "locals" }
+{ $subsection "namespaces" }
+{ $subsection "namespaces-global" }
+{ $subsection "values" }
+"Abstractions:"
+{ $subsection "objects" }
+{ $subsection "destructors" }
+{ $subsection "macros" }
+{ $subsection "fry" }
+"Program organization:"
+{ $subsection "vocabs.loader" }
 "Vocabularies tagged " { $link T{ vocab-tag { name "extensions" } } } " implement various additional language abstractions." ;
 
 ARTICLE: "handbook-environment-reference" "Environment reference"
+"Parse time and compile time:"
+{ $subsection "parser" }
+{ $subsection "definitions" }
+{ $subsection "vocabularies" }
+{ $subsection "source-files" }
+{ $subsection "compiler" }
+"Tools:"
 { $subsection "prettyprint" }
 { $subsection "tools" }
-{ $subsection "cli" }
-{ $subsection "rc-files" }
 { $subsection "help" }
 { $subsection "inference" }
-{ $subsection "compiler" }
-{ $subsection "system" }
 { $subsection "images" }
-{ $subsection "alien" }
+"VM:"
+{ $subsection "cli" }
+{ $subsection "rc-files" }
 { $subsection "init" }
-{ $subsection "layouts" }
-{ $see-also "program-org" } ;
+{ $subsection "system" }
+{ $subsection "layouts" } ;
 
 ARTICLE: "handbook-library-reference" "Library reference"
 "This index only includes articles from loaded vocabularies. To explore more vocabularies, see " { $link "vocab-index" } "."
@@ -282,9 +304,14 @@ ARTICLE: "handbook" "Factor handbook"
 "Learn the language:"
 { $subsection "cookbook" }
 { $subsection "first-program" }
+"Reference material:"
 { $subsection "handbook-language-reference" }
 { $subsection "handbook-environment-reference" }
+{ $subsection "io" }
 { $subsection "ui" }
+{ $subsection "ui-tools" }
+{ $subsection "unicode" }
+{ $subsection "alien" }
 { $subsection "handbook-library-reference" }
 "Explore loaded libraries:"
 { $subsection "article-index" }
index 6608a6e9c0eaee311f74d1fb595dfa68a4e6e8db..e6db2d3b9c3c7e400cb7c1b651ae8bf5006f0701 100644 (file)
@@ -8,7 +8,6 @@ ARTICLE: "help.home" "Factor documentation"
   { $link "handbook" }
   { $link "vocab-index" }
   { $link "ui-tools" }
-  { $link "handbook-library-reference" }
 }
 { $heading "Recently visited" }
 { $table
diff --git a/basis/help/syntax/tags.txt b/basis/help/syntax/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
index 804ef035f45f178eb64183c346fe4f1c5f259132..6fece31d88845baf6f7d75407405ce2c18e8e6a4 100644 (file)
@@ -65,7 +65,6 @@ M: object specializer-declaration class ;
 
 SYNTAX: HINTS:
     scan-object
-    dup method-spec? [ first2 method ] when
     [ redefined ]
     [ parse-definition "specializer" set-word-prop ] bi ;
 
@@ -119,6 +118,6 @@ SYNTAX: HINTS:
 
 \ >be { { bignum fixnum } { fixnum fixnum } } "specializer" set-word-prop
 
-\ hashtable \ at* method { { fixnum object } { word object } } "specializer" set-word-prop
+M\ hashtable at* { { fixnum object } { word object } } "specializer" set-word-prop
 
-\ hashtable \ set-at method { { object fixnum object } { object word object } } "specializer" set-word-prop
+M\ hashtable set-at { { object fixnum object } { object word object } } "specializer" set-word-prop
diff --git a/basis/interpolate/tags.txt b/basis/interpolate/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
index 18dabed4b039518e3b559e65273560a28b2b124c..b1f0b6ca1732b3d59b6092d32b665c1d04d08ea2 100644 (file)
@@ -112,7 +112,15 @@ HELP: MEMO::
 { $description "Defines a memoized word with named inputs; it reads stack values into bindings from left to right, then executes the body with those bindings in lexical scope." } ;
 
 { POSTPONE: MEMO: POSTPONE: MEMO:: } related-words
+                                          
+HELP: M::
+{ $syntax "M:: class generic ( bindings... -- outputs... ) body... ;" }
+{ $description "Defines a method with named inputs; it reads stack values into bindings from left to right, then executes the body with those bindings in lexical scope." }
+{ $notes "The output names do not affect the word's behavior, however the compiler attempts to check the stack effect as with other definitions." } ;
+
+{ POSTPONE: M: POSTPONE: M:: } related-words
 
+                                                 
 ARTICLE: "locals-literals" "Locals in literals"
 "Certain data type literals are permitted to contain free variables. Any such literals are written into code which constructs an instance of the type with the free variable values spliced in. Conceptually, this is similar to the transformation applied to quotations containing free variables."
 $nl
@@ -237,13 +245,14 @@ $nl
 }
 "The reason is that locals are rewritten into stack code at parse time, whereas macro expansion is performed later during compile time. To circumvent this problem, the " { $vocab-link "macros.expander" } " vocabulary is used to rewrite simple macro usages prior to local transformation, however "{ $vocab-link "macros.expander" } " does not deal with more complicated cases where the literal inputs to the macro do not immediately precede the macro call in the source." ;
 
-ARTICLE: "locals" "Local variables and lexical closures"
+ARTICLE: "locals" "Lexical variables and closures"
 "The " { $vocab-link "locals" } " vocabulary implements lexical scope with full closures, both downward and upward. Mutable bindings are supported, including assignment to bindings in outer scope."
 $nl
 "Compile-time transformation is used to compile local variables to efficient code; prettyprinter extensions are defined so that " { $link see } " can display original word definitions with local variables and not the closure-converted concatenative code which results."
 $nl
 "Applicative word definitions where the inputs are named local variables:"
 { $subsection POSTPONE: :: }
+{ $subsection POSTPONE: M:: }
 { $subsection POSTPONE: MEMO:: }
 { $subsection POSTPONE: MACRO:: }
 "Lexical binding forms:"
index 8e61e39faf8a511f9b8891b2ccdf0f7fa344a19c..5e61c1ddfd45f0b881417557dcf7e9326d9547b4 100644 (file)
@@ -455,7 +455,7 @@ GENERIC: lambda-method-forget-test ( a -- b )
 
 M:: integer lambda-method-forget-test ( a -- b ) ;
 
-[ ] [ [ { integer lambda-method-forget-test } forget ] with-compilation-unit ] unit-test
+[ ] [ [ M\ integer lambda-method-forget-test forget ] with-compilation-unit ] unit-test
 
 [ 10 ] [ 10 [| A | { [ A ] } ] call first call ] unit-test
 
index 8987def80bbae6727504c3d32449e4d2de93089c..e35adb10e55e7b0d16b7b2ff3165f7eb64f5b002 100644 (file)
@@ -2,7 +2,7 @@ USING: help.syntax help.markup arrays sequences ;
 
 IN: math.ranges
 
-ARTICLE: "ranges" "Ranges"
+ARTICLE: "math.ranges" "Numeric ranges"
 "A " { $emphasis "range" } " is a virtual sequence with real number elements "
 "ranging from " { $emphasis "a" } " to " { $emphasis "b" } " by " { $emphasis "step" } ". Ascending as well as descending ranges are supported."
 $nl
@@ -24,4 +24,4 @@ $nl
 { $code "100 1 [a,b] product" }
 "A range can be converted into a concrete sequence using a word such as " { $link >array } ". In most cases this is unnecessary since ranges implement the sequence protocol already. It is necessary if a mutable sequence is needed, for use with words such as " { $link set-nth } " or " { $link change-each } "." ;
   
-ABOUT: "ranges"
\ No newline at end of file
+ABOUT: "math.ranges"
\ No newline at end of file
diff --git a/basis/models/arrow/smart/smart-docs.factor b/basis/models/arrow/smart/smart-docs.factor
new file mode 100644 (file)
index 0000000..45faf52
--- /dev/null
@@ -0,0 +1,21 @@
+IN: models.arrow.smart
+USING: help.syntax help.markup models.product ;
+
+HELP: <smart-arrow>
+{ $values { "quot" { $quotation "( ... -- output )" } } }
+{ $description "A macro that expands into a form with the stack effect of the quotation. The form constructs a model which applies the quotation to values from an underlying " { $link product } " model having as many components as the quotation has inputs." }
+{ $examples
+  "A model which adds the values of two existing models:"
+  { $example
+    "USING: models models.arrows.smart accessors math prettyprint ;"
+    "1 <model> 2 <model> [ + ] <smart-arrow>"
+    "[ activate-model ] [ value>> ] bi ."
+    "3"
+  }
+} ;
+
+ARTICLE: "models.arrows.smart" "Smart arrow models"
+"The " { $vocab-link "models.arrows.smart" } " vocabulary generalizes arrows to arbitrary input arity. They're called “smart” because they resemble " { $link "combinators.smart" } "."
+{ $subsection <smart-arrow> } ;
+
+ABOUT: "models.arrows.smart"
\ No newline at end of file
index 5af5dba74811bd315ffe3b3b2e9775ea15fca681..1ccdafb2bbe27ecce00b298124ca756bc956f389 100644 (file)
@@ -1,2 +1,3 @@
+extensions
 text
 parsing
index bcd91a4d942a5970be9c6c61f04e5ca71ae51638..8004c1141fb978a2b136b69c794c490789076d84 100644 (file)
@@ -41,18 +41,18 @@ M: effect pprint* effect>string "(" ")" surround text ;
 : pprint-prefix ( word quot -- )
     <block swap pprint-word call block> ; inline
 
+M: parsing-word pprint*
+    \ POSTPONE: [ pprint-word ] pprint-prefix ;
+
 M: word pprint*
-    dup parsing-word? [
-        \ POSTPONE: [ pprint-word ] pprint-prefix
-    ] [
-        {
-            [ "break-before" word-prop line-break ]
-            [ pprint-word ]
-            [ ?start-group ]
-            [ ?end-group ]
-            [ "break-after" word-prop line-break ]
-        } cleave
-    ] if ;
+    [ pprint-word ] [ ?start-group ] [ ?end-group ] tri ;
+
+M: method-body pprint*
+    <block
+    \ M\ pprint-word
+    [ "method-class" word-prop pprint-word ]
+    [ "method-generic" word-prop pprint-word ] bi
+    block> ;
 
 M: real pprint* number>string text ;
 
@@ -206,8 +206,8 @@ M: curry pprint* pprint-object ;
 M: compose pprint* pprint-object ;
 
 M: wrapper pprint*
-    dup wrapped>> word? [
-        <block \ \ pprint-word wrapped>> pprint-word block>
-    ] [
-        pprint-object
-    ] if ;
+    {
+        { [ dup wrapped>> method-body? ] [ wrapped>> pprint* ] }
+        { [ dup wrapped>> word? ] [ <block \ \ pprint-word wrapped>> pprint-word block> ] }
+        [ pprint-object ]
+    } cond ;
index 7e37aa0da57fe910de07c6c7c6a73543191a731f..799d500c188256ac8a6c2de5d6e7f293b7658bba 100644 (file)
@@ -180,28 +180,6 @@ DEFER: parse-error-file
     "string-layout-test" string-layout check-see
 ] unit-test
 
-! Define dummy words for the below...
-: <NSRect> ( a b c d -- e ) ;
-: <PixelFormat> ( -- fmt ) ;
-: send ( obj -- ) ;
-
-\ send soft "break-after" set-word-prop
-
-: final-soft-break-test ( -- str )
-    {
-        "USING: kernel sequences ;"
-        "IN: prettyprint.tests"
-        ": final-soft-break-layout ( class dim -- view )"
-        "    [ \"alloc\" send 0 0 ] dip first2 <NSRect>"
-        "    <PixelFormat> \"initWithFrame:pixelFormat:\" send"
-        "    dup 1 \"setPostsBoundsChangedNotifications:\" send"
-        "    dup 1 \"setPostsFrameChangedNotifications:\" send ;"
-    } ;
-
-[ t ] [
-    "final-soft-break-layout" final-soft-break-test check-see
-] unit-test
-
 : narrow-test ( -- str )
     {
         "USING: arrays combinators continuations kernel sequences ;"
@@ -300,11 +278,7 @@ GENERIC: generic-see-test-with-f ( obj -- obj )
 M: f generic-see-test-with-f ;
 
 [ "USING: prettyprint.tests ;\nM: f generic-see-test-with-f ;\n" ] [
-    [ { POSTPONE: f generic-see-test-with-f } see ] with-string-writer
-] unit-test
-
-[ "USING: prettyprint.tests ;\nM: f generic-see-test-with-f ;\n" ] [
-    [ \ f \ generic-see-test-with-f method see ] with-string-writer
+    [ M\ f generic-see-test-with-f see ] with-string-writer
 ] unit-test
 
 PREDICATE: predicate-see-test < integer even? ;
@@ -331,5 +305,5 @@ GENERIC: ended-up-ballin' ( a -- b )
 M: started-out-hustlin' ended-up-ballin' ; inline
 
 [ "USING: prettyprint.tests ;\nM: started-out-hustlin' ended-up-ballin' ; inline\n" ] [
-    [ { started-out-hustlin' ended-up-ballin' } see ] with-string-writer
+    [ M\ started-out-hustlin' ended-up-ballin' see ] with-string-writer
 ] unit-test
index 6d51b42a86c11214ae7f29a92e36cddcf7fefbd2..b2e99843c7ca230e641f456a2e745699382d01a7 100644 (file)
@@ -13,7 +13,12 @@ HELP: synopsis*
 
 HELP: see
 { $values { "defspec" "a definition specifier" } }
-{ $contract "Prettyprints a definition." } ;
+{ $contract "Prettyprints a definition." }
+{ $examples
+  "A word:" { $code "\\ append see" }
+  "A method:" { $code "USE: arrays" "M\\ array length see" }
+  "A help article:" { $code "USE: help.topics" "\"help\" >link see" }
+} ;
 
 HELP: see-methods
 { $values { "word" "a " { $link generic } " or a " { $link class } } }
index 9fc14ff5813b3509df0ec778c76d50e6b0e89551..2494c72fa4134b6e12cc8f884e69b19f2ab7dd38 100644 (file)
@@ -76,9 +76,6 @@ M: hook-generic synopsis*
         [ stack-effect. ]
     } cleave ;
 
-M: method-spec synopsis*
-    first2 method synopsis* ;
-
 M: method-body synopsis*
     [ definer. ]
     [ "method-class" word-prop pprint-word ]
@@ -122,9 +119,6 @@ M: object see*
         block>
     ] with-use ;
 
-M: method-spec see*
-    first2 method see* ;
-
 GENERIC: see-class* ( word -- )
 
 M: union-class see-class*
index f47852aca754115dcb54d1f9ec944c27f748b8e4..9fa9d1e2aa1b317c401dbf762fe285eff76e91e2 100644 (file)
@@ -43,6 +43,6 @@ GENERIC: blah-generic ( a -- b )
 
 M: string blah-generic ;
 
-{ string blah-generic } watch
+[ ] [ M\ string blah-generic watch ] unit-test
 
 [ "hi" ] [ "hi" blah-generic ] unit-test
index 8c3d95f2b877e017892ebf2074fbc5c74cc2f91a..64e6508ab62e34f45022872dbd1e638514b65667 100644 (file)
@@ -20,9 +20,6 @@ M: word reset
         f "unannotated-def" set-word-prop
     ] [ drop ] if ;
 
-M: method-spec reset
-    first2 method reset ;
-
 ERROR: cannot-annotate-twice word ;
 
 <PRIVATE
@@ -32,9 +29,6 @@ ERROR: cannot-annotate-twice word ;
         cannot-annotate-twice
     ] when ;
 
-: method-spec>word ( obj -- word )
-    dup method-spec? [ first2 method ] when ;
-
 : save-unannotated-def ( word -- )
     dup def>> "unannotated-def" set-word-prop ;
 
@@ -44,7 +38,7 @@ ERROR: cannot-annotate-twice word ;
 PRIVATE>
 
 : annotate ( word quot -- )
-    [ method-spec>word check-annotate-twice ] dip
+    [ check-annotate-twice ] dip
     [ over save-unannotated-def (annotate) ] with-compilation-unit ;
 
 <PRIVATE
@@ -103,9 +97,6 @@ M: generic annotate-methods
 M: word annotate-methods
     annotate ;
 
-M: method-spec annotate-methods
-    annotate ;
-
 : breakpoint ( word -- )
     [ add-breakpoint ] annotate-methods ;
 
index 79335fd0320ebf37ace7db5fab04693a7ec2e0e3..7c9a38796b5de053f56b9a0a3ba4c4f8c1bd64ff 100755 (executable)
@@ -170,8 +170,6 @@ IN: tools.deploy.shaker
         
         strip-prettyprint? [
             {
-                "break-before"
-                "break-after"
                 "delimiter"
                 "flushable"
                 "foldable"
index 96f5a043788c83f6113bfeddbb347c513aabf709..49cfb054a13e03b44240c9379edc0939025f64e7 100644 (file)
@@ -3,4 +3,4 @@ USING: math classes.tuple prettyprint.custom
 tools.disassembler tools.test strings ;\r
 \r
 [ ] [ \ + disassemble ] unit-test\r
-[ ] [ { string pprint* } disassemble ] unit-test\r
+[ ] [ M\ string pprint* disassemble ] unit-test\r
index 83b7dfef81b70e7db97d78bf7ae2fbf49c0cba22..744318a0a435c580d670e3c89a37f1aa1e371c43 100755 (executable)
@@ -16,8 +16,6 @@ M: pair disassemble first2 disassemble* [ tabs>spaces print ] each ;
 
 M: word disassemble word-xt 2array disassemble ;
 
-M: method-spec disassemble first2 method disassemble ;
-
 cpu x86?
 "tools.disassembler.udis"
 "tools.disassembler.gdb" ?
index 20b16f450a9693cfeeecd6fea1fc34e61a46651e..454e4700a0ac78f6bd120afc6459493824436c95 100644 (file)
@@ -1,7 +1,13 @@
-USING: namespaces ui.tools.browser.history sequences tools.test ;
+USING: namespaces ui.tools.browser.history sequences tools.test
+accessors kernel ;
 IN: ui.tools.browser.history.tests
 
-f <history> "history" set
+TUPLE: dummy obj ;
+
+M: dummy history-value obj>> ;
+M: dummy set-history-value (>>obj) ;
+
+dummy new <history> "history" set
 
 "history" get add-history
 
@@ -9,27 +15,27 @@ f <history> "history" set
 [ t ] [ "history" get forward>> empty? ] unit-test
 
 "history" get add-history
-"history" get 3 >>value drop
+3 "history" get owner>> set-history-value
 
 [ t ] [ "history" get back>> empty? ] unit-test
 [ t ] [ "history" get forward>> empty? ] unit-test
 
 "history" get add-history
-"history" get 4 >>value drop
+4 "history" get owner>> set-history-value
 
 [ f ] [ "history" get back>> empty? ] unit-test
 [ t ] [ "history" get forward>> empty? ] unit-test
 
 "history" get go-back
 
-[ 3 ] [ "history" get value>> ] unit-test
+[ 3 ] [ "history" get owner>> history-value ] unit-test
 
 [ t ] [ "history" get back>> empty? ] unit-test
 [ f ] [ "history" get forward>> empty? ] unit-test
 
 "history" get go-forward
 
-[ 4 ] [ "history" get value>> ] unit-test
+[ 4 ] [ "history" get owner>> history-value ] unit-test
 
 [ f ] [ "history" get back>> empty? ] unit-test
 [ t ] [ "history" get forward>> empty? ] unit-test
index 93f45591a540bb65e1b65bae425143a160964dce..52cd77d7263cdb656b02bad68248c59eca720dd1 100644 (file)
@@ -55,7 +55,7 @@ $nl
 
 ARTICLE: "ui-tools" "UI developer tools"
 "The " { $vocab-link "ui.tools" } " vocabulary hierarchy implements a collection of simple developer tools."
-$nl
+{ $subsection "starting-ui-tools" }
 "To take full advantage of the UI tools, you should be using a supported text editor. See " { $link "editor" } "."
 $nl
 "Common functionality:"
@@ -66,7 +66,7 @@ $nl
 { $subsection "ui-listener" }
 { $subsection "ui-browser" }
 { $subsection "ui-inspector" }
-{ $subsection "ui-profiler" }
+{ $subsection "ui.tools.profiler" }
 { $subsection "ui-walker" }
 { $subsection "ui.tools.deploy" }
 "Platform-specific features:"
diff --git a/basis/ui/traverse/traverse-docs.factor b/basis/ui/traverse/traverse-docs.factor
new file mode 100644 (file)
index 0000000..e69de29
index e18637a652da2af05897f4f2f526237190266f62..4d2072db1c70e6448f6bedded25ec3f258fa4145 100644 (file)
@@ -62,4 +62,4 @@ M: object (flatten-tree) , ;
     { 0 1 } { 2 0 1 } { { "a" "b" "c" "d" } { "e" "f" "g" } { { "h" "i" } "j" } } gadgets-in-range
 ] unit-test
 
-[ { array children>> } forget ] with-compilation-unit
+[ M\ array children>> forget ] with-compilation-unit
index 9450b49f0bd2f14bae20dcc19c15ecfb7093f92c..56432585c0fac349dc4840d5e847df9db8df9cdd 100644 (file)
@@ -1,7 +1,7 @@
 USING: help.markup help.syntax strings ;
 IN: unicode
 
-ARTICLE: "unicode" "Unicode"
+ARTICLE: "unicode" "Unicode support"
 "The " { $vocab-link "unicode" } " vocabulary and its sub-vocabularies implement support for the Unicode 5.1 character set."
 $nl
 "The Unicode character set contains most of the world's writing systems. Unicode is intended as a replacement for, and is a superset of, such legacy character sets as ASCII, Latin1, MacRoman, and so on. Unicode characters are called " { $emphasis "code points" } "; Factor's " { $link "strings" } " are sequences of code points."
index df38869fbf35ae52a5f5cb53555a848172580df1..7c96f19ac9fd40830464f1a890a36c3fe421effa 100644 (file)
@@ -2,7 +2,7 @@ USING: help.markup help.syntax ;
 IN: values\r
 \r
 ARTICLE: "values" "Global values"\r
-"Usually, dynamically scoped variables are sufficient for holding data which is not literal. But occasionally, for global information that's calculated just once, it's useful to use the word mechanism instead, and set the word to the appropriate value just once. The " { $vocab-link "values" } " vocabulary implements " { $emphasis "values" } ", which abstract over this concept. To create a new word as a value, use the following syntax:"\r
+"Usually, dynamically-scoped variables subsume global variables and are sufficient for holding global data. But occasionally, for global information that's calculated just once and must be accessed more rapidly than a dynamic variable lookup can provide, it's useful to use the word mechanism instead, and set a word to the appropriate value just once. The " { $vocab-link "values" } " vocabulary implements " { $emphasis "values" } ", which abstract over this concept. To create a new word as a value, use the following syntax:"\r
 { $subsection POSTPONE: VALUE: }\r
 "To get the value, just call the word. The following words manipulate values:"\r
 { $subsection get-value }\r
index 71c0ff728276e0787cbda7cfcb9e0b4656368f1e..4f4a20b1cb83326b5706914cdb913f14055e1d0b 100644 (file)
@@ -1 +1,2 @@
+extensions
 syntax
index 6e6812e25c3ca3e1c098bc75bfc6f49530ed3489..a0b349be51b9e2c2731297f450e599d2d8cd29bb 100644 (file)
@@ -62,6 +62,7 @@ IN: bootstrap.syntax
     "W{"
     "["
     "\\"
+    "M\\"
     "]"
     "delimiter"
     "f"
index eded33beed3788bbd69e21493204f151b7349229..ab8ba398cda09ad22208424f97005a127b423977 100644 (file)
@@ -174,8 +174,7 @@ GENERIC: update-methods ( class seq -- )
         [ forget ] [ drop ] if
     ] [ 2drop ] if ;
 
-: forget-methods ( class -- )
-    [ implementors ] [ [ swap 2array ] curry ] bi map forget-all ;
+GENERIC: forget-methods ( class -- )
 
 GENERIC: class-forgotten ( use class -- )
 
index fa2df4e3121c18507b42b460f81209e763cb763f..75d733b213213c7d22e35224a62a35c4bd13943c 100644 (file)
@@ -133,7 +133,7 @@ M: integer forget-robustness-generic ;
 [
     [ ] [ \ forget-robustness-generic forget ] unit-test
     [ ] [ \ forget-robustness forget ] unit-test
-    [ ] [ { forget-robustness forget-robustness-generic } forget ] unit-test
+    [ ] [ M\ forget-robustness forget-robustness-generic forget ] unit-test
 ] with-compilation-unit
 
 ! rapido found this one
@@ -559,7 +559,7 @@ DEFER: subclass-reset-test-3
 
 GENERIC: break-me ( obj -- )
 
-[ ] [ [ { integer break-me } forget ] with-compilation-unit ] unit-test
+[ ] [ [ M\ integer break-me forget ] with-compilation-unit ] unit-test
 
 [ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test ;" <string-reader> "subclass-reset-test" parse-stream drop ] unit-test
 [ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test-1 < subclass-reset-test ;" eval ] unit-test
index cc502140ad18db3284fab98ee088b2144ab7f20f..9c96fe34c9d1f75badaba22d20e92676198237c9 100644 (file)
@@ -4,46 +4,313 @@ math assocs sequences sequences.private combinators.private
 effects words ;
 IN: combinators
 
+ARTICLE: "cleave-shuffle-equivalence" "Expressing shuffle words with cleave combinators"
+"Cleave combinators are defined in terms of shuffle words, and mappings from certain shuffle idioms to cleave combinators are discussed in the documentation for " { $link bi } ", " { $link 2bi } ", " { $link 3bi } ", " { $link tri } ", " { $link 2tri } " and " { $link 3tri } "."
+$nl
+"Certain shuffle words can also be expressed in terms of the cleave combinators. Internalizing such identities can help with understanding and writing code using cleave combinators:"
+{ $code
+    ": keep  [ ] bi ;"
+    ": 2keep [ ] 2bi ;"
+    ": 3keep [ ] 3bi ;"
+    ""
+    ": dup   [ ] [ ] bi ;"
+    ": 2dup  [ ] [ ] 2bi ;"
+    ": 3dup  [ ] [ ] 3bi ;"
+    ""
+    ": tuck  [ nip ] [ ] 2bi ;"
+    ": swap  [ nip ] [ drop ] 2bi ;"
+    ""
+    ": over  [ ] [ drop ] 2bi ;"
+    ": pick  [ ] [ 2drop ] 3bi ;"
+    ": 2over [ ] [ drop ] 3bi ;"
+} ;
+
+ARTICLE: "cleave-combinators" "Cleave combinators"
+"The cleave combinators apply multiple quotations to a single value."
+$nl
+"Two quotations:"
+{ $subsection bi }
+{ $subsection 2bi }
+{ $subsection 3bi }
+"Three quotations:"
+{ $subsection tri }
+{ $subsection 2tri }
+{ $subsection 3tri }
+"An array of quotations:"
+{ $subsection cleave }
+{ $subsection 2cleave }
+{ $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:"
+{ $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."
+{ $subsection "cleave-shuffle-equivalence" } ;
+
+ARTICLE: "spread-shuffle-equivalence" "Expressing shuffle words with spread combinators"
+"Spread combinators are defined in terms of shuffle words, and mappings from certain shuffle idioms to spread combinators are discussed in the documentation for " { $link bi* } ", " { $link 2bi* } ", " { $link tri* } ", and " { $link 2tri* } "."
+$nl
+"Certain shuffle words can also be expressed in terms of the spread combinators. Internalizing such identities can help with understanding and writing code using spread combinators:"
+{ $code
+    ": dip   [ ] bi* ;"
+    ": 2dip  [ ] [ ] tri* ;"
+    ""
+    ": slip  [ call ] [ ] bi* ;"
+    ": 2slip [ call ] [ ] [ ] tri* ;"
+    ""
+    ": nip   [ drop ] [ ] bi* ;"
+    ": 2nip  [ drop ] [ drop ] [ ] tri* ;"
+    ""
+    ": rot"
+    "    [ [ drop ] [      ] [ drop ] tri* ]"
+    "    [ [ drop ] [ drop ] [      ] tri* ]"
+    "    [ [      ] [ drop ] [ drop ] tri* ]"
+    "    3tri ;"
+    ""
+    ": -rot"
+    "    [ [ drop ] [ drop ] [      ] tri* ]"
+    "    [ [      ] [ drop ] [ drop ] tri* ]"
+    "    [ [ drop ] [      ] [ drop ] tri* ]"
+    "    3tri ;"
+    ""
+    ": spin"
+    "    [ [ drop ] [ drop ] [      ] tri* ]"
+    "    [ [ drop ] [      ] [ drop ] tri* ]"
+    "    [ [      ] [ drop ] [ drop ] tri* ]"
+    "    3tri ;"
+} ;
+
+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* }
+{ $subsection 2tri* }
+"An array of quotations:"
+{ $subsection 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:"
+{ $code
+    "! First alternative; uses dip"
+    "[ [ 1 + ] dip 1 - ] dip 2 *"
+    "! Second alternative: uses tri*"
+    "[ 1 + ] [ 1 - ] [ 2 * ] tri*"
+}
+"A generalization of the above combinators to any number of quotations can be found in " { $link "combinators" } "."
+{ $subsection "spread-shuffle-equivalence" } ;
+
+ARTICLE: "apply-combinators" "Apply combinators"
+"The apply combinators apply a single quotation to multiple values. The " { $snippet "@" } " suffix signifies application."
+$nl
+"Two quotations:"
+{ $subsection bi@ }
+{ $subsection 2bi@ }
+"Three quotations:"
+{ $subsection tri@ }
+{ $subsection 2tri@ }
+"A pair of utility words built from " { $link bi@ } ":"
+{ $subsection both? }
+{ $subsection either? } ;
+
+ARTICLE: "slip-keep-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."
+$nl
+"The dip combinators invoke the quotation at the top of the stack, hiding the values underneath:"
+{ $subsection dip }
+{ $subsection 2dip }
+{ $subsection 3dip }
+{ $subsection 4dip }
+"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 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: "curried-dataflow" "Curried dataflow combinators"
+"Curried cleave combinators:"
+{ $subsection bi-curry }
+{ $subsection tri-curry }
+"Curried spread combinators:"
+{ $subsection bi-curry* }
+{ $subsection tri-curry* }
+"Curried apply combinators:"
+{ $subsection bi-curry@ }
+{ $subsection tri-curry@ }
+{ $see-also "dataflow-combinators" } ;
+
+ARTICLE: "compositional-examples" "Examples of compositional combinator usage"
+"Consider printing the same message ten times:"
+{ $code ": print-10 ( -- ) 10 [ \"Hello, world.\" print ] times ;" }
+"if we wanted to abstract out the message into a parameter, we could keep it on the stack between iterations:"
+{ $code ": print-10 ( message -- ) 10 [ dup print ] times drop ;" }
+"However, keeping loop-invariant values on the stack doesn't always work out nicely. For example, a word to subtract a value from each element of a sequence:"
+{ $code ": subtract-n ( seq n -- seq' ) swap [ over - ] map nip ;" }
+"Three shuffle words are required to pass the value around. Instead, the loop-invariant value can be partially applied to a quotation using " { $link curry } ", yielding a new quotation that is passed to " { $link map } ":"
+{ $example
+  "USING: kernel math prettyprint sequences ;"
+  ": subtract-n ( seq n -- seq' ) [ - ] curry map ;"
+  "{ 10 20 30 } 5 subtract-n ."
+  "{ 5 15 25 }"
+}
+"Now consider the word that is dual to the one above; instead of subtracting " { $snippet "n" } " from each stack element, it subtracts each element from " { $snippet "n" } "."
+$nl
+"One way to write this is with a pair of " { $link swap } "s:"
+{ $code ": n-subtract ( n seq -- seq' ) swap [ swap - ] curry map ;" }
+"Since this pattern comes up often, " { $link with } " encapsulates it:"
+{ $example
+  "USING: kernel math prettyprint sequences ;"
+  ": n-subtract ( n seq -- seq' ) [ - ] with map ;"
+  "30 { 10 20 30 } n-subtract ."
+  "{ 20 10 0 }"
+}
+{ $see-also "fry.examples" } ;
+
+ARTICLE: "compositional-combinators" "Compositional combinators"
+"Certain combinators transform quotations to produce a new quotation."
+{ $subsection "compositional-examples" }
+"Fundamental operations:"
+{ $subsection curry }
+{ $subsection compose }
+"Derived operations:"
+{ $subsection 2curry }
+{ $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."
+$nl
+"Curried dataflow combinators can be used to build more complex dataflow by combining cleave, spread and apply patterns in various ways."
+{ $subsection "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." ;
+
+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."
+{ $subsection f }
+{ $subsection t }
+"There are some logical operations on booleans:"
+{ $subsection >boolean }
+{ $subsection not }
+{ $subsection and }
+{ $subsection or }
+{ $subsection xor }
+"Boolean values are most frequently used for " { $link "conditionals" } "."
+{ $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."
+$nl
+"Here is the " { $link f } " object:"
+{ $example "f ." "f" }
+"Here is the " { $link f } " class:"
+{ $example "\\ f ." "POSTPONE: f" }
+"They are not equal:"
+{ $example "f \\ f = ." "f" }
+"Here is an array containing the " { $link f } " object:"
+{ $example "{ f } ." "{ f }" }
+"Here is an array containing the " { $link f } " class:"
+{ $example "{ POSTPONE: f } ." "{ POSTPONE: f }" }
+"The " { $link f } " object is an instance of the " { $link f } " class:"
+{ $example "USE: classes" "f class ." "POSTPONE: f" }
+"The " { $link f } " class is an instance of " { $link word } ":"
+{ $example "USE: classes" "\\ f class ." "word" }
+"On the other hand, " { $link t } " is just a word, and there is no class which it is a unique instance of."
+{ $example "t \\ t eq? ." "t" }
+"Many words which search collections confuse the case of no element being present with an element being found equal to " { $link f } ". If this distinction is imporant, there is usually an alternative word which can be used; for example, compare " { $link at } " with " { $link at* } "." ;
+
+ARTICLE: "conditionals-boolean-equivalence" "Expressing conditionals with boolean logic"
+"Certain simple conditional forms can be expressed in a simpler manner using boolean logic."
+$nl
+"The following two lines are equivalent:"
+{ $code "[ drop f ] unless" "swap and" }
+"The following two lines are equivalent:"
+{ $code "[ ] [ ] ?if" "swap or" }
+"The following two lines are equivalent, where " { $snippet "L" } " is a literal:"
+{ $code "[ L ] unless*" "L or" } ;
+
+ARTICLE: "conditionals" "Conditional combinators"
+"The basic conditionals:"
+{ $subsection if }
+{ $subsection when }
+{ $subsection unless }
+"Forms abstracting a common stack shuffle pattern:"
+{ $subsection if* }
+{ $subsection when* }
+{ $subsection unless* }
+"Another form abstracting a common stack shuffle pattern:"
+{ $subsection ?if }
+"Sometimes instead of branching, you just need to pick one of two values:"
+{ $subsection ? }
+"Two combinators which abstract out nested chains of " { $link if } ":"
+{ $subsection cond }
+{ $subsection case }
+{ $subsection "conditionals-boolean-equivalence" }
+{ $see-also "booleans" "bitwise-arithmetic" both? either? } ;
+
+ARTICLE: "dataflow-combinators" "Data flow combinators"
+"Data flow combinators pass values between quotations:"
+{ $subsection "slip-keep-combinators" }
+{ $subsection "cleave-combinators" }
+{ $subsection "spread-combinators" }
+{ $subsection "apply-combinators" }
+{ $see-also "curried-dataflow" } ;
+
 ARTICLE: "combinators-quot" "Quotation construction utilities"
 "Some words for creating quotations which can be useful for implementing method combinations and compiler transforms:"
 { $subsection cond>quot }
 { $subsection case>quot }
 { $subsection alist>quot } ;
 
-ARTICLE: "call" "Calling code with known stack effects"
-"Arbitrary quotations and words can be called from code accepted by the optimizing compiler. This is done by specifying the stack effect of the quotation literally. It is checked at runtime that the stack effect is accurate."
+ARTICLE: "call" "Fundamental combinators"
+"The most basic combinators are those that take either a quotation or word, and invoke it immediately. There are two sets of combinators; they differe in whether or not the stack effect of the expected code is declared."
 $nl
-"Quotations:"
-{ $subsection POSTPONE: call( }
+"The simplest combinators do not take an effect declaration:"
+{ $subsection call }
+{ $subsection execute }
+"These combinators only get optimized by the compiler if the quotation or word parameter is a literal; otherwise a compiler warning will result. Definitions of combinators which require literal parameters must be followed by the " { $link POSTPONE: inline } " declaration. For example:"
+{ $code
+    ": keep ( x quot -- x )"
+    "    over [ call ] dip ; inline"
+}
+"See " { $link "declarations" } " and " { $link "compiler-errors" } " for details."
+$nl
+"The other set of combinators allow arbitrary quotations and words to be called from optimized code. This is done by specifying the stack effect of the quotation literally. It is checked at runtime that the stack effect is accurate."
 { $subsection call-effect }
-"Words:"
-{ $subsection POSTPONE: execute( }
 { $subsection execute-effect }
-"Unsafe calls:"
+"A simple layer of syntax sugar is defined on top:"
+{ $subsection POSTPONE: call( }
+{ $subsection POSTPONE: execute( }
+"Unsafe calls declare an effect statically without any runtime checking:"
 { $subsection call-effect-unsafe }
-{ $subsection execute-effect-unsafe } ;
+{ $subsection execute-effect-unsafe }
+{ $see-also "effects" "inference" } ;
 
-ARTICLE: "combinators" "Additional combinators"
-"The " { $vocab-link "combinators" } " vocabulary provides a few useful combinators."
+ARTICLE: "combinators" "Combinators"
+"A central concept in Factor is that of a " { $emphasis "combinator" } ", which is a word taking code as input."
+{ $subsection "call" }
+{ $subsection "dataflow-combinators" }
+{ $subsection "conditionals" }
+{ $subsection "looping-combinators" }
+{ $subsection "compositional-combinators" }
+{ $subsection "combinators.short-circuit" }
+{ $subsection "combinators.smart" }
+"More combinators are defined for working on data structures, such as " { $link "sequences-combinators" } " and " { $link "assocs-combinators" } "."
 $nl
-"Generalization of " { $link bi } " and " { $link tri } ":"
-{ $subsection cleave }
-"Generalization of " { $link 2bi } " and " { $link 2tri } ":"
-{ $subsection 2cleave }
-"Generalization of " { $link 3bi } " and " { $link 3tri }  ":"
-{ $subsection 3cleave }
-"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."
+"The " { $vocab-link "combinators" } " provides some less frequently-used features."
 $nl
 "A combinator which can help with implementing methods on " { $link hashcode* } ":"
 { $subsection recursive-hashcode }
-{ $subsection "call" }
 { $subsection "combinators-quot" }
-{ $see-also "quotations" "dataflow" } ;
+"Advanced topics:"
+{ $see-also "quotations" } ;
 
 ABOUT: "combinators"
 
index b53ab28cbc7b99e2898bcc44ed45532e3a3bc8c7..9d49cf62c64231379d7e99762675b9c92bfa7d0a 100644 (file)
@@ -56,11 +56,24 @@ $nl
 { $subsection redefine-error } ;
 
 ARTICLE: "definitions" "Definitions"
-"A " { $emphasis "definition" } " is an artifact read from a source file. This includes words, methods, help articles, and path names (which represent the source file at that location). Words for working with definitions are found in the " { $vocab-link "definitions" } " vocabulary."
+"A " { $emphasis "definition" } " is an artifact read from a source file. Words for working with definitions are found in the " { $vocab-link "definitions" } " vocabulary."
+$nl
+"Definitions are defined using parsing words. Examples of definitions together with their defining parsing words are words (" { $link POSTPONE: : } "), methods (" { $link POSTPONE: M: } "), and vocabularies (" { $link POSTPONE: IN: } ")."
+$nl
+"All definitions share some common traits:"
+{ $list
+  "There is a word to list all definitions of a given type"
+  "There is a parsing word for creating new definitions"
+  "There is an ordinary word which is the runtime equivalent of the parsing word, for introspection"
+  "Instances of the definition may be introspected and modified with the definition protocol"
+}
+"For every source file loaded into the system, a list of definitions is maintained. Pathname objects implement the definition protocol, acting over the definitions their source files contain. See " { $link "source-files" } " for details."
 { $subsection "definition-protocol" }
 { $subsection "definition-crossref" }
 { $subsection "definition-checking" }
 { $subsection "compilation-units" }
+"A parsing word to remove definitions:"
+{ $subsection POSTPONE: FORGET: }
 { $see-also "see" "parser" "source-files" "words" "generic" "help-impl" } ;
 
 ABOUT: "definitions"
index b2d265a2e3cf3a43032f048171b36086109f8f5a..558b25910343dc4025009e6e19203dde138adb3e 100644 (file)
@@ -20,14 +20,11 @@ TUPLE: some-class ;
 
 M: some-class some-generic ;
 
-TUPLE: another-class some-generic ;
-
 [ ] [
     [
-        {
-            some-generic
-            some-class
-            { another-class some-generic }
-        } forget-all
+        \ some-generic
+        \ some-class
+        2array
+        forget-all
     ] with-compilation-unit
 ] unit-test
index c95c5816ac19c1baa754b6aed779b66b45cc9319..636067e04b6b764e94b081d302b2ba4dc6a45348 100644 (file)
@@ -3,8 +3,6 @@
 USING: kernel sequences namespaces assocs graphs math math.order ;
 IN: definitions
 
-MIXIN: definition
-
 ERROR: no-compilation-unit definition ;
 
 SYMBOLS: inlined-dependency flushed-dependency called-dependency ;
@@ -42,7 +40,7 @@ GENERIC: set-where ( loc defspec -- )
 
 GENERIC: forget* ( defspec -- )
 
-M: object forget* drop ;
+M: f forget* drop ;
 
 SYMBOL: forgotten-definitions
 
@@ -53,8 +51,6 @@ SYMBOL: forgotten-definitions
 
 : forget-all ( definitions -- ) [ forget ] each ;
 
-GENERIC: synopsis* ( defspec -- )
-
 GENERIC: definer ( defspec -- start end )
 
 GENERIC: definition ( defspec -- seq )
index b209dcf259eaf149b1a1bcc52074200cdbb48842..20709ca8075fa5cc1b711fe9e201423d8757e594 100644 (file)
@@ -1,4 +1,4 @@
-USING: help.markup help.syntax math strings words kernel ;
+USING: help.markup help.syntax math strings words kernel combinators ;
 IN: effects
 
 ARTICLE: "effect-declaration" "Stack effect declaration"
@@ -29,14 +29,11 @@ $nl
 "The stack effect inferencer verifies stack effect comments to ensure the correct number of inputs and outputs is listed. Value names are ignored; only their number matters. An error is thrown if a word's declared stack effect does not match its inferred stack effect. See " { $link "inference" } "." ;
 
 ARTICLE: "effects" "Stack effects"
-"A " { $emphasis "stack effect declaration" } ", for example " { $snippet "( x y -- z )" } " denotes that an operation takes two inputs, with " { $snippet "y" } " at the top of the stack, and returns one output."
+"A " { $emphasis "stack effect declaration" } ", for example " { $snippet "( x y -- z )" } " denotes that an operation takes two inputs, with " { $snippet "y" } " at the top of the stack, and returns one output. Stack effects are first-class, and words for working with them are found in the " { $vocab-link "effects" } " vocabulary."
 $nl
-"Stack effects of words can be declared."
+"Stack effects of words must be declared, and the " { $link "compiler" } " checks that these declarations are correct. Invalid declarations are reported as " { $link "compiler-errors" } ". The " { $link "inference" } " tool can be used to check stack effects interactively."
 { $subsection "effect-declaration" }
-"Stack effects are first-class, and words for working with them are found in the " { $vocab-link "effects" } " vocabulary."
-{ $subsection effect }
-{ $subsection effect? }
-"There is a literal syntax for stack objects. It is most often used with " { $link define-declared } "."
+"There is a literal syntax for stack objects. It is most often used with " { $link define-declared } ", " { $link call-effect } " and " { $link execute-effect } "."
 { $subsection POSTPONE: (( }
 "Getting a word's declared stack effect:"
 { $subsection stack-effect }
@@ -45,7 +42,9 @@ $nl
 "Comparing effects:"
 { $subsection effect-height }
 { $subsection effect<= }
-{ $see-also "inference" } ;
+"The class of stack effects:"
+{ $subsection effect }
+{ $subsection effect? } ;
 
 ABOUT: "effects"
 
index 06a8fa87a3b36397e99641fcf0538d31009e18cf..7017ef8a087928d93bb777d7cb38170050696a63 100644 (file)
@@ -45,8 +45,8 @@ $nl
 { $subsection make-generic }
 "Low-level method constructor:"
 { $subsection <method> }
-"A " { $emphasis "method specifier" } " refers to a method and implements the " { $link "definition-protocol" } ":"
-{ $subsection method-spec }
+"Methods may be pushed on the stack with a literal syntax:"
+{ $subsection POSTPONE: M\ }
 { $see-also "see" } ;
 
 ARTICLE: "method-combination" "Custom method combination"
@@ -98,8 +98,8 @@ $nl
 "Generic words must declare their stack effect in order to compile. See " { $link "effect-declaration" } "."
 { $subsection "method-order" }
 { $subsection "call-next-method" }
-{ $subsection "generic-introspection" }
 { $subsection "method-combination" }
+{ $subsection "generic-introspection" }
 "Generic words specialize behavior based on the class of an object; sometimes behavior needs to be specialized on the object's " { $emphasis "structure" } "; this is known as " { $emphasis "pattern matching" } " and is implemented in the " { $vocab-link "match" } " vocabulary." ;
 
 ABOUT: "generic"
@@ -119,9 +119,10 @@ HELP: define-generic
 { $description "Defines a generic word. A method combination is an object which responds to the " { $link perform-combination } " generic word." }
 { $contract "The method combination quotation is called each time the generic word has to be updated (for example, when a method is added), and thus must be side-effect free." } ;
 
-HELP: method-spec
-{ $class-description "The class of method specifiers, which are two-element arrays consisting of a class word followed by a generic word." }
-{ $examples { $code "{ fixnum + }" "{ editor draw-gadget* }" } } ;
+HELP: M\
+{ $syntax "M\\ class generic" }
+{ $class-description "Pushes a method on the stack." }
+{ $examples { $code "M\\ fixnum + see" } { $code "USING: ui.gadgets ui.gadgets.editors ;" "M\\ editor draw-gadget* edit" } } ;
 
 HELP: method-body
 { $class-description "The class of method bodies, which are words with special word properties set." } ;
index aadc44833fa8c3713c41e50f99c1fb04cc42f0e0..f28332353e66de182023887fcf5920d327e58919 100755 (executable)
@@ -105,9 +105,6 @@ M: shit big-generic-test "shit" ;
 [ float ] [ \ real \ float math-class-max ] unit-test
 [ fixnum ] [ \ fixnum \ null math-class-max ] unit-test
 
-[ t ] [ { hashtable equal? } method-spec? ] unit-test
-[ f ] [ { word = } method-spec? ] unit-test
-
 ! Regression
 TUPLE: first-one ;
 TUPLE: second-one ;
@@ -164,7 +161,7 @@ M: sequence generic-forget-test-2 = ;
 ] unit-test
 
 [ ] [
-    [ { sequence generic-forget-test-2 } forget ] with-compilation-unit
+    [ M\ sequence generic-forget-test-2 forget ] with-compilation-unit
 ] unit-test
 
 [ f ] [
@@ -234,7 +231,7 @@ M: number c-n-m-cache ;
 
 [ 3 ] [ 2 c-n-m-cache ] unit-test
 
-[ ] [ [ { integer c-n-m-cache } forget ] with-compilation-unit ] unit-test
+[ ] [ [ M\ integer c-n-m-cache forget ] with-compilation-unit ] unit-test
 
 [ 2 ] [ 2 c-n-m-cache ] unit-test
 
index c22641d4391318eb8e28eabd8b877fa9267db2ec..65a802dc2dd3c968a85e96fe66292abee698848a 100644 (file)
@@ -24,11 +24,6 @@ M: generic definition drop f ;
 : method ( class generic -- method/f )
     "methods" word-prop at ;
 
-PREDICATE: method-spec < pair
-    first2 generic? swap class? and ;
-
-INSTANCE: method-spec definition
-
 : order ( generic -- seq )
     "methods" word-prop keys sort-classes ;
 
@@ -90,9 +85,6 @@ TUPLE: check-method class generic ;
 PREDICATE: method-body < word
     "method-generic" word-prop >boolean ;
 
-M: method-spec stack-effect
-    first2 method stack-effect ;
-
 M: method-body stack-effect
     "method-generic" word-prop stack-effect ;
 
@@ -139,24 +131,6 @@ M: default-method irrelevant? drop t ;
     dupd <default-method> "default-method" set-word-prop ;
 
 ! Definition protocol
-M: method-spec where
-    dup first2 method [ ] [ second ] ?if where ;
-
-M: method-spec set-where
-    first2 method set-where ;
-
-M: method-spec definer
-    first2 method definer ;
-
-M: method-spec definition
-    first2 method definition ;
-
-M: method-spec forget*
-    first2 method [ forgotten-definition ] [ forget* ] bi ;
-
-M: method-spec smart-usage
-    second smart-usage ;
-
 M: method-body definer
     drop \ M: \ ; ;
 
@@ -214,5 +188,8 @@ M: generic subwords
 M: generic forget*
     [ subwords forget-all ] [ call-next-method ] bi ;
 
+M: class forget-methods
+    [ implementors ] [ [ swap method ] curry ] bi map forget-all ;
+
 : xref-generics ( -- )
     all-words [ subwords [ xref ] each ] each ;
index 4323f91bc3dfe46659c3b6d8058af21b9c8f065c..60fa7453394f53b43a00e0f2ab7a8eae796d9295 100644 (file)
@@ -15,7 +15,7 @@ HELP: no-math-method
 HELP: math-method
 { $values { "word" generic } { "class1" class } { "class2" class } { "quot" quotation } }
 { $description "Generates a definition for " { $snippet "word" } " when the two inputs are instances of " { $snippet "class1" } " and " { $snippet "class2" } ", respectively." }
-{ $examples { $example "USING: generic.math math prettyprint ;" "\\ + fixnum float math-method ." "[ { fixnum float } declare [ >float ] dip float=>+ ]" } } ;
+{ $examples { $example "USING: generic.math math prettyprint ;" "\\ + fixnum float math-method ." "[ { fixnum float } declare [ >float ] dip M\\ float + ]" } } ;
 
 HELP: math-class
 { $class-description "The class of subtypes of " { $link number } " which are not " { $link null } "." } ;
index 204441c19ad42af27234bc1d420be453f542c1fc..d0f968a791d528a41f8ed5f4e017eef6a0329354 100644 (file)
@@ -80,12 +80,12 @@ ARTICLE: "encodings-descriptors" "Encoding descriptors"
 "An encoding descriptor is something which can be used with binary input or output streams to encode or decode bytes stored in a certain representation. It must conform to the " { $link "encodings-protocol" } ". Encodings which you can use are defined in the following vocabularies:"
 { $subsection "io.encodings.binary" }
 { $subsection "io.encodings.utf8" }
-{ $subsection "io.encodings.utf16" }
+{ $vocab-subsection "UTF-16 encoding" "io.encodings.utf16" }
 { $vocab-subsection "UTF-32 encoding" "io.encodings.utf32" }
 { $vocab-subsection "Strict encodings" "io.encodings.strict" }
 "Legacy encodings:"
 { $vocab-subsection "8-bit encodings" "io.encodings.8-bit" }
-{ $vocab-subsection "ASCII" "io.encodings.ascii" }
+{ $vocab-subsection "ASCII encoding" "io.encodings.ascii" }
 { $see-also "encodings-introduction" } ;
 
 ARTICLE: "encodings-protocol" "Encoding protocol"
index c178573a0a4d9390d78f343989800df26a01e05d..36d04f1437eabe8176f5e9b8783fb17a163efab7 100644 (file)
@@ -841,260 +841,6 @@ $nl
 { $subsection roll }
 { $subsection -roll } ;
 
-ARTICLE: "cleave-shuffle-equivalence" "Expressing shuffle words with cleave combinators"
-"Cleave combinators are defined in terms of shuffle words, and mappings from certain shuffle idioms to cleave combinators are discussed in the documentation for " { $link bi } ", " { $link 2bi } ", " { $link 3bi } ", " { $link tri } ", " { $link 2tri } " and " { $link 3tri } "."
-$nl
-"Certain shuffle words can also be expressed in terms of the cleave combinators. Internalizing such identities can help with understanding and writing code using cleave combinators:"
-{ $code
-    ": keep  [ ] bi ;"
-    ": 2keep [ ] 2bi ;"
-    ": 3keep [ ] 3bi ;"
-    ""
-    ": dup   [ ] [ ] bi ;"
-    ": 2dup  [ ] [ ] 2bi ;"
-    ": 3dup  [ ] [ ] 3bi ;"
-    ""
-    ": tuck  [ nip ] [ ] 2bi ;"
-    ": swap  [ nip ] [ drop ] 2bi ;"
-    ""
-    ": over  [ ] [ drop ] 2bi ;"
-    ": pick  [ ] [ 2drop ] 3bi ;"
-    ": 2over [ ] [ drop ] 3bi ;"
-} ;
-
-ARTICLE: "cleave-combinators" "Cleave combinators"
-"The cleave combinators apply multiple quotations to a single value."
-$nl
-"Two quotations:"
-{ $subsection bi }
-{ $subsection 2bi }
-{ $subsection 3bi }
-"Three quotations:"
-{ $subsection tri }
-{ $subsection 2tri }
-{ $subsection 3tri }
-"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" } "."
-{ $subsection "cleave-shuffle-equivalence" } ;
-
-ARTICLE: "spread-shuffle-equivalence" "Expressing shuffle words with spread combinators"
-"Spread combinators are defined in terms of shuffle words, and mappings from certain shuffle idioms to spread combinators are discussed in the documentation for " { $link bi* } ", " { $link 2bi* } ", " { $link tri* } ", and " { $link 2tri* } "."
-$nl
-"Certain shuffle words can also be expressed in terms of the spread combinators. Internalizing such identities can help with understanding and writing code using spread combinators:"
-{ $code
-    ": dip   [ ] bi* ;"
-    ": 2dip  [ ] [ ] tri* ;"
-    ""
-    ": slip  [ call ] [ ] bi* ;"
-    ": 2slip [ call ] [ ] [ ] tri* ;"
-    ""
-    ": nip   [ drop ] [ ] bi* ;"
-    ": 2nip  [ drop ] [ drop ] [ ] tri* ;"
-    ""
-    ": rot"
-    "    [ [ drop ] [      ] [ drop ] tri* ]"
-    "    [ [ drop ] [ drop ] [      ] tri* ]"
-    "    [ [      ] [ drop ] [ drop ] tri* ]"
-    "    3tri ;"
-    ""
-    ": -rot"
-    "    [ [ drop ] [ drop ] [      ] tri* ]"
-    "    [ [      ] [ drop ] [ drop ] tri* ]"
-    "    [ [ drop ] [      ] [ drop ] tri* ]"
-    "    3tri ;"
-    ""
-    ": spin"
-    "    [ [ drop ] [ drop ] [      ] tri* ]"
-    "    [ [ drop ] [      ] [ drop ] tri* ]"
-    "    [ [      ] [ drop ] [ drop ] tri* ]"
-    "    3tri ;"
-} ;
-
-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* }
-{ $subsection 2tri* }
-"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 dip"
-    "[ [ 1 + ] dip 1 - ] dip 2 *"
-    "! Second alternative: uses tri*"
-    "[ 1 + ] [ 1 - ] [ 2 * ] tri*"
-}
-"A generalization of the above combinators to any number of quotations can be found in " { $link "combinators" } "."
-{ $subsection "spread-shuffle-equivalence" } ;
-
-ARTICLE: "apply-combinators" "Apply combinators"
-"The apply combinators apply a single quotation to multiple values. The " { $snippet "@" } " suffix signifies application."
-$nl
-"Two quotations:"
-{ $subsection bi@ }
-{ $subsection 2bi@ }
-"Three quotations:"
-{ $subsection tri@ }
-{ $subsection 2tri@ }
-"A pair of utility words built from " { $link bi@ } ":"
-{ $subsection both? }
-{ $subsection either? } ;
-
-ARTICLE: "slip-keep-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."
-$nl
-"The dip combinators invoke the quotation at the top of the stack, hiding the values underneath:"
-{ $subsection dip }
-{ $subsection 2dip }
-{ $subsection 3dip }
-{ $subsection 4dip }
-"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 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: "curried-dataflow" "Curried dataflow combinators"
-"Curried cleave combinators:"
-{ $subsection bi-curry }
-{ $subsection tri-curry }
-"Curried spread combinators:"
-{ $subsection bi-curry* }
-{ $subsection tri-curry* }
-"Curried apply combinators:"
-{ $subsection bi-curry@ }
-{ $subsection tri-curry@ }
-{ $see-also "dataflow-combinators" } ;
-
-ARTICLE: "compositional-examples" "Examples of compositional combinator usage"
-"Consider printing the same message ten times:"
-{ $code ": print-10 ( -- ) 10 [ \"Hello, world.\" print ] times ;" }
-"if we wanted to abstract out the message into a parameter, we could keep it on the stack between iterations:"
-{ $code ": print-10 ( message -- ) 10 [ dup print ] times drop ;" }
-"However, keeping loop-invariant values on the stack doesn't always work out nicely. For example, a word to subtract a value from each element of a sequence:"
-{ $code ": subtract-n ( seq n -- seq' ) swap [ over - ] map nip ;" }
-"Three shuffle words are required to pass the value around. Instead, the loop-invariant value can be partially applied to a quotation using " { $link curry } ", yielding a new quotation that is passed to " { $link map } ":"
-{ $example
-  "USING: kernel math prettyprint sequences ;"
-  ": subtract-n ( seq n -- seq' ) [ - ] curry map ;"
-  "{ 10 20 30 } 5 subtract-n ."
-  "{ 5 15 25 }"
-}
-"Now consider the word that is dual to the one above; instead of subtracting " { $snippet "n" } " from each stack element, it subtracts each element from " { $snippet "n" } "."
-$nl
-"One way to write this is with a pair of " { $link swap } "s:"
-{ $code ": n-subtract ( n seq -- seq' ) swap [ swap - ] curry map ;" }
-"Since this pattern comes up often, " { $link with } " encapsulates it:"
-{ $example
-  "USING: kernel math prettyprint sequences ;"
-  ": n-subtract ( n seq -- seq' ) [ - ] with map ;"
-  "30 { 10 20 30 } n-subtract ."
-  "{ 20 10 0 }"
-}
-{ $see-also "fry.examples" } ;
-
-ARTICLE: "compositional-combinators" "Compositional combinators"
-"Certain combinators transform quotations to produce a new quotation."
-{ $subsection "compositional-examples" }
-"Fundamental operations:"
-{ $subsection curry }
-{ $subsection compose }
-"Derived operations:"
-{ $subsection 2curry }
-{ $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."
-$nl
-"Curried dataflow combinators can be used to build more complex dataflow by combining cleave, spread and apply patterns in various ways."
-{ $subsection "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." ;
-
-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 [ call ] dip ; inline"
-}
-"Word inlining is documented in " { $link "declarations" } "." ;
-
-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."
-{ $subsection f }
-{ $subsection t }
-"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."
-$nl
-"Here is the " { $link f } " object:"
-{ $example "f ." "f" }
-"Here is the " { $link f } " class:"
-{ $example "\\ f ." "POSTPONE: f" }
-"They are not equal:"
-{ $example "f \\ f = ." "f" }
-"Here is an array containing the " { $link f } " object:"
-{ $example "{ f } ." "{ f }" }
-"Here is an array containing the " { $link f } " class:"
-{ $example "{ POSTPONE: f } ." "{ POSTPONE: f }" }
-"The " { $link f } " object is an instance of the " { $link f } " class:"
-{ $example "USE: classes" "f class ." "POSTPONE: f" }
-"The " { $link f } " class is an instance of " { $link word } ":"
-{ $example "USE: classes" "\\ f class ." "word" }
-"On the other hand, " { $link t } " is just a word, and there is no class which it is a unique instance of."
-{ $example "t \\ t eq? ." "t" }
-"Many words which search collections confuse the case of no element being present with an element being found equal to " { $link f } ". If this distinction is imporant, there is usually an alternative word which can be used; for example, compare " { $link at } " with " { $link at* } "." ;
-
-ARTICLE: "conditionals-boolean-equivalence" "Expressing conditionals with boolean logic"
-"Certain simple conditional forms can be expressed in a simpler manner using boolean logic."
-$nl
-"The following two lines are equivalent:"
-{ $code "[ drop f ] unless" "swap and" }
-"The following two lines are equivalent:"
-{ $code "[ ] [ ] ?if" "swap or" }
-"The following two lines are equivalent, where " { $snippet "L" } " is a literal:"
-{ $code "[ L ] unless*" "L or" } ;
-
-ARTICLE: "conditionals" "Conditionals and logic"
-"The basic conditionals:"
-{ $subsection if }
-{ $subsection when }
-{ $subsection unless }
-"Forms abstracting a common stack shuffle pattern:"
-{ $subsection if* }
-{ $subsection when* }
-{ $subsection unless* }
-"Another form abstracting a common stack shuffle pattern:"
-{ $subsection ?if }
-"Sometimes instead of branching, you just need to pick one of two values:"
-{ $subsection ? }
-"There are some logical operations on booleans:"
-{ $subsection >boolean }
-{ $subsection not }
-{ $subsection and }
-{ $subsection or }
-{ $subsection xor }
-{ $subsection "conditionals-boolean-equivalence" }
-"See " { $link "combinators" } " for forms which abstract away common patterns involving multiple nested branches."
-{ $see-also "booleans" "bitwise-arithmetic" both? either? } ;
-
 ARTICLE: "equality" "Equality"
 "There are two distinct notions of “sameness” when it comes to objects."
 $nl
@@ -1116,34 +862,3 @@ ARTICLE: "assertions" "Assertions"
 { $subsection assert }
 { $subsection assert= } ;
 
-ARTICLE: "dataflow-combinators" "Data flow combinators"
-"Data flow combinators pass values between quotations:"
-{ $subsection "slip-keep-combinators" }
-{ $subsection "cleave-combinators" }
-{ $subsection "spread-combinators" }
-{ $subsection "apply-combinators" }
-{ $see-also "curried-dataflow" } ;
-
-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 "dataflow-combinators" }
-{ $subsection "conditionals" }
-{ $subsection "looping-combinators" }
-{ $subsection "compositional-combinators" }
-{ $subsection "combinators" }
-"More combinators are defined for working on data structures, such as " { $link "sequences-combinators" } " and " { $link "assocs-combinators" } "."
-$nl
-"Advanced topics:"
-{ $subsection "assertions" }
-{ $subsection "implementing-combinators" }
-{ $subsection "macros" }
-{ $subsection "errors" }
-{ $subsection "continuations" } ;
-
-ABOUT: "dataflow"
-
index f79dcb54815da0c91a1d0cdb0b263efb3970878b..c28bf062c1954abd705f692fcf5c0bb1adf694da 100644 (file)
@@ -355,8 +355,9 @@ ARTICLE: "bitwise-arithmetic" "Bitwise arithmetic"
 { $subsection 2/ }
 { $subsection 2^ }
 { $subsection bit? }
-"The " { $vocab-link "math.bitwise" } " vocabulary implements additional bitwise integer operations."
-{ $see-also "conditionals" } ;
+{ $subsection "math.bitwise" }
+{ $subsection "math.bits" }
+{ $see-also "booleans" } ;
 
 ARTICLE: "arithmetic" "Arithmetic"
 "Factor attempts to preserve natural mathematical semantics for numbers. Multiplying two large integers never results in overflow, and dividing two integers yields an exact ratio. Floating point numbers are also supported, along with complex numbers."
index 1bdd1009e9c77c7b03504554de13b22973285ac6..8b2200aa6710fdbb14425acbc5a5e2f0e333c735 100644 (file)
@@ -87,7 +87,14 @@ ARTICLE: "order-specifiers" "Ordering specifiers"
 { $subsection +lt+ }
 { $subsection +eq+ }
 { $subsection +gt+ } ;
-    
+
+ARTICLE: "math.order.example" "Linear order example"
+"A tuple class which defines an ordering among instances by comparing the values of the " { $snippet "id" } " slot:"
+{ $code
+  "TUPLE: sprite id name bitmap ;"
+  "M: sprite <=> [ id>> ] compare ;"
+} ;
+
 ARTICLE: "math.order" "Linear order protocol"
 "Some classes have an intrinsic order amongst instances:"
 { $subsection <=> }
@@ -101,6 +108,8 @@ ARTICLE: "math.order" "Linear order protocol"
 { $subsection before? }
 { $subsection after=? }
 { $subsection before=? }
+"Out of the above generic words, it suffices to implement " { $link <=> } " alone. The others may be provided as an optimization."
+{ $subsection "math.order.example" }
 { $see-also "sequences-sorting" } ;
 
 ABOUT: "math.order"
index ff0542a7b87da8b877c0c7f326033d9d48f6b60f..74d7c58963807d4c8552a6612c6b693b48a3a90e 100644 (file)
@@ -32,7 +32,7 @@ ARTICLE: "namespaces.private" "Namespace implementation details"
 { $subsection >n }
 { $subsection ndrop } ;
 
-ARTICLE: "namespaces" "Variables and namespaces"
+ARTICLE: "namespaces" "Dynamic variables and namespaces"
 "The " { $vocab-link "namespaces" } " vocabulary implements simple dynamically-scoped variables."
 $nl
 "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 "words.symbol" } ")."
@@ -43,7 +43,6 @@ $nl
 "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." ;
index 547f7c0490ebd3805c2ca5277eaa85b8be8245b7..be4b345f4f05db887bcc8410c4790d10d1e3341f 100644 (file)
@@ -92,9 +92,7 @@ ARTICLE: "parser" "The parser"
 "This parser is a general facility for reading textual representations of objects and definitions. The parser is implemented in the " { $vocab-link "parser" } " and " { $vocab-link "syntax" } " vocabularies."
 $nl
 "This section concerns itself with usage and extension of the parser. Standard syntax is described in " { $link "syntax" } "."
-{ $subsection "vocabulary-search" }
 { $subsection "parser-files" }
-{ $subsection "top-level-forms" }
 "The parser can be extended."
 { $subsection "parsing-words" }
 { $subsection "parser-lexer" }
index 2a03b7c74f6bca70dd24916390a81d475c68d82b..a72f4adf8805b30e8390baf7aefc543220e0fd4d 100644 (file)
@@ -24,7 +24,7 @@ ARTICLE: "wrappers" "Wrappers"
 "Wrappers are used to push words on the data stack; they evaluate to the object being wrapped:"
 { $subsection wrapper }
 { $subsection literalize }
-{ $see-also "dataflow" "combinators" } ;
+{ $see-also "combinators" } ;
 
 ABOUT: "quotations"
 
index e2badc2031aa8f66a7ce644254e2d7fc76938290..556e41249e24032abdb00d79ae423b8e57c39f0b 100755 (executable)
@@ -1354,14 +1354,16 @@ ARTICLE: "virtual-sequences" "Virtual sequences"
 "Virtual sequences allow different ways of accessing a sequence without having to create a new sequence or a new data structure altogether. To do this, they translate the virtual index into a normal index into an underlying sequence using the " { $link "virtual-sequences-protocol" } "."
 { $subsection "virtual-sequences-protocol" } ;
 
-ARTICLE: "sequences-integers" "Integer sequences and 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."
 $nl
 "For example, the " { $link each } " combinator, given an integer, simply calls a quotation that number of times, pushing a counter on each iteration that ranges from 0 up to that integer:"
 { $example "3 [ . ] each" "0\n1\n2" }
 "A common idiom is to iterate over a sequence, while also maintaining a loop counter. This can be done using " { $link each-index } ", " { $link map-index } " and " { $link reduce-index } "."
 $nl
-"Combinators that produce new sequences, such as " { $link map } ", will output an array if the input is an integer." ;
+"Combinators that produce new sequences, such as " { $link map } ", will output an array if the input is an integer."
+$nl
+"More elaborate counted loops can be performed with " { $link "math.ranges" } "." ;
 
 ARTICLE: "sequences-access" "Accessing sequence elements"
 { $subsection ?nth }
@@ -1593,7 +1595,6 @@ $nl
 "Sequences implement a protocol:"
 { $subsection "sequence-protocol" }
 { $subsection "sequences-f" }
-{ $subsection "sequences-integers" }
 "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" }
 { $subsection "sequences-combinators" }
@@ -1612,6 +1613,10 @@ $nl
 { $subsection "binary-search" }
 { $subsection "sets" }
 { $subsection "sequences-trimming" }
+{ $subsection "sequences.deep" }
+"Using sequences for looping:"
+{ $subsection "sequences-integers" }
+{ $subsection "math.ranges" }
 "For inner loops:"
 { $subsection "sequences-unsafe" } ;
 
index 840fe628e0a52dbba67707b277bb459a1ce467ac..1e5f9bf1ddbf4e7fcc4e4547724c7f4817be690e 100644 (file)
@@ -83,7 +83,7 @@ $nl
 "A word can be used to check if a class has an initial value or not:"
 { $subsection initial-value } ;
 
-ARTICLE: "slots" "Slots"
+ARTICLE: "slots" "Low-level slot operations"
 "The " { $vocab-link "slots" } " vocabulary contains words for introspecting the slots of an object. A " { $emphasis "slot" } " is a component of an object which can store a value."
 $nl
 { $link "tuples" } " are composed entirely of slots, and instances of " { $link "builtin-classes" } " consist of slots together with intrinsic data."
@@ -104,6 +104,9 @@ $nl
 { $subsection define-changer }
 { $subsection define-slot-methods }
 { $subsection define-accessors }
+"Unsafe slot access:"
+{ $subsection slot }
+{ $subsection set-slot }
 { $see-also "accessors" "mirrors" } ;
 
 ABOUT: "slots"
index df9eb568f6e6f88de2bfae58f7acb634587b4042..bb8791df97ef4ed319834be8823bf092097764f6 100644 (file)
@@ -167,6 +167,8 @@ $nl
 ARTICLE: "syntax" "Syntax"
 "Factor has two main forms of syntax: " { $emphasis "definition" } " syntax and " { $emphasis "literal" } " syntax. Code is data, so the syntax for code is a special case of object literal syntax. This section documents literal syntax. Definition syntax is covered in " { $link "words" } ". Extending the parser is the main topic of " { $link "parser" } "."
 { $subsection "parser-algorithm" }
+{ $subsection "vocabulary-search" }
+{ $subsection "top-level-forms" }
 { $subsection "syntax-comments" }
 { $subsection "syntax-literals" }
 { $subsection "syntax-immediate" } ;
@@ -762,7 +764,9 @@ HELP: >>
 { $description "Marks the end of a parse time code block." } ;
 
 HELP: call-next-method
+{ $syntax "call-next-method" }
 { $description "Calls the next applicable method. Only valid inside a method definition. The values at the top of the stack are passed on to the next method, and they must be compatible with that method's class specializer." }
+{ $notes "This word looks like an ordinary word but it is a parsing word. It cannot be factored out of a method definition, since the code expansion references the current method object directly." }
 { $errors
     "Throws a " { $link no-next-method } " error if this is the least specific method, and throws an " { $link inconsistent-next-method } " error if the values at the top of the stack are not compatible with the current method's specializer."
 } ;
index cb5cdfd5acc4b0438cb1c1d6541ecb8fa447b5c0..2e072f72d823d867ef423adb92ea04b722f360b8 100644 (file)
@@ -104,6 +104,7 @@ IN: bootstrap.syntax
 
     "POSTPONE:" [ scan-word parsed ] define-core-syntax
     "\\" [ scan-word <wrapper> parsed ] define-core-syntax
+    "M\\" [ scan-word scan-word method <wrapper> parsed ] define-core-syntax
     "inline" [ word make-inline ] define-core-syntax
     "recursive" [ word make-recursive ] define-core-syntax
     "foldable" [ word make-foldable ] define-core-syntax
index 2755039af63c60c9053fd0a2c13cbf5136047c52..721846b2d1c9f9caf56cdd0a96e48b9b4bc69c4c 100644 (file)
@@ -1,10 +1,12 @@
 IN: words.constant.tests
-USING: tools.test math ;
+USING: tools.test math words.constant ;
 
 CONSTANT: a +
 
 [ + ] [ a ] unit-test
 
+[ t ] [ \ a constant? ] unit-test
+
 CONSTANT: b \ +
 
 [ \ + ] [ b ] unit-test
@@ -12,3 +14,7 @@ CONSTANT: b \ +
 CONSTANT: c { 1 2 3 }
 
 [ { 1 2 3 } ] [ c ] unit-test
+
+SYMBOL: foo
+
+[ f ] [ \ foo constant? ] unit-test
\ No newline at end of file
index 00302df98a826aa662c3de5cbadd98acc2655b6d..b518760bf980ded0d0fb3c6c8186c35f161a3c98 100644 (file)
@@ -3,12 +3,15 @@
 USING: accessors kernel sequences words definitions quotations ;
 IN: words.constant
 
-PREDICATE: constant < word ( obj -- ? )
-    def>> dup length 1 = [ first word? not ] [ drop f ] if ;
+PREDICATE: constant < word "constant" word-prop >boolean ;
 
 : define-constant ( word value -- )
-    [ ] curry (( -- value )) define-inline ;
+    [ "constant" set-word-prop ]
+    [ [ ] curry (( -- value )) define-inline ] 2bi ;
+
+M: constant reset-word
+    [ call-next-method ] [ f "constant" set-word-prop ] bi ;
 
 M: constant definer drop \ CONSTANT: f ;
 
-M: constant definition def>> first literalize 1quotation ;
\ No newline at end of file
+M: constant definition "constant" word-prop literalize 1quotation ;
\ No newline at end of file
index a107808eec35073761310c47a1e968cba061bf79..34ec6b9174f41f3d6e041024e9a1a9f18ed42721 100644 (file)
@@ -1,10 +1,9 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences accessors definitions
-words words.constant ;
+USING: kernel sequences accessors definitions words ;
 IN: words.symbol
 
-PREDICATE: symbol < constant ( obj -- ? )
+PREDICATE: symbol < word ( obj -- ? )
     [ def>> ] [ [ ] curry ] bi sequence= ;
 
 M: symbol definer drop \ SYMBOL: f ;
@@ -12,4 +11,4 @@ M: symbol definer drop \ SYMBOL: f ;
 M: symbol definition drop f ;
 
 : define-symbol ( word -- )
-    dup define-constant ;
+    dup [ ] curry (( -- value )) define-inline ;
diff --git a/extra/descriptive/tags.txt b/extra/descriptive/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
diff --git a/extra/multi-methods/tags.txt b/extra/multi-methods/tags.txt
new file mode 100644 (file)
index 0000000..f427429
--- /dev/null
@@ -0,0 +1 @@
+extensions
index 47619a17f88aa5134aa9616fcae2acf65fea6e65..44385cf3b7411a8392c9839f3b9a015f0954af2b 100644 (file)
@@ -1 +1,2 @@
-reflection
\ No newline at end of file
+extensions
+reflection