home .. forth .. colorforth mail list archive ..

Re: [colorforth] objects and forth


On Mon, Jan 26, 2009 at 04:06:14PM -0700, vaded@xxxxxxxxxxxxxx wrote:
> "However, as a model for factoring code or designing components, it is
> horrible."
> 
> Could you elaborate on that point a bit?

Certainly.  Quick point of reference, my formal training heavily influences my view of this. Having been a Classicist in a former life, I've studied more human languages than most programmers have programming languages.  And when it come to programming, I've used about 16 programming languages in production over the years.

The meaning of any word in any language is entirely dependent on context.  In a language like Forth, that context is the order in which that word was defined / compiled.  In a language like C, the context that determines the meaning is the way in which the program was linked.  And in a language like Smalltalk, the meaning of the word depends both on the Smalltalk dictionary, the definitions within a class, and any binding in the particular BlockContext you're running.

In all three languages any given WORD can have more than 1 meaning.  The problem of determining the meaning of any given word is dependent on the context at a particular point in time.  As you increase the amount of indirection in the naming of these elements, the basis of object orientation, and push the binding to later and later in the process, the harder it is to know at the time of reading what a given word means. 

In Forth with early binding, the context is generally the same at edit, compile, and run time.  In a language like C, the context can change depending on the scope and link time binding.  A word may have different meanings in different function definitions, but also globally depending on the libraries linked.  In an OO language like Smalltalk, the context is only really defined at runtime, and much to the dismay of many Smalltalkers, can often cause immense pain when trying to run older code in newer systems.  If you need an example, read the Squeak mailing list for several months after they roll out a new release, and lots of old software breaks.  There is even a project called "Level Playing Field" which normalizes the behavior across the past few major releases.  Much of "test driven development" is a response that tries to deal with the problems created by this uncertainty.

From a design point of view, treating linguistic constructs as objects, when they are clearly not objects, is simply disingenuous.  Words in any programming language are still words.  As such, they are merely symbols that stand for things that exist within the experience of the programmer, and the context of the program.  Confusing the idiom you use to talk about those things with the thing itself, doesn't make for good design; merely a muddled understanding of the problem you are trying to solve.  Much like Chuck's revelation about the map is not the territory, but is a useful representation of it.  Good design recognizes the underlying reality, as well as, the limitations of the language we use.

A friend of mine recently sent me a beauty of a code snippet from a project he inherited from a former employee:

	public static void setCustomerName(String customer_name) {
		customerID = customer_name.toInt();
	}

	public static int getCustomerName() {
		return customerID;
	}

These two accessor methods merely operate on an customer record object that has fields customerID and customerName as entities within it.  However, the programmer in question, deep in the belly of this beast, was at cross purposes with herself, and mixed the concepts of customerName and the definition of these accessors.  All of the tests in the test suite worked, the application did basically what it was supposed to do, but without reading the guts of this seemingly simple object, the meaning of the words you read in English are contrary to the definition in the code.  This lead to hours of wasted time by later programmers extending the code.

This is not to say that this one example of programming invalidates the usefulness of OO.  It merely illuminates how a programer's inability to choose the correct words is not solved by using OO techniques.  Finding the correct refactoring, and using the correct terminology to convey both the purpose and meaning of the code, is independent of the mental model you use to think about the relationship between code and data.  That mental model, however, can often help to confuse the issue by muddying the contextual waters to an extent that the actual meaning at run time and the intended meaning at edit time diverge.

I personally feel that OO design doesn't belong within a program.  If you can't envision the complete state of memory at every stage in your code, you've outprogramed your head.  Adding additional layers of complexity to an already complex problem merely make your program less understandable.  Where OO does apply, however, is when you are thinking of the interfaces between programs.  Commands you send to a chip over the bus are messages in the OO sense.  Commands you send between nodes on a network are messages in the OO sense.  But messages you send in a Smalltalk sense, are actually just function calls and indirect jumps.  And such a mixed metaphor is just disingenuous design.



---------------------------------------------------------------------
To unsubscribe, e-mail: colorforth-unsubscribe@xxxxxxxxxxxxxxxxxx
For additional commands, e-mail: colorforth-help@xxxxxxxxxxxxxxxxxx
Main web page - http://www.colorforth.com