Babblings of an aging geek in love with the Absurd, his family, and his own hubris.... oh, and Lisp.

Whence Forth?

In his blog entry, James Hague talks a bout how Forth was really grand, but never went anywhere. A friend of mine asked, “why was Forth so much fun?” to which I responded, “I may have to write a blog entry to explain and reminisce…”

I really can’t remember when I learned Forth, but I still have my aging copy of Leo Brodie’s Starting Forth. I keep it even though many of the pages detached and often fall on the floor. I keep it out of the excitement I felt way back when.

What made Forth exciting was how simple the language was. It just didn’t have much… of anything. Most of the executable revolved around the editor. Since you probably haven’t encountered it, let me explain the entire language in one paragraph:

Forth is a functional, RPN language, therefore, it doesn’t need a complex syntax, precendence rules, etc. You call a function (with no parameters), and it simply operates on the values on the stack.

There. I did it. That is it in a nutshell. Because it is so small, but can easily build a large collection of functions, the Forth concepts were refined into early hardware devices, like laser printers. I loved taking some of the early laser printers and dropping into the console and creating Forth-like functions in PostScript.

Let me mention another language that I fell in love with for many of the same reasons: Scheme. When I read in SICP that the original Scheme was implemented with only 7 special forms, I was hooked.

This meant that I didn’t have to memorize complex syntax trees in order to get started. Like Forth, it meant that I could get working on concepts early. As such, it is a language to be learned over a weekend. Sure, like chess, you may never master it, but you can get things done quickly.

Contrast these languages with Scala. Scala seems to have “special forms” for function names for infix operator precedence. While this may lead to succinct expressions, this behavior may leak complexity into your programs.

For instance, your class can implement a trait, which is essentially an interface. It differs from an interface in that a trait can offer its children inherited methods. (Nice.) Even though a class can only have one “parent class”, you can get code from many traits. (Great)

However, a trait can inherit, as a parent, a class (Huh?). If you’re child class implements a trait that inherits from a class, that class is now your class’ parent class. (Seriously?) If you already had a parent class, your code won’t compile, and you may not realize which trait has what parent class in its hierarchy that is causing you grief. (WTF!?)

This is why I’m not crazy about Scala, even though it seems to capture a lot of mind-share in the software development community.

In my opinion, two critical problems for both Forth and Scheme had them fail to capture much mind-share:

  1. Initial view of the syntax appears strange.
  2. Early implementations didn’t build an executable.

That’s right, the simple syntax that many people love was too different for many people to accept: “Ugh, where are all the special symbols to show me what is what!?” (Forth) and “Ugh, what is with all these parenthesis!?” (Scheme)

The show stopper for me was how I couldn’t build up special interfaces (graphical user interfaces, etc) or executables a customer could run. While this last problem was eventually solved, in the minds of many, the only interface was a REPL.

I suppose this is why I’m quite interested in the excitement generated by Clojure. It embraces that simplicity but interfaces to everything.

So… what is the answer? An initial hurdle to a simpler language, or a simpler-looking language with greater complexity?