This is Info file gforth.info, produced by Makeinfo version 1.68 from
the input file gforth.texi.

INFO-DIR-SECTION GNU programming tools
START-INFO-DIR-ENTRY
* Gforth: (gforth).             A fast interpreter for the Forth language.
END-INFO-DIR-ENTRY

   This file documents Gforth 0.4.0

   Copyright (C) 1995-1998 Free Software Foundation, Inc.

   Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
 are preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this      manual under the conditions for verbatim copying, provided
also that the      sections entitled "Distribution" and "General Public
License" are      included exactly as in the original, and provided
that the entire      resulting derived work is distributed under the
terms of a permission      notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual      into another language, under the above conditions for
modified versions,      except that the sections entitled
"Distribution" and "General Public      License" may be included in a
translation approved by the author instead      of in the original
English.


File: gforth.info,  Node: Interpretation and Compilation Semantics,  Prev: Supplying names,  Up: Defining Words

Interpretation and Compilation Semantics
----------------------------------------

   The "interpretation semantics" of a word are what the text
interpreter does when it encounters the word in interpret state. It also
appears in some other contexts, e.g., the execution token returned by
`' WORD' identifies the interpretation semantics of WORD (in other
words, `' WORD execute' is equivalent to interpret-state text
interpretation of `WORD').

   The "compilation semantics" of a word are what the text interpreter
does when it encounters the word in compile state. It also appears in
other contexts, e.g, `POSTPONE WORD' compiles(1) the compilation
semantics of WORD.

   The standard also talks about "execution semantics". They are used
only for defining the interpretation and compilation semantics of many
words. By default, the interpretation semantics of a word are to
`execute' its execution semantics, and the compilation semantics of a
word are to `compile,' its execution semantics.(2)

   You can change the compilation semantics into `execute'ing the
execution semantics with

`immediate'       -         core       ``immediate''

   You can remove the interpretation semantics of a word with

`compile-only'       -         gforth       ``compile-only''

`restrict'       -         gforth       ``restrict''

   Note that ticking (`'') compile-only words gives an error
("Interpreting a compile-only word").

   Gforth also allows you to define words with arbitrary combinations of
interpretation and compilation semantics.

`interpret/compile:'       interp-xt comp-xt "name" -         gforth       ``interpret/compile:''

   This feature was introduced for implementing `TO' and `S"'. I
recommend that you do not define such words, as cute as they may be:
they make it hard to get at both parts of the word in some contexts.
E.g., assume you want to get an execution token for the compilation
part. Instead, define two words, one that embodies the interpretation
part, and one that embodies the compilation part.  Once you have done
that, you can define a combined word with `interpret/compile:' for the
convenience of your users.

   You also might try to provide an optimizing implementation of the
default compilation semantics with this feature, like this:

     :noname
        foo bar ;
     :noname
        POSTPONE foo POSTPONE bar ;
     interpret/compile: foobar

   as an optimizing version of

     : foobar
         foo bar ;

   Unfortunately, this does not work correctly with `[compile]',
because `[compile]' assumes that the compilation semantics of all
`interpret/compile:' words are non-default. I.e., `[compile] foobar'
would compile the compilation semantics for the optimizing `foobar',
whereas it would compile the interpretation semantics for the
non-optimizing `foobar'.

   Some people try to use state-smart words to emulate the feature
provided by `interpret/compile:' (words are state-smart if they check
`STATE' during execution). E.g., they would try to code `foobar' like
this:

     : foobar
       STATE @
       IF ( compilation state )
         POSTPONE foo POSTPONE bar
       ELSE
         foo bar
       ENDIF ; immediate

   While this works if `foobar' is processed only by the text
interpreter, it does not work in other contexts (like `'' or
`POSTPONE'). E.g., `' foobar' will produce an execution token for a
state-smart word, not for the interpretation semantics of the original
`foobar'; when you execute this execution token (directly with
`EXECUTE' or indirectly through `COMPILE,') in compile state, the
result will not be what you expected (i.e., it will not perform `foo
bar'). State-smart words are a bad idea. Simply don't write them!

   It is also possible to write defining words that define words with
arbitrary combinations of interpretation and compilation semantics. In
general, this looks like:

     : def-word
         create-interpret/compile
         CODE1
     interpretation>
         CODE2
     <interpretation
     compilation>
         CODE3
     <compilation ;

   For a WORD defined with `def-word', the interpretation semantics are
to push the address of the body of WORD and perform CODE2, and the
compilation semantics are to push the address of the body of WORD and
perform CODE3. E.g., `constant' can also be defined like this (except
that the defined constants don't behave correctly when `[compile]'d):

     : constant ( n "name" -- )
         create-interpret/compile
         ,
     interpretation> ( -- n )
         @
     <interpretation
     compilation> ( compilation. -- ; run-time. -- n )
         @ postpone literal
     <compilation ;

`create-interpret/compile'       "name" -         gforth       ``create-interpret/compile''

`interpretation>'       compilation. - orig colon-sys         gforth       ``interpretation>''

`<interpretation'       compilation. orig colon-sys -         gforth       ``<interpretation''

`compilation>'       compilation. - orig colon-sys         gforth       ``compilation>''

`<compilation'       compilation. orig colon-sys -         gforth       ``<compilation''

   Note that words defined with `interpret/compile:' and
`create-interpret/compile' have an extended header structure that
differs from other words; however, unless you try to access them with
plain address arithmetic, you should not notice this. Words for
accessing the header structure usually know how to deal with this; e.g.,
`' word >body' also gives you the body of a word created with
`create-interpret/compile'.

   ---------- Footnotes ----------

   (1) In standard terminology, "appends to the current definition".

   (2) In standard terminology: The default interpretation semantics
are its execution semantics; the default compilation semantics are to
append its execution semantics to the execution semantics of the current
definition.


File: gforth.info,  Node: Structures,  Next: Object-oriented Forth,  Prev: Defining Words,  Up: Words

Structures
==========

   This section presents the structure package that comes with Gforth. A
version of the package implemented in plain ANS Forth is available in
`compat/struct.fs'. This package was inspired by a posting on
comp.lang.forth in 1989 (unfortunately I don't remember, by whom;
possibly John Hayes). A version of this section has been published in
???. Marcel Hendrix provided helpful comments.

* Menu:

* Why explicit structure support?::
* Structure Usage::
* Structure Naming Convention::
* Structure Implementation::
* Structure Glossary::


File: gforth.info,  Node: Why explicit structure support?,  Next: Structure Usage,  Prev: Structures,  Up: Structures

Why explicit structure support?
-------------------------------

   If we want to use a structure containing several fields, we could
simply reserve memory for it, and access the fields using address
arithmetic (*note Address arithmetic::.). As an example, consider a
structure with the following fields

`a'
     is a float

`b'
     is a cell

`c'
     is a float

   Given the (float-aligned) base address of the structure we get the
address of the field

`a'
     without doing anything further.

`b'
     with `float+'

`c'
     with `float+ cell+ faligned'

   It is easy to see that this can become quite tiring.

   Moreover, it is not very readable, because seeing a `cell+' tells us
neither which kind of structure is accessed nor what field is accessed;
we have to somehow infer the kind of structure, and then look up in the
documentation, which field of that structure corresponds to that offset.

   Finally, this kind of address arithmetic also causes maintenance
troubles: If you add or delete a field somewhere in the middle of the
structure, you have to find and change all computations for the fields
afterwards.

   So, instead of using `cell+' and friends directly, how about storing
the offsets in constants:

     0 constant a-offset
     0 float+ constant b-offset
     0 float+ cell+ faligned c-offset

   Now we can get the address of field `x' with `x-offset +'. This is
much better in all respects. Of course, you still have to change all
later offset definitions if you add a field. You can fix this by
declaring the offsets in the following way:

     0 constant a-offset
     a-offset float+ constant b-offset
     b-offset cell+ faligned constant c-offset

   Since we always use the offsets with `+', using a defining word
`cfield' that includes the `+' in the action of the defined word offers
itself:

     : cfield ( n "name" -- )
         create ,
     does> ( name execution: addr1 -- addr2 )
         @ + ;
     
     0 cfield a
     0 a float+ cfield b
     0 b cell+ faligned cfield c

   Instead of `x-offset +', we now simply write `x'.

   The structure field words now can be used quite nicely. However,
their definition is still a bit cumbersome: We have to repeat the name,
the information about size and alignment is distributed before and
after the field definitions etc.  The structure package presented here
addresses these problems.


File: gforth.info,  Node: Structure Usage,  Next: Structure Naming Convention,  Prev: Why explicit structure support?,  Up: Structures

Structure Usage
---------------

   You can define a structure for a (data-less) linked list with
     struct
         cell% field list-next
     end-struct list%

   With the address of the list node on the stack, you can compute the
address of the field that contains the address of the next node with
`list-next'. E.g., you can determine the length of a list with:

     : list-length ( list -- n )
     \ "list" is a pointer to the first element of a linked list
     \ "n" is the length of the list
         0 begin ( list1 n1 )
             over
         while ( list1 n1 )
             1+ swap list-next @ swap
         repeat
         nip ;

   You can reserve memory for a list node in the dictionary with `list%
%allot', which leaves the address of the list node on the stack. For
the equivalent allocation on the heap you can use `list% %alloc' (or,
for an `allocate'-like stack effect (i.e., with ior), use `list%
%allocate'). You can also get the the size of a list node with `list%
%size' and it's alignment with `list% %alignment'.

   Note that in ANS Forth the body of a `create'd word is `aligned' but
not necessarily `faligned'; therefore, if you do a
     create *name* foo% %allot

   then the memory alloted for `foo%' is guaranteed to start at the
body of `*name*' only if `foo%' contains only character, cell and
double fields.

   You can also include a structure `foo%' as field of another
structure, with:
     struct
     ...
         foo% field ...
     ...
     end-struct ...

   Instead of starting with an empty structure, you can also extend an
existing structure. E.g., a plain linked list without data, as defined
above, is hardly useful; You can extend it to a linked list of integers,
like this:(1)

     list%
         cell% field intlist-int
     end-struct intlist%

   `intlist%' is a structure with two fields: `list-next' and
`intlist-int'.

   You can specify an array type containing *n* elements of type `foo%'
like this:

     foo% *n* *

   You can use this array type in any place where you can use a normal
type, e.g., when defining a `field', or with `%allot'.

   The first field is at the base address of a structure and the word
for this field (e.g., `list-next') actually does not change the address
on the stack. You may be tempted to leave it away in the interest of
run-time and space efficiency. This is not necessary, because the
structure package optimizes this case and compiling such words does not
generate any code. So, in the interest of readability and
maintainability you should include the word for the field when
accessing the field.

   ---------- Footnotes ----------

   (1) This feature is also known as *extended records*. It is the main
innovation in the Oberon language; in other words, adding this feature
to Modula-2 led Wirth to create a new language, write a new compiler
etc.  Adding this feature to Forth just requires a few lines of code.


File: gforth.info,  Node: Structure Naming Convention,  Next: Structure Implementation,  Prev: Structure Usage,  Up: Structures

Structure Naming Convention
---------------------------

   The field names that come to (my) mind are often quite generic, and,
if used, would cause frequent name clashes. E.g., many structures
probably contain a `counter' field. The structure names that come to
(my) mind are often also the logical choice for the names of words that
create such a structure.

   Therefore, I have adopted the following naming conventions:

   * The names of fields are of the form `*struct*-*field*', where
     `*struct*' is the basic name of the structure, and `*field*' is
     the basic name of the field. You can think about field words as
     converting converts the (address of the) structure into the
     (address of the) field.

   * The names of structures are of the form `*struct*%', where
     `*struct*' is the basic name of the structure.

   This naming convention does not work that well for fields of extended
structures; e.g., the integer list structure has a field `intlist-int',
but has `list-next', not `intlist-next'.


File: gforth.info,  Node: Structure Implementation,  Next: Structure Glossary,  Prev: Structure Naming Convention,  Up: Structures

Structure Implementation
------------------------

   The central idea in the implementation is to pass the data about the
structure being built on the stack, not in some global variable.
Everything else falls into place naturally once this design decision is
made.

   The type description on the stack is of the form *align size*.
Keeping the size on the top-of-stack makes dealing with arrays very
simple.

   `field' is a defining word that uses `create' and `does>'. The body
of the field contains the offset of the field, and the normal `does>'
action is

      +

   i.e., add the offset to the address, giving the stack effect `addr1
-- addr2' for a field.

   This simple structure is slightly complicated by the optimization
for fields with offset 0, which requires a different `does>'-part
(because we cannot rely on there being something on the stack if such a
field is invoked during compilation). Therefore, we put the different
`does>'-parts in separate words, and decide which one to invoke based
on the offset. For a zero offset, the field is basically a noop; it is
immediate, and therefore no code is generated when it is compiled.


File: gforth.info,  Node: Structure Glossary,  Prev: Structure Implementation,  Up: Structures

Structure Glossary
------------------

`%align'       align size -         gforth       ``%align''
   align the data space pointer to the alignment `align'.

`%alignment'       align size - align         gforth       ``%alignment''
   the alignment of the structure

`%alloc'       size align - addr         gforth       ``%alloc''
   allocate `size' address units with alignment `align', giving a data
block at `addr'; `throw's an ior code if not successful.

`%allocate'       align size - addr ior         gforth       ``%allocate''
   allocate `size' address units with alignment `align', similar to
`allocate'.

`%allot'       align size - addr         gforth       ``%allot''
   allot `size' address units of data space with alignment `align'; the
resulting block of data is found at `addr'.

`cell%'       - align size         gforth       ``cell%''

`char%'       - align size         gforth       ``char%''

`dfloat%'       - align size         gforth       ``dfloat%''

`double%'       - align size         gforth       ``double%''

`end-struct'       align size "name" -         gforth       ``end-struct''
   `name' execution: `addr1 -- addr1+offset1'
create a field `name' with offset `offset1', and the type given by
`size align'. `offset2' is the offset of the next field, and `align2'
is the alignment of all fields.

`field'       align1 offset1 align size "name" -  align2 offset2         gforth       ``field''
   name execution: ( addr1 - addr2 )

`float%'       - align size         gforth       ``float%''

`nalign'       addr1 n - addr2         gforth       ``nalign''
   `addr2' is the aligned version of `addr1' wrt the alignment `n'.

`sfloat%'       - align size         gforth       ``sfloat%''

`%size'       align size - size         gforth       ``%size''
   the size of the structure

`struct'       - align size         gforth       ``struct''
   an empty structure, used to start a structure definition.


File: gforth.info,  Node: Object-oriented Forth,  Next: Tokens for Words,  Prev: Structures,  Up: Words

Object-oriented Forth
=====================

   Gforth comes with three packets for object-oriented programming,
`objects.fs', `oof.fs', and `mini-oof.fs'; none of them is preloaded,
so you have to `include' them before use. The most important
differences between these packets (and others) are discussed in *Note
Comparison with other object models::. All packets are written in ANS
Forth and can be used with any other ANS Forth.

* Menu:

* Objects::
* OOF::
* Mini-OOF::


File: gforth.info,  Node: Objects,  Next: OOF,  Prev: Object-oriented Forth,  Up: Object-oriented Forth

Objects
-------

   This section describes the `objects.fs' packet. This material also
has been published in `Yet Another Forth Objects Package' by Anton Ertl
and appeared in Forth Dimensions 19(2), pages 37-43
(`http://www.complang.tuwien.ac.at/forth/objects/objects.html').

   This section assumes (in some places) that you have read *Note
Structures::.

* Menu:

* Properties of the Objects model::
* Why object-oriented programming?::
* Object-Oriented Terminology::
* Basic Objects Usage::
* The class Object::
* Creating objects::
* Object-Oriented Programming Style::
* Class Binding::
* Method conveniences::
* Classes and Scoping::
* Object Interfaces::
* Objects Implementation::
* Comparison with other object models::
* Objects Glossary::

   Marcel Hendrix provided helpful comments on this section. Andras
Zsoter and Bernd Paysan helped me with the related works section.


File: gforth.info,  Node: Properties of the Objects model,  Next: Why object-oriented programming?,  Prev: Objects,  Up: Objects

Properties of the `objects.fs' model
....................................

   * It is straightforward to pass objects on the stack. Passing
     selectors on the stack is a little less convenient, but possible.

   * Objects are just data structures in memory, and are referenced by
     their address. You can create words for objects with normal
     defining words like `constant'. Likewise, there is no difference
     between instance variables that contain objects and those that
     contain other data.

   * Late binding is efficient and easy to use.

   * It avoids parsing, and thus avoids problems with state-smartness
     and reduced extensibility; for convenience there are a few parsing
     words, but they have non-parsing counterparts. There are also a few
     defining words that parse. This is hard to avoid, because all
     standard defining words parse (except `:noname'); however, such
     words are not as bad as many other parsing words, because they are
     not state-smart.

   * It does not try to incorporate everything. It does a few things
     and does them well (IMO). In particular, I did not intend to
     support information hiding with this model (although it has
     features that may help); you can use a separate package for
     achieving this.

   * It is layered; you don't have to learn and use all features to use
     this model. Only a few features are necessary (*Note Basic Objects
     Usage::, *Note The class Object::, *Note Creating objects::.), the
     others are optional and independent of each other.

   * An implementation in ANS Forth is available.

   I have used the technique, on which this model is based, for
implementing the parser generator Gray; we have also used this technique
in Gforth for implementing the various flavours of wordlists (hashed or
not, case-sensitive or not, special-purpose wordlists for locals etc.).


File: gforth.info,  Node: Why object-oriented programming?,  Next: Object-Oriented Terminology,  Prev: Properties of the Objects model,  Up: Objects

Why object-oriented programming?
................................

   Often we have to deal with several data structures (*objects*), that
have to be treated similarly in some respects, but differ in others.
Graphical objects are the textbook example: circles, triangles,
dinosaurs, icons, and others, and we may want to add more during
program development. We want to apply some operations to any graphical
object, e.g., `draw' for displaying it on the screen. However, `draw'
has to do something different for every kind of object.

   We could implement `draw' as a big `CASE' control structure that
executes the appropriate code depending on the kind of object to be
drawn. This would be not be very elegant, and, moreover, we would have
to change `draw' every time we add a new kind of graphical object (say,
a spaceship).

   What we would rather do is: When defining spaceships, we would tell
the system: "Here's how you `draw' a spaceship; you figure out the
rest."

   This is the problem that all systems solve that (rightfully) call
themselves object-oriented, and the object-oriented package I present
here also solves this problem (and not much else).


File: gforth.info,  Node: Object-Oriented Terminology,  Next: Basic Objects Usage,  Prev: Why object-oriented programming?,  Up: Objects

Object-Oriented Terminology
...........................

   This section is mainly for reference, so you don't have to understand
all of it right away.  The terminology is mainly Smalltalk-inspired.  In
short:

*class*
     a data structure definition with some extras.

*object*
     an instance of the data structure described by the class
     definition.

*instance variables*
     fields of the data structure.

*selector*
     (or *method selector*) a word (e.g., `draw') for performing an
     operation on a variety of data structures (classes). A selector
     describes *what* operation to perform. In C++ terminology: a
     (pure) virtual function.

*method*
     the concrete definition that performs the operation described by
     the selector for a specific class. A method specifies *how* the
     operation is performed for a specific class.

*selector invocation*
     a call of a selector. One argument of the call (the TOS
     (top-of-stack)) is used for determining which method is used. In
     Smalltalk terminology: a message (consisting of the selector and
     the other arguments) is sent to the object.

*receiving object*
     the object used for determining the method executed by a selector
     invocation. In our model it is the object that is on the TOS when
     the selector is invoked. (*Receiving* comes from Smalltalks
     *message* terminology.)

*child class*
     a class that has (*inherits*) all properties (instance variables,
     selectors, methods) from a *parent class*. In Smalltalk
     terminology: The subclass inherits from the superclass. In C++
     terminology: The derived class inherits from the base class.


File: gforth.info,  Node: Basic Objects Usage,  Next: The class Object,  Prev: Object-Oriented Terminology,  Up: Objects

Basic Objects Usage
...................

   You can define a class for graphical objects like this:

     object class \ "object" is the parent class
       selector draw ( x y graphical -- )
     end-class graphical

   This code defines a class `graphical' with an operation `draw'.  We
can perform the operation `draw' on any `graphical' object, e.g.:

     100 100 t-rex draw

   where `t-rex' is a word (say, a constant) that produces a graphical
object.

   How do we create a graphical object? With the present definitions,
we cannot create a useful graphical object. The class `graphical'
describes graphical objects in general, but not any concrete graphical
object type (C++ users would call it an *abstract class*); e.g., there
is no method for the selector `draw' in the class `graphical'.

   For concrete graphical objects, we define child classes of the class
`graphical', e.g.:

     graphical class \ "graphical" is the parent class
       cell% field circle-radius
     
     :noname ( x y circle -- )
       circle-radius @ draw-circle ;
     overrides draw
     
     :noname ( n-radius circle -- )
       circle-radius ! ;
     overrides construct
     
     end-class circle

   Here we define a class `circle' as a child of `graphical', with a
field `circle-radius' (which behaves just like a field in *note
Structures::.); it defines new methods for the selectors `draw' and
`construct' (`construct' is defined in `object', the parent class of
`graphical').

   Now we can create a circle on the heap (i.e., `allocate'd memory)
with

     50 circle heap-new constant my-circle

   `heap-new' invokes `construct', thus initializing the field
`circle-radius' with 50. We can draw this new circle at (100,100) with

     100 100 my-circle draw

   Note: You can invoke a selector only if the object on the TOS (the
receiving object) belongs to the class where the selector was defined
or one of its descendents; e.g., you can invoke `draw' only for objects
belonging to `graphical' or its descendents (e.g., `circle').
Immediately before `end-class', the search order has to be the same as
immediately after `class'.


File: gforth.info,  Node: The class Object,  Next: Creating objects,  Prev: Basic Objects Usage,  Up: Objects

The class `object'
..................

   When you define a class, you have to specify a parent class.  So how
do you start defining classes? There is one class available from the
start: `object'. You can use it as ancestor for all classes. It is the
only class that has no parent. It has two selectors: `construct' and
`print'.


File: gforth.info,  Node: Creating objects,  Next: Object-Oriented Programming Style,  Prev: The class Object,  Up: Objects

Creating objects
................

   You can create and initialize an object of a class on the heap with
`heap-new' ( ... class - object ) and in the dictionary (allocation
with `allot') with `dict-new' ( ... class - object ). Both words invoke
`construct', which consumes the stack items indicated by "..." above.

   If you want to allocate memory for an object yourself, you can get
its alignment and size with `class-inst-size 2@' ( class - align size
). Once you have memory for an object, you can initialize it with
`init-object' ( ... class object - ); `construct' does only a part of
the necessary work.


File: gforth.info,  Node: Object-Oriented Programming Style,  Next: Class Binding,  Prev: Creating objects,  Up: Objects

Object-Oriented Programming Style
.................................

   This section is not exhaustive.

   In general, it is a good idea to ensure that all methods for the
same selector have the same stack effect: when you invoke a selector,
you often have no idea which method will be invoked, so, unless all
methods have the same stack effect, you will not know the stack effect
of the selector invocation.

   One exception to this rule is methods for the selector `construct'.
We know which method is invoked, because we specify the class to be
constructed at the same place. Actually, I defined `construct' as a
selector only to give the users a convenient way to specify
initialization. The way it is used, a mechanism different from selector
invocation would be more natural (but probably would take more code and
more space to explain).


File: gforth.info,  Node: Class Binding,  Next: Method conveniences,  Prev: Object-Oriented Programming Style,  Up: Objects

Class Binding
.............

   Normal selector invocations determine the method at run-time
depending on the class of the receiving object (late binding).

   Sometimes we want to invoke a different method. E.g., assume that
you want to use the simple method for `print'ing `object's instead of
the possibly long-winded `print' method of the receiver class. You can
achieve this by replacing the invocation of `print' with

     [bind] object print

   in compiled code or

     bind object print

   in interpreted code. Alternatively, you can define the method with a
name (e.g., `print-object'), and then invoke it through the name. Class
binding is just a (often more convenient) way to achieve the same
effect; it avoids name clutter and allows you to invoke methods
directly without naming them first.

   A frequent use of class binding is this: When we define a method for
a selector, we often want the method to do what the selector does in
the parent class, and a little more. There is a special word for this
purpose: `[parent]'; `[parent] *selector*' is equivalent to `[bind]
*parent selector*', where `*parent*' is the parent class of the current
class. E.g., a method definition might look like:

     :noname
       dup [parent] foo \ do parent's foo on the receiving object
       ... \ do some more
     ; overrides foo

   In `Object-oriented programming in ANS Forth' (Forth Dimensions,
March 1997), Andrew McKewan presents class binding as an optimization
technique. I recommend not using it for this purpose unless you are in
an emergency. Late binding is pretty fast with this model anyway, so the
benefit of using class binding is small; the cost of using class binding
where it is not appropriate is reduced maintainability.

   While we are at programming style questions: You should bind
selectors only to ancestor classes of the receiving object. E.g., say,
you know that the receiving object is of class `foo' or its
descendents; then you should bind only to `foo' and its ancestors.


File: gforth.info,  Node: Method conveniences,  Next: Classes and Scoping,  Prev: Class Binding,  Up: Objects

Method conveniences
...................

   In a method you usually access the receiving object pretty often.  If
you define the method as a plain colon definition (e.g., with
`:noname'), you may have to do a lot of stack gymnastics. To avoid
this, you can define the method with `m: ... ;m'. E.g., you could
define the method for `draw'ing a `circle' with

     m: ( x y circle -- )
       ( x y ) this circle-radius @ draw-circle ;m

   When this method is executed, the receiver object is removed from the
stack; you can access it with `this' (admittedly, in this example the
use of `m: ... ;m' offers no advantage). Note that I specify the stack
effect for the whole method (i.e. including the receiver object), not
just for the code between `m:' and `;m'. You cannot use `exit' in
`m:...;m'; instead, use `exitm'.(1)

   You will frequently use sequences of the form `this *field*' (in the
example above: `this circle-radius'). If you use the field only in this
way, you can define it with `inst-var' and eliminate the `this' before
the field name. E.g., the `circle' class above could also be defined
with:

     graphical class
       cell% inst-var radius
     
     m: ( x y circle -- )
       radius @ draw-circle ;m
     overrides draw
     
     m: ( n-radius circle -- )
       radius ! ;m
     overrides construct
     
     end-class circle

   `radius' can only be used in `circle' and its descendent classes and
inside `m:...;m'.

   You can also define fields with `inst-value', which is to `inst-var'
what `value' is to `variable'.  You can change the value of such a
field with `[to-inst]'.  E.g., we could also define the class `circle'
like this:

     graphical class
       inst-value radius
     
     m: ( x y circle -- )
       radius draw-circle ;m
     overrides draw
     
     m: ( n-radius circle -- )
       [to-inst] radius ;m
     overrides construct
     
     end-class circle

   ---------- Footnotes ----------

   (1) Moreover, for any word that calls `catch' and was defined before
loading `objects.fs', you have to redefine it like I redefined `catch':
`: catch this >r catch r> to-this ;'


File: gforth.info,  Node: Classes and Scoping,  Next: Object Interfaces,  Prev: Method conveniences,  Up: Objects

Classes and Scoping
...................

   Inheritance is frequent, unlike structure extension. This exacerbates
the problem with the field name convention (*note Structure Naming
Convention::.): One always has to remember in which class the field was
originally defined; changing a part of the class structure would require
changes for renaming in otherwise unaffected code.

   To solve this problem, I added a scoping mechanism (which was not in
my original charter): A field defined with `inst-var' (or `inst-value')
is visible only in the class where it is defined and in the descendent
classes of this class.  Using such fields only makes sense in
`m:'-defined methods in these classes anyway.

   This scoping mechanism allows us to use the unadorned field name,
because name clashes with unrelated words become much less likely.

   Once we have this mechanism, we can also use it for controlling the
visibility of other words: All words defined after `protected' are
visible only in the current class and its descendents. `public'
restores the compilation (i.e. `current') wordlist that was in effect
before. If you have several `protected's without an intervening
`public' or `set-current', `public' will restore the compilation
wordlist in effect before the first of these `protected's.


File: gforth.info,  Node: Object Interfaces,  Next: Objects Implementation,  Prev: Classes and Scoping,  Up: Objects

Object Interfaces
.................

   In this model you can only call selectors defined in the class of the
receiving objects or in one of its ancestors. If you call a selector
with a receiving object that is not in one of these classes, the result
is undefined; if you are lucky, the program crashes immediately.

   Now consider the case when you want to have a selector (or several)
available in two classes: You would have to add the selector to a
common ancestor class, in the worst case to `object'. You may not want
to do this, e.g., because someone else is responsible for this ancestor
class.

   The solution for this problem is interfaces. An interface is a
collection of selectors. If a class implements an interface, the
selectors become available to the class and its descendents. A class
can implement an unlimited number of interfaces. For the problem
discussed above, we would define an interface for the selector(s), and
both classes would implement the interface.

   As an example, consider an interface `storage' for writing objects
to disk and getting them back, and a class `foo' foo that implements
it. The code for this would look like this:

     interface
       selector write ( file object -- )
       selector read1 ( file object -- )
     end-interface storage
     
     bar class
       storage implementation
     
     ... overrides write
     ... overrides read
     ...
     end-class foo

   (I would add a word `read' ( file - object ) that uses `read1'
internally, but that's beyond the point illustrated here.)

   Note that you cannot use `protected' in an interface; and of course
you cannot define fields.

   In the Neon model, all selectors are available for all classes;
therefore it does not need interfaces. The price you pay in this model
is slower late binding, and therefore, added complexity to avoid late
binding.


File: gforth.info,  Node: Objects Implementation,  Next: Comparison with other object models,  Prev: Object Interfaces,  Up: Objects

`objects.fs' Implementation
...........................

   An object is a piece of memory, like one of the data structures
described with `struct...end-struct'. It has a field `object-map' that
points to the method map for the object's class.

   The *method map*(1) is an array that contains the execution tokens
(XTs) of the methods for the object's class. Each selector contains an
offset into the method maps.

   `selector' is a defining word that uses `create' and `does>'. The
body of the selector contains the offset; the `does>' action for a
class selector is, basically:

     ( object addr ) @ over object-map @ + @ execute

   Since `object-map' is the first field of the object, it does not
generate any code. As you can see, calling a selector has a small,
constant cost.

   A class is basically a `struct' combined with a method map. During
the class definition the alignment and size of the class are passed on
the stack, just as with `struct's, so `field' can also be used for
defining class fields. However, passing more items on the stack would be
inconvenient, so `class' builds a data structure in memory, which is
accessed through the variable `current-interface'. After its definition
is complete, the class is represented on the stack by a pointer (e.g.,
as parameter for a child class definition).

   At the start, a new class has the alignment and size of its parent,
and a copy of the parent's method map. Defining new fields extends the
size and alignment; likewise, defining new selectors extends the method
map. `overrides' just stores a new XT in the method map at the offset
given by the selector.

   Class binding just gets the XT at the offset given by the selector
from the class's method map and `compile,'s (in the case of `[bind]')
it.

   I implemented `this' as a `value'. At the start of an `m:...;m'
method the old `this' is stored to the return stack and restored at the
end; and the object on the TOS is stored `TO this'. This technique has
one disadvantage: If the user does not leave the method via `;m', but
via `throw' or `exit', `this' is not restored (and `exit' may crash).
To deal with the `throw' problem, I have redefined `catch' to save and
restore `this'; the same should be done with any word that can catch an
exception. As for `exit', I simply forbid it (as a replacement, there is
`exitm').

   `inst-var' is just the same as `field', with a different `does>'
action:
     @ this +
   Similar for `inst-value'.

   Each class also has a wordlist that contains the words defined with
`inst-var' and `inst-value', and its protected words. It also has a
pointer to its parent. `class' pushes the wordlists of the class an all
its ancestors on the search order, and `end-class' drops them.

   An interface is like a class without fields, parent and protected
words; i.e., it just has a method map. If a class implements an
interface, its method map contains a pointer to the method map of the
interface. The positive offsets in the map are reserved for class
methods, therefore interface map pointers have negative offsets.
Interfaces have offsets that are unique throughout the system, unlike
class selectors, whose offsets are only unique for the classes where
the selector is available (invokable).

   This structure means that interface selectors have to perform one
indirection more than class selectors to find their method. Their body
contains the interface map pointer offset in the class method map, and
the method offset in the interface method map. The `does>' action for
an interface selector is, basically:

     ( object selector-body )
     2dup selector-interface @ ( object selector-body object interface-offset )
     swap object-map @ + @ ( object selector-body map )
     swap selector-offset @ + @ execute

   where `object-map' and `selector-offset' are first fields and
generate no code.

   As a concrete example, consider the following code:

     interface
       selector if1sel1
       selector if1sel2
     end-interface if1
     
     object class
       if1 implementation
       selector cl1sel1
       cell% inst-var cl1iv1
     
     ' m1 overrides construct
     ' m2 overrides if1sel1
     ' m3 overrides if1sel2
     ' m4 overrides cl1sel2
     end-class cl1
     
     create obj1 object dict-new drop
     create obj2 cl1    dict-new drop

   The data structure created by this code (including the data structure
for `object') is shown in the <a
href="objects-implementation.eps">figure</a>, assuming a cell size of 4.

   ---------- Footnotes ----------

   (1) This is Self terminology; in C++ terminology: virtual function
table.


File: gforth.info,  Node: Comparison with other object models,  Next: Objects Glossary,  Prev: Objects Implementation,  Up: Objects

Comparison with other object models
...................................

   Many object-oriented Forth extensions have been proposed (`A survey
of object-oriented Forths' (SIGPLAN Notices, April 1996) by Bradford J.
Rodriguez and W. F. S. Poehlman lists 17). Here I'll discuss the
relation of `objects.fs' to two well-known and two closely-related (by
the use of method maps) models.

   The most popular model currently seems to be the Neon model (see
`Object-oriented programming in ANS Forth' (Forth Dimensions, March
1997) by Andrew McKewan). The Neon model uses a `*selector object*'
syntax, which makes it unnatural to pass objects on the stack. It also
requires that the selector parses the input stream (at compile time);
this leads to reduced extensibility and to bugs that are hard to find.
Finally, it allows using every selector to every object; this
eliminates the need for classes, but makes it harder to create
efficient implementations. A longer version of this critique can be
found in `On Standardizing Object-Oriented Forth Extensions' (Forth
Dimensions, May 1997) by Anton Ertl.

   Another well-known publication is `Object-Oriented Forth' (Academic
Press, London, 1987) by Dick Pountain. However, it is not really about
object-oriented programming, because it hardly deals with late binding.
Instead, it focuses on features like information hiding and overloading
that are characteristic of modular languages like Ada (83).

   In `Does late binding have to be slow?' (Forth Dimensions ??? 1996)
Andras Zsoter describes a model that makes heavy use of an active object
(like `this' in `objects.fs'): The active object is not only used for
accessing all fields, but also specifies the receiving object of every
selector invocation; you have to change the active object explicitly
with `{ ... }', whereas in `objects.fs' it changes more or less
implicitly at `m: ... ;m'. Such a change at the method entry point is
unnecessary with the Zsoter's model, because the receiving object is
the active object already; OTOH, the explicit change is absolutely
necessary in that model, because otherwise no one could ever change the
active object. An ANS Forth implementation of this model is available
at `http://www.forth.org/fig/oopf.html'.

   The `oof.fs' model combines information hiding and overloading
resolution (by keeping names in various wordlists) with object-oriented
programming. It sets the active object implicitly on method entry, but
also allows explicit changing (with `>o...o>' or with
`with...endwith'). It uses parsing and state-smart objects and classes
for resolving overloading and for early binding: the object or class
parses the selector and determines the method from this. If the
selector is not parsed by an object or class, it performs a call to the
selector for the active object (late binding), like Zsoter's model.
Fields are always accessed through the active object. The big
disadvantage of this model is the parsing and the state-smartness, which
reduces extensibility and increases the opportunities for subtle bugs;
essentially, you are only safe if you never tick or `postpone' an
object or class (Bernd disagrees, but I (Anton) am not convinced).

   The Mini-OOF model is quite similar to a very stripped-down version
of the Objects model, but syntactically it is a mixture of the Objects
and the OOF model.

