moved generic.txt to devel-guide

cvs
Slava Pestov 2005-02-10 22:55:34 +00:00
parent 7f92f0df6a
commit 6f765bc74c
1 changed files with 0 additions and 217 deletions

View File

@ -1,217 +0,0 @@
THE FACTOR GENERIC WORD SYSTEM
Factor's generic word system is a very abstract generalization of
"object oriented" features found in other programming languges.
To use the generic word system, you must put the following near the
beginning of your source file:
USE: generic
The key motivation is that sometimes, you want to write a word that has
differing behavior depending on the class of its argument. For example,
in a game, a 'draw' word could take different action if given a ship, a
weapon, a planet, etc.
Duplicating 'type case' logic is undesirable and also results in
unnecessary coupling -- adding support for a new type of graphical
object would require modifying the original definition of 'draw', for
example.
* Types
In Factor, the idea of a 'type' refers to a very concrete concept. The
type of an object is its representation in runtime object memory. Types
include fixnums, bignums, cons cells, vectors, strings, and so on. The
set of available types is fixed; adding a new type requires modifying
the runtime source written in C.
* Classes
In Factor, a 'class' is just a predicate that categorizes objects as
being a member of the class or not. To be useful, it must be consistent
-- for a given object, it must always return the same truth value.
Examples of classes might include:
- Cons cells where both elements are integers
- Floating point numbers between -1 and 1
- Hash tables holding a certain key
- Any object that occurs as a member of a certain global variable
holding a list.
- ... and so on.
As you can see, a class of objects does not need to be a subset or a
superset of a type of objects.
Classes, unlike types, can be defined by the user.
* Generic words
A generic word is a word whose behavior depends on the class of the
object at the top of the stack.
Generic words are defined using the following syntax:
GENERIC: draw ( actor -- )
#! Draw the actor.
A stack effect comment, as above, is not required but recommended.
* Methods
A method associates behavior to a generic word. Methods are defined by
writing M:, followed by a class name, followed by the name of a
previously-defined generic word.
One of the main benefits of generic words is that each method definition
can potentially occur in a different source file. Generic word
definitions also hide conditionals.
Here are two methods for the generic 'draw' word:
M: ship draw ( actor -- )
[
surface get screen-xy radius get color get
filledCircleColor
] bind ;
M: plasma draw ( actor -- )
[
surface get screen-xy dup len get + color get
vlineColor
] bind ;
Here, 'ship' and 'class' are user-defined classes.
* Metaclasses
To understand what classes already exist, and how to define your own
classes, the concept of a 'metaclass' must be grasped first. Roughly
speaking, a metaclass is a class of classes.
New metaclasses can be defined by the user, but its an involved process
that requires a deeper understanding of the generic word systsem than
can be given here.
** The object class
Every object is a member of the object class. The object class is also a
metaclass, and it is the one and only instance of itself.
Confusing? The idea is pretty simple. If you define a method on
'object', it will be called when no more specific method is available:
GENERIC: describe
M: number describe "The number " write . ;
M: object describe "I don't know anything about " write . ;
Since the only instance of the object metaclass is itself, you cannot
define new classes in the object metaclass.
** The builtin metaclass
The builtin metaclass contains precisely the following classes; each
class corresponds to a runtime type:
alien
array
bignum
complex
cons
dll
f
fixnum
float
port
ratio
sbuf
string
t
vector
word
Each builtin class has a corresponding membership test predicate, named
after the builtin class suffixed with '?'. For example, cons?, word?,
etc.
Adding new classes to the builtin metaclass requires modifications to
the C code comprising Factor's runtime.
** The union metaclass
The union metaclass contains classes whose members are defined to be the
aggregate of the members of a list of existing classes.
For example, the Factor library defines some unions over numeric types:
UNION: integer fixnum bignum ;
UNION: rational integer ratio ;
UNION: real rational float ;
UNION: number real complex ;
Now, the absolute value function can be defined in an efficient manner
for real numbers, and in a more general fashion for complex numbers:
GENERIC: abs ( z -- |z| )
M: real abs dup 0 < [ neg ] when ;
M: complex abs >rect mag2 ;
New unions can be defined by you, and the numerical types example above
gives the syntax: you write UNION: followed by the name of the union,
followed by its members. The list of members is terminated with a
semi-colon.
A predicate named after the union followed by '?' is
automatically-defined. For example, the following definition of 'real?'
was automatically created:
: real?
dup rational? [
drop t
] [
dup float? [
drop t
] [
drop f
] ifte
] ifte ;
** The predicate metaclass
The predicate metaclass contains classes whose membership test is an
arbitrary expression. To speed up dispatch, each predicate must be
defined as a subclass of some other class. That way predicates
subclassing from disjoint builtin classes do not need to be
simultaenously tested.
The library/strings.factor module defines some subclasses of integer,
classifying the different types of ASCII characters:
PREDICATE: integer blank " \t\n\r" str-contains? ;
PREDICATE: integer letter CHAR: a CHAR: z between? ;
PREDICATE: integer LETTER CHAR: A CHAR: Z between? ;
PREDICATE: integer digit CHAR: 0 CHAR: 9 between? ;
PREDICATE: integer printable CHAR: \s CHAR: ~ between? ;
Each predicate defines a corresponding predicate word whose name is
suffixed with '?'; for example, a 'digit?' word is automatically
defined:
: digit?
dup integer? [
CHAR: 0 CHAR: 9 between?
] [
drop f
] ifte ;
For obvious reasons, the predicate definition must consume and produce
exactly one value on the stack.
** The tuple metaclass
This is quite involved; see tuples.txt.