Re: Forth and OO design?



On Jul 4, 6:57 pm, m_l_g3 <m_l...@xxxxxxxxx> wrote:
[snip]
Can you please elaborate?

Sure, the source will be available on Github as soon as I finish off
the self-hosting environment.

The basic structure of the VM is:

* 8 cell circular data stack
* data stack index register
* 8 cell circular return stack
* return stack index register
* current object register
* memory source register
* memory destination register
* for/next count register

The system consists of a handful of objects:

* Core - an object consisting of 32 methods that compile inline
instructions
* Macro - an object consisting of 6 methods that are used to generate
immediate style words
* Sys - an object containing methods which partition the memory space
* Stack - a utility object that has stack manipulation routines not
found in Core (like swap and nip)
* Char - a utility object for manipulating characters (the VM uses
cell based addressing)
* Term - an object that manages the keyboard and text display
* String - an object that manages a string table, and produces symbol
tokens (aka string addresses)
* Lexicon - a meta-object object that consists entirely of key ,
value , pairs and works like a stack
* Compiler - an object that converts source (read string token lists)
into code

How do you implement objects and what do you keep on the OO context stack?

You load source into the lexicon. To extend an object, you do a copy
down of the old object,
and add your desired fields. Once made, an object can not be unmade,
except by forgetting all
of the objects made since it was.

What about the design?
As I understand, you did not have any classes at all.

You don't need classes to do OO! If you haven't already please read
Randall Smith's and
David Ungar's seminal "Programming as an Experience: The Inspiration
for Self"

http://research.sun.com/self/papers/programming-as-experience.html

What I use rather than classes is the notion of "classiness", do two
objects share a common
set of semantics. This treats the methods an object responds to as
traits of the object. A
specific set of traits define a class. So let's say I have an object
Circle which is derived
from Widget, as in I did a shallow copy of Widget's methods, and then
overrode a few and added
an extension method called 'radius'. What I can then say is:

Circle a Widget is?

Which simply asks is Circle a member of the class Widget. Which will
place true (-1) or false (0)
on the stack if Circle implements all of Widget's methods. So this
will return true. Asking the
opposite question:

Widget a Circle is?

will return false, as Widget doesn't have a method called 'radius',
and so is not a kind of Circle.

Design is assembling the program structure what you want
from the structural units that you have.

No, that is not design. Design is the art and practice of describing
a plan or
the thought behind the creation of a object. Design in programming
involves the
careful selection of words and idioms that best convey your intent in
a manner
that is both clear and concise. Design is most definitely not
slapping prefab ***
together.

Java-style OO design is assembling the program structure from classes and
interfaces. But in a prototype-based model, you don't have any classes at all...

Java is probably the worst example of what good OO design is. Sun was
a Smalltalk/TCL
shop before Java was ever a going concern. Sun also had produced the
Self programming
language which became the bastardized basis of Javascript. (Javascript
is a better OO
language than Java in nearly all ways).

So it is interesting
1) how you could manage without classes

Easily, a class is really just a optimization technique disguised as a
language feature.
Rather than having each object maintain its own copy of some code, you
define a class object
which holds the code on the behalf of all the instance objects. This
isn't actually what
you want 99% of the time from a semantic standpoint, as OO programming
well really requires the
ability to ad hoc extend individual objects. But most people don't do
this or think about
it because back in the 1980s you just didn't have enough memory!

2) how did you do your design in Forth.

Well the way I did my design in Forth, as I first prototyped it in
Assembler, Javascript,
C, Smalltalk, and Forth. I tested out each idea in different contexts
to establish which
worked best in practice. Then I built 4 test VMs, one in Javascript,
one in Smalltalk, one in C,
and then one in assembler. I then wrote three compilers one in C and
one in Javascript that output
to the VM, using the same instruction set that would run on the FPGA.
I then wrote a full featured
version in 90 lines of Perl, which I'm using to bootstrap the Intel
native version of the VM
written in my own Forth itself.

By building several prototypes in different contexts, I was able to
explore compilation issues,
choice of instruction set, and which words had the best semantics to
express my ideas. The
Javascript versions were incredibly helpful, and what I used to build
the first prototype of
the Intel native compiler. The sever limitations of Javascript, led
me to some design decisions
that dramatically simplified my compilation techniques. I would have
probably never thought of them
in Forth, because I don't have trouble manipulating blocks of memory
in Forth!

Probably, the top-level structure is not OO but just Forth.

Nope, the whole damn thing is OO. Methods defined in Core or Macro
(which can be extended at edit time),
are treated as implicit message sends to Core and Macro. All other
words are message sends to the object
pointed to by the object register. If a method is not found in the
current object context, it is kicked
to that Object's "*" wildcard method which is similar to Smalltalk's
doesNotUnderstand:aMessage. That
allows you to vector it off to one of the object's components if you
so choose.

What is significantly different from say programming in Smalltalk, is
that I keep a Forth style separation
between my object and the data they manipulate. Data is just data, be
it code, JPEGs, 3D models, or the like.
Confusing your data for your object is just bad design.

Dave

http://blog.dloh.org/
.


Loading