GARTHWILSON wrote:
but rather adding new ones and trying them immediately (even if that includes FORGETting one or more of the last-defined words), sometimes while even having an earlier part running in the background and not wanting to disturb it regardless of how fast you can recompile the whole application.
Right, and while there is some value in this, on the whole I think it's a wash. I find test-driven development techniques works better on the whole.
TDD is a practice where you maintain two programs at once. The first is a collection of tests which can be run
in any order, and which exercises the various components of your production code. The second program, obviously, is your production code. The trick is to iterate in a loop of writing
one test
first, then writing
just enough production code (however stupidly simple it is) to make that one test pass. For any given iteration, you'll find that this
does take a longer time than the traditional Forth-style interactive development process. However, the corresponding time spent debugging is substantially reduced, particularly since you have an ever-growing body of executable specifications which you can refer to both for correctness checking and also to serve as an example on how to use something (what was the order of those stack arguments again? Did I need to NUL-terminate that string or not? Etc.).
And, you might find that you need to change entire swaths of code because you coded yourself into a corner. Or, it's not compatible with a customer's new requirements, etc. This happens. With your interactive approach, you start anew, but you have no way of ensuring your changes retain compatibility with the rest of the software you've written. With TDD, you have a body of tests to back you up. Yeah, some of those tests are going to change along with your production code changes. But, unless you're starting completely from scratch, you won't be changing every test (all at once, at least), so TDD still delivers more value.
My HDLC implementation, despite being grossly incomplete at the moment, falls under 202 lines of of production code. I have 303 lines of tests backing those production lines.
This brings me to another great advantage of Forth -- succinctness. C is quite verbose. TDD in C has a ratio of 4:1 to 10:1 test-to-production lines of code. The reason for this is, in C, you often have many branches inside a function. Every if, while, do, ?: operator, and switch statement represents a branch to one or more targets. That basically means that every one of those branch targets needs to be exercised by your tests.
With Forth, you can factor your code so finely that many of your decisions and their effects can be pulled into an independently tested chunk, which then gets re-used in other code. So, TDD with Forth tends to have about 1.5:1 code test-to-production code. This makes sense when you consider that a word should have no more complexity in it than a single IF statement, or BEGIN/WHILE, etc.
Quote:
Forth, Inc. says it is routine for them to take jobs and finish them in one-tenth the man-hours budgetted to do the same thing in C, and reduce the hardware requirements at the same time.
Again, in what context? Observe that Forth, Inc. targets embedded markets primarily, and that means they're working against hardware engineers, not software engineers. Or, if they are software engineers, they've obviously never worked a day in their lives in a software-as-a-service shop, where releases are done several times a day. When you have that kind of market-driven pressure to keep up, it's sink or swim, and believe me, you do find ways to swim.
I find, as a general rule, hardware engineers make the absolute worst software engineers you can imagine. I note that Chuck Moore made the same observation in one of his fireside chats. They have a tendency to write spaghetti code, they tend not to test edge cases, etc. Many embedded organizations also tend to be caught up in documentation-heavy
methodologies, like CMM, Sigma-6, and related practices. I have no problem with any of these if they're adequately justified, but coding takes a back-seat to things like design review meetings, code certifications and sign-offs, etc. Forth shops tend not to have such processes in place, based on conversations with professional Forth coders. That accounts for a major boost in productivity too.
Another thing to remember is that Forth, Inc. is a small fry in a big ocean of competing, and increasingly more popular, embedded technologies. They will make any claim they need to ensure their revenue stream continues.
Before I learned TDD, I also believed the 10x figure was unique to Forth (and to Lisp, for Forth and Lisp have the same interactivity aspect). After learning TDD, however, I find I'm just as productive in C (by which I mean that I can pump out comparable quantities of code with comparable feature sets) as I am in Forth.
Quote:
as you don't have to leave or suspend or background the text editor on the PC or use another window or anything like that to select a piece of code on the screen and try it on the target.
What you describe above is one of the sole justifications behind any IDE (it's where the "I" in IDE comes from -- Integrated). Eclipse is a great example, like I mentioned earlier. Designed originally for Java, but since expanded for other languages, when you "save" a file, it not only saves the source, but kicks off the compiler as well. At least for Java, it'll also (under some circumstances) kick the compiler off even before you click the Save button (you can tell Eclipse to auto-save every few minutes). The Arduino IDE is another example which allows you to reflash the microcontroller without leaving the IDE, with a single mouse-click.