Tuesday, October 11, 2011

Breaking the Forth Wall

I've made yet more progress on my stand-alone Forth for the x86. I wanted to mention some interesting things about forth real quick while I work out some problems with the call-gate style of key handling and add DOES> words to the language.

There is some very interesting things about Forth as a language. It can very easily support simplified versions of some very powerful features from other languages such as coroutines, continuations, exception handling, closures, and object-orient features. Often these sorts of things are implemented in a similar spirit to other features in a Forth like memory management- the programmer takes more responsibility for her code than usual and the implementation is a simple one that has good enough characteristics to work for what the programmer needs. I could certainly program in Haskell and get all of the power I want in a language for most tasks, but Forth is interesting because it does these things in such a low level context, where we have access to every part of the system and can play with them as needed for whatever we want. For example, we can use the return stack to implement coroutines with a word as simple as ": yield r> r> swap >r >r ;". This will continue the word that called us, which can do the same thing to continue the word called. We might not get everything we want out of this type of implementation, and we have to be very careful to not mess things up, but its pretty good considering we are just above assembly language in terms of abstraction and we have to build everything ourselves.

Another thing I wanted to mention is that there seems to be some relationship between stack languages and functional programming. It is very natural for concatentive language to be seen as functional language where the main operation is composition rather than application. Notice that whitespace represents application in Haskell, but represents composition in Factor, Cat, Joy or Forth. Also, the concept of a graph reduction machine (which is used to give operational semantics to functional programming languages) apparently has found fast and very natural implementations on stack machines where the graph is compiled code (rather then traversing the graph structure with separate code).

In addition, I've been reading Moving Forths section about DOES>, explaining probably the most complex part of Forth, and they mention that the use of code fields in some ways anticipates object oriented programming. This reminded me of the STGM (Spineless Tagless Graph-Reduction Machine) which is Haskell's abstract machine and is implemented as its run-time system. I remember reading that they used essentially a code field to determine what to do with their objects (in the more general sense of entities in a program's memory) rather then tagging them with types and switching on the type (the tag is just a pointer to code that does the Right Thing). This is exactly how variables, constants, does words, and regular words are implemented in Forth. Its probably a well known technique, but Forth must have pioneered it.

Hopefully next time I will have an actual progress update and won't have to resort to a pun for a title.

No comments:

Post a Comment