Lost at C? Forth May Be the Answer
forth.org
forth.org
It sounds to me like what's being described here is an array of pointers to arrays. Not only is that feasible in C, it is extremely simple and common. The second argument to main() is such an array, for example.
> In C, you’re more protected. But then, you also have to do things like type casting to circumvent a patronizing compiler constantly checking up on you.
I don't consider it "patronizing" when a compiler warns me that casting the first few bytes of a string literal into a memory address might not be what I want. I consider that "helpful".
> The biggest drawback of Forth is the Catch 22 that attends any nonconformist idea. Not many people know Forth, and people won’t usually learn something unless everyone else is already using it.
The author apparently does not think much of his audience. He's basically saying that if you don't learn Forth it's because you're a conformist.
> Industry experience has shown that a Forth programmer is up to ten times more productive than a C programmer.
Now this is just silly. If this were really "industry experience", nobody would still be using C for anything except legacy applications.
Anytime I see some kind of statement like this, I am reminded of the python paradox.
After writing it, I learned a lot more about the Forth community, and how they despise my (perhaps misguided but well-intentioned) attempts to teach people about the principles of writing a Forth interpreter. Search for "JONESFORTH" in the comp.lang.forth archives for some examples.
Could you elaborate on that? Why would they despise your attempt to help others?
Also, thank you for writing JONESFORTH. It's a very useful resource.
Anyhow if you want to find out more, go to:
https://groups.google.com/group/comp.lang.forth/topics
and type "JONESFORTH" in the search box.
You might find this quote interesting:
"The ANS Forth standard is at least one, maybe two orders of magnitude more complex than Mr. Moore's approach to Forth. He says that code should be so simple that most type of errors simply can't happen. In the late eighties and early nineties Chuck quit writing code in Forth and experimented with sourceless programming. His first versions of his VLSI CAD software, OKAD, were constructed without source using his tools in his OK operating system. Later he return to Forth programming and rewrote OKAD II under his new colorForth. [Moore, 2000] In the chat session Chuck was asked, 'How did you come to the conclusion that Forth was too complex, and that sourceless programming was your next move?'
His reply was, 'Maybe by reading the Forth Standard.'"
He later recanted:
"I'm back.
OKAD was a mistake. I have added Forth to OKAD. ...
A few years ago I gave up on Forth, it was too complicated. It was about the time of the work of the standard committee and I wanted something simple. I abandoned source and used a decompiler to view the object code. It did not really work. I also wanted to get away from the keyboard."
More here:
• Your ROT originally was backwards. That is, rather than rotating the third element on the stack to the top, it pushed the top stack element down by two items, which is traditionally called -ROT. While obviously this is a purely arbitrary convention, and irrelevant to just trying to explain how Forth works, it did create unnecessary confusion; it means that anybody who actually learned Forth from JONESFORTH would constantly be struggling to remember which way ROT worked. I apologize for never properly reporting this to you. You fixed this in http://git.annexia.org/?p=jonesforth.git;a=commit;h=dccbff0e...
• The design of JONESFORTH (last time I read it) doesn't accommodate CREATE DOES>, which is the Forth way of creating functions that have state — closures, if you will, or objects with a single method. This, by contrast, I think really is relevant to trying to explain how Forth works. The techniques that support CREATE DOES> (ITC, DTC) are no more complex than JONESFORTH.
I think comp.lang.forth people were slamming JONESFORTH not because of anything about JONESFORTH but because they are mentally insane. (Although I can't really find the flames you were alluding to. The worst I found is complaints about minor incompatibilities like the above.)
But first, we need to agree on the problem space.
FORTH was originally used for non-critical real time control of telescope hardware. The computation requirements were quite modest, there was limited storage available, and the audience was pretty technical. The programs did not have much dynamic state.
Generally, FORTH has been a failure outside of this envelope. While there are very whizzy specialized implementations of FORTH that are very close to equally specialized hardware, and that are capable of exceptional performance and turning really neat tricks, the usual result of bringing FORTH to bear on problems that have a large amount of state or very hard real-time requirements are: Slipped schedules, eventual cancellation of projects, and the labeling of anything dealing with the language as unhealthy fanatacism.
In the hands of a moderately skilled programmer, FORTH is good at:
- near-real-time operations involving modest amounts of computation
- rapid prototyping of same
- stuff whose consumers are very technical and can Deal With support along the lines of "comment out that line, stick this code in and try it again"
In my experience FORTH has not demonstrated success at projects that involve more than three or four engineers, projects that have extensive or complex data structures, or that require high performance (i.e., when microseconds count). This counts out video games (I've seen a lot of these attempts fail), operating systems (ditto), and commercial applications like word processors (shudder).
But if you've got a telescope to control, or a mass spectrometer, or you're doing new hardware bringup, FORTH is great stuff, and I've seen it shine.
Much more here:
[I tried to find references, but couldn't. I do remember finding this out, and saying "That explains /everything/!"]
You can code a train-wreck in anything, I guess.
http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/boot/forth/
And for some sources for the Denver Airport claim:
http://developers.slashdot.org/story/05/08/27/1634255/Denver...
http://www.44342.com/forth-f381-t4059-p1.htm
Edit: it should be noted that the mechanical side of the baggage handling system was extremely complex, and at the beginning was prone to breaking.
But the language is rather old. The standard was never updated to turn forth into a "modern" language. And then there is the community. Even things like named "function" arguments are scowled at.
http://www.dadhacker.com/blog/?p=1468
One of the reasons there is a FORTH interpreter for every platform is that it's so easy to port or bring up that it's /always/ an early arrival.
It's sure not modern. Unextendeded FORTH has nothing like a heap (just stack-like allocation). I could go on.
And yeah, you get yelled at by FORTH purists who see nothing wrong with the language. They can be an interesting crowd to deal with; the most incompetent ones seem to be the loudest and most arrogant about FORTH's universal applicability to everything (and if you can't see this, you're a moran). See earlier comment about projects running late, then killed.
[Back in the day, when I was working on database engines at a largish computer company, a manager of mine said, "I've got to go over to building 123 and evaluate a proposal by some people who want to sell us an O(N) sorting algorithm."
"Don't they know that's impossible?"
"No. They claim they've done it. They got some people in Marketing all excited. They think it could be really big."
"Huh."
"They've written it in FORTH."
(pause)
"They're stark raving loonies," I said.
Oh, and it was about as miserable and as confused and misguided and very nearly fraudulent as you can imagine. Go figure.]
I have to say, however, I would love to see an interpreter for FORTH which does not actually maintain a secondary stack at runtime, but compiles the code down to something equivalent, e.g. uses the LLVM Jit.
Much of what is done with the second stack is simply reordering bits of data or duplicating bits of data. This could all be done at "compile time". Each stack location would only exist at compile time. At runtime the values would be stored in ordinary variables and references. There'd be no need to duplicate data or reorder it at runtime. Instead it would just pull the data from the correct variable or memory location.
Naturally this defeats all the principals of FORTH compilers, etc, blah, blah, blah. But it would still be a fun (and easy) thing to do.
Actually, stack machine with one stack isn't Turing-complete. You need two stacks for this.
http://en.wikipedia.org/wiki/Turing_machine_equivalents#Two-...
http://www.yosefk.com/blog/my-history-with-forth-stack-machi...
It was memorable because it was fast as blazes, essentially compiling routines to a sequence of JSRs, and it featured built-in wireframe 3D graphics primitives. This was exciting at a time where naively clearing the screen with line() routines took several seconds.
Registers aren't good at compressing code the Forth way.
Register code for z = x - y (assume all are in registers or stack) could be sub r1,r2,r3, or sub r127,r124,r11, or anything. Register indices depends on context. On Forth it always will be just sub instruction. If y operand is in memory, the Forth code will be @ sub, and always will be. We could abstract that : @sub @ sub ; if we feel that calling @sub will save us little code memory. It is just not possible with registers, because of the context: the sequence ld ri,(rj); sub rk,rl,ri could use any proper i, j, k and l as register indices.
As a side note I should say that Java stack machine byte code isn't compressed as Forth code should be, so it lose to register code in Dalvik.
As a rule, Forth code is 2-3 times less than CISC code (VAX, x86) and CISC code is 2-3 times less that RISC code (which itself is smaller that VLIW code).
But I do think it's important to look at Forth and see its place in history as a viable alternative to C, on pretty much any level C cared to compete in. It's important to understand that C is not the only way. (I don't mean this as a criticism of C.)
You might be interested in StrongForth, a strong statically typed variant of Forth:
There is however StrongForth.f which runs on top of an ANS Forth system:
When is this article from?
I built my own machine AND half-arsed Forth implementation for Z80 back in '92 from a couple of library books, a dismantled broken RM380Z and a PC with DOS 3 and TASM on it. It sort of worked but was a little unreliable (it was all on stripboard, most of the bus timing was guessed and the XTAL was way too fast). I think the entire Forth impl assembled down to about 4K.
That sort of thing is just impossible with today's equipment. It's depressing. To much abstraction these days. Ironically Forth was probably the first language that supported writing DSLs :)
I'll dig it out and document it one day.
AFAIK, you can define your own FOR loops in FORTH, but you can't enforce statically that each FOR has a matching LOOP; the mismatched program will happily run and corrupt the return stack (if you use the return stack top to store the loop index so that it will be available using the magic word I).
90% of embedded ARM, PIC, AVR, MSP430, eZ80, 68HC11 etc fit that description in one way or another.
This is of course all IMHO.