FORTH (by alaric)
Recently there's been some excitement in some corners of the programming languages community over the fact that Forth Dimensions has been scanned in and OCRed and is now available.
FORTH is far from a mainstream programming language these days, but it's one that, I think, is still very useful; both in its own right, and as an inspiration for language designers.
Although they are very different languages, FORTH has a very similar philosophy to LISP; both emphasise maximal expressiveness in a minimal set of orthogonal primitives, helped extensively by helpings of metaprogramming, low-cost abstraction, and no inherent separation between 'inbuilt' and 'user' facilities of the language.
FORTH grew from a world of very low-level programming, getting the best out of very limited hardware; getting this 'best' involved giving the programmer great control, by fitting an interactive development environment and very compact facilities to do great things into a few KB. True to the demands of the time, this involved facilities to get good execution performance and minimal memory consumption.
A lot of the writing emphasising the greatness of FORTH comes from this era, giving it a sometimes amusing feel today, when people proudly talk of a few day's work that saves a few tens of bytes; much of what made FORTH great at the time is now available from 'scripting languages' such as Python, with the added benefits of garbage collection and type safety.
So what can we learn from it today?
Certainly, it's a great case study in language design; it and LISP show two very different approaches to building a minimal language core.
But I think it still has practical applications!
There is still a lot of programming done in environments with constrained memory and CPU resources: embedded systems. Look in the Atmel AVR product catalogue and you'll still see many devices that are too small even to fit FORTH! But the larger of the 8-bit and 16-bit microcontrollers often have enough RAM and FLASH to run a FORTH, in which case the resulting improvements in development productivity and field serviceability from having an in-circuit interactive prompt and metaprogramming facilities are very compelling; and 32-bit ARM microcontrollers are veritable FORTH dream machines. Indeed, MicroProcessor Engineering sell a smorgasbord of titillating FORTH systems for embedded environments.
Secondly, I think FORTH is an excellent model for an intermediate language in code generation. A basic FORTH runtime can be assembled for most platforms in under a man-week, capable of quite efficiently compiling portable code to native; at which point, your entire runtime and software stack is up and running. Having done that, optimisation can continue in parallel, both improving the quality of the code generator (using more and more sophisticated platform-specific optimisations) and replacing portable implementations of libraries written in FORTH with ones hand-coded in assembly or otherwise using special platform features.
A stack machine is a useful intermediate language compared to a register-based VM, since stack code, without the complexities of tagged register data flow, is easier to transform; and the fact that the FORTH model in particular allows for an interactive prompt means that it's easy to include low-level debugging and bootstrapping facilities into your VM. Textual FORTH code can be used as a reasonably compact portable object format that's also amenable to manual processing.
But I don't think one need copy the original FORTH design too slavishly. Traditional FORTH is based heavily around contiguous memory allocation by advancing a pointer, which becomes a burden in multithreaded environments. Part of my ongoing research work for ARGON is the design of a stack language with a FORTHy feel, but designed for more modern patterns of usage, which I'm calling HYDROGEN.
So imagine my joy upon reading Design Concepts in Programming Languages and finding that it studies a stack-based language as a case study in semantics! I just wish they'd given an example of compiling the LISPy languages they develop later into it, rather than aiming at a register machine...