]> gitweb.factorcode.org Git - factor.git/commitdiff
tuple docs
authorSlava Pestov <slava@factorcode.org>
Mon, 7 Feb 2005 17:02:06 +0000 (17:02 +0000)
committerSlava Pestov <slava@factorcode.org>
Mon, 7 Feb 2005 17:02:06 +0000 (17:02 +0000)
doc/generic.txt
doc/tuples.txt [new file with mode: 0644]

index 224deb1cad9bbcc5302d020cbb78f4d8f7a5ab85..74c46b37dc5f811659b7cb6e89d3160322a6114c 100644 (file)
@@ -212,61 +212,6 @@ defined:
 For obvious reasons, the predicate definition must consume and produce
 exactly one value on the stack.
 
-** The traits metaclass
+** The tuple metaclass
 
-(The name for this metaclass is wrong and will change eventually. The
-original idea was to allow an object to inherit any number of 'traits',
-thus they would behave like mixins. This never materialized.)
-
-The traits metaclass allows one to associate more fine-grained behavior,
-specifically with hashtables.
-
-New classes can be defined like so:
-
-TRAITS: plasma
-
-In terms of behavior, this is actually identical to the following:
-
-PREDICATE: hashtable plasma \ traits swap hash plasma = ;
-
-However, it is far more efficient (and less verbose).
-
-You can define methods as usual:
-
-GENERIC: collide ( actor1 actor2 -- )
-
-M: plasma collide ( actor1 actor2 -- )
-    #! Remove the other actor.
-    deactivate deactivate ;
-
-How does one actually get an object that plasma? responds with t to? You
-define a constructor word by writing C: followed by the class name:
-
-C: plasma ( actor dy -- plasma )
-    [
-        velocity set
-        actor-xy
-        blue color set
-        10 len set
-        5 radius set
-        active on
-    ] extend ;
-
-The constructor word is named after the class, surrounded in angle
-brackets (< and >). For example, the above actually creates a word named
-<plasma>.
-
-The constructor's definition begins with the parameters given by the
-user, underneath a blank plasma object.
-
-That is, a dummy constructor just returns a blank hashtable that
-responds t to the corresponding membership predicate:
-
-TRAITS: foo
-C: foo ;
-
-<foo> foo? .
-==> t
-
-"hello" foo? .
-==> f
+This is quite involved; see tuples.txt.
diff --git a/doc/tuples.txt b/doc/tuples.txt
new file mode 100644 (file)
index 0000000..82f484d
--- /dev/null
@@ -0,0 +1,67 @@
+FACTOR TUPLES
+
+Tuples are user-defined types with named fields, somewhat analogous to
+classes or structs in other languages, however they support dynamic
+method dispatch as well as delegation.
+
+* Defining a tuple
+
+TUPLE: point x y z ;
+
+This defines a new type, 'tuple', and the following words:
+
+point-x set-point-x
+point-y set-point-y
+point-z set-point-z
+point?
+
+To be able to create new instances of tuples, you must define a
+constructor:
+
+C: point ( x y z -- point )
+    [ set-point-z ] keep
+    [ set-point-y ] keep
+    [ set-point-x ] keep ;
+
+Calling 'class' on a tuple returns the tuple's class, so these are
+genuine, disjoint types, not some hack based around vectors or
+hashtables:
+
+1 2 3 <point> class .
+==> point
+
+* Syntax
+
+Tuples have a literal syntax:
+
+1 2 3 <point>
+
+<< point 1 2 3 >>
+
+It is very simple; the tuple class name comes first, followed by the
+values of all slots. If insufficient or extraneous slots are specified,
+an error is raised.
+
+* Generic words
+
+You can define methods for generic words on tuples, just like with any
+other class. For more information, see generic.txt.
+
+* Delegation
+
+If a tuple defines a slot named 'delegate', any generic words called on
+the tuple that are not defined for the tuple's class will be passed on
+to the delegate.
+
+This idiom is used in the I/O code for wrapper streams. For example, the
+ansi-stream class delegates all generic words to its underlying stream,
+except for fwrite-attr, which outputs the necessary terminal escape
+codes. Another example is stdio-stream, which performs all I/O on its
+underlying stream, except it flushes after every new line (which would
+be undesirable for say, a file).
+
+The UI uses delegation extensively, and will be documented separately.
+
+Delegation is used instead of inheritance in Factor, but it is not a
+substitute; in particular, the semantics differ in that a delegated
+method call receives the delegate on the stack, not the original object.