Top 10 List

Ways to Simplify Programming

By Mike Elola

10. Optimize the benefits of subroutines

 Choose a language that minimizes the run-time overhead of subroutines. That way, your use of many small, discrete, and reusable functions pays even greater rewards.

 Forth minimizes subroutine overhead, heightening the appeal of a modular programming style based on subroutines. Languages such as 'C' set up and break down stack frames before and after each subroutine call. By avoiding this burdensome stack-management activity, Forth liberates subroutine calls from ungainly run-time overhead.

 Forth can be characterized as a lean execution engine that is accompanied by an impressive collection of reusable subroutines. Forth starts by prompting you to enter commands, each of which starts an execution sequence that can thread its way throughout many different routines. Threads of execution direct the interplay of many routines so that various functions can spring to life, such as a compiler, an editor, and a host of other development tools.

 Like applications in other operating environments, Forth subroutines can be run as commands. This facilitates fast iteration through change compile-test cycles for new Forth subroutines. For a 'C' subroutine to run as a discrete unit, source code must be altered and recompiled to meet the operating system's definition of an executable code resource. Through its incorporation of a run-time engine, Forth can dictate the forms executable resources may take. One of those forms is simple, efficient subroutines. (Forth can offer advantages that are lacking in less complete systems)


9. Modularize down to the Subroutine level

 Choose a language suited to a programming style involving many short subroutines that are easily understood, easily tested, and easily reused.

Forth lets you compose a long program as a moderate-length collection of short subroutines. For example, the broad functionality of Forth results from a collection of about one hundred subroutines, most of which call about seven others. When an execution thread is unwound, a lengthy execution sequence is often produced. Yet because each subroutine is defined and compiled only once, a compact, memory-conserving program can result.

A style of programming based on many small subroutines has been practiced by virtually all vendors of commercial Forth systems. Because of this, Forth provides access to a large number of useful and trivial-to-reuse data processing functions.


8. Scalability that does not sacrifice cohesiveness

 Choose a programming language that is seamlessly extensible and scalable, so the system is not distributed by your extensions or cutbacks. Such a system remains cohesive despite its reconfiguration.

Because Forth is subroutine-based, subroutines are the natural way to expand Forth or to scale it back. The Forth dictionary is designed to offer seamless expansion of the Forth Environment. Of course, your newly compiled routines are accorded exactly the same treatment as the original, vendor-supplied routines. And by unlinking subroutines from the Forth dictionary, you can prune the dictionary and free memory.

Forth is profoundly extensible. Unlike most languages, Forth extensibility is not limited to "functions," nor to any other restricted language element. For example, you can add new control-flow directive that is equivalent to a C switch to help you specify state machines more easily or more clearly.

Code resources are created in several ways. One way is to compile source code. Alternately, code resources may be supplied by the Forth vendor. However code resources came to be, a single Forth execution engine handles them exactly the same way. This regularity permits a run-time system that is small and efficient -- permitting applications derived from Forth to be pared down to very small sized. To create a commercial application, you minimize Forth before extending it with the final versions of your own subroutines. Even using large Forth systems, you can build small applications to suit embedded applications (ranging between 2 and 30 kilobytes).


7. Syntactically lean programming languages

 Languages that are syntactically lean encourage you to create source code that is readily understood and easier to maintain. You should not have to think like a parser to untangle the meaning of source code! Forth shows how a language of homogeneous elements defeats the need for syntax-processing -- both by humans and computers.

Forth's regularity eliminates the need for a parser to discriminate between elements that may be deeply nested. In contrast to the multiple-try algorithms of other compilers, the Forth compiler uses algorithms that are orders of magnitude simpler.

A forth system has the simple task of recognizing word-size elements only. A simple lookup table for subroutine names addresses most of its needs.


6. Meaning directly conveyed by source code

 Choose a language that makes the meaning of source code obvious. Accordingly, programming systems should not steal any of your control over the evaluation sequence. To regain the control that should be exclusively yours, avoid languages with precedence rules and with evaluation-altering parentheses.

Let's lay to rest the myth that you need computer assistance in this regard. You should be able to determine the meaning of source code without the hardship of nontrivial, code-resequencing rules. Parentheses are a nuisance rather than a convenience. This grievous type of activity leads to unexpected bugs, extra hours of debugging, and greater maintenance costs.

This affliction can be completely remedied through the prescription of postfix notation. In Forth, you establish the order of evaluation by arranging the source code into the desired sequence. That way, the sequence you see is always the evaluation sequence you get (WYSIWYG). Because there is only one possible way it will be handled, Forth code is more likely to behave as you expect it to.

Computers require postfix ordering of operations. (an add operation is meaningless if the operands are not identified first.) When you adopt postfix notation too, your source code can more accurately convey your intentions on down to the computer chip doing the work.

You may already consider it a hindrance, this distasteful practice of peppering your source code with parentheses. This process is actually an encoding process, after which the meaning of source code is a step removed from your view. A substantial "decoding" step is required to account for precedence rules, as well as any parentheses that are present.


5. Seamless development and run-time environments

 Development environment tools should offer you a faithful preview of how code will behave when run in an unembellished target environment.

The Forth user interface joins Forth's development and execution environments so seamlessly and transparently that a hybrid of the two is produced.

Nothing of substance distinguishes the target execution environment from the Forth development environment. The development environment is merely a subroutine-extended superset of the static execution environment that travels with your applications. Accordingly, test results obtained in the full Forth environment are much more trustworthy than those obtained in development systems that emulate an execution engine rather than incorporate it.

A full development environment for Forth includes a fair number of services and tools. A finished application often does not need Forth's user interface to read and process commands whenever the system is idle. (The system is "idle" when it is not processing previously entered commands.)


4. Support for rapid development

 Choose a development system that lets you conveniently exercise recently compiled code, that supports incremental compilation, and that offers a way to minimize recompilation efforts. One consistent user interface for all development tools can also boost productivity by reducing errors and learning difficulty.

To exercise recently compiled code without delay, you need a run-time facility that is continuously available as part of your development environment. The run-time engine must be able to respond to you, letting you determine when and how code you have compiled will run. Forth responds to commands you enter to compile or edit source code -- and commands to run, debug, or discard compiled code. In these and other ways, Forth offers you a host of integrated tools for constructing programs rapidly.

With Forth tools, you can incrementally exercise and verify components of your application even when you have programmed only a small fraction of it, such as one subroutine.

Forth supports its own form of incremental compilation. First you compile and fix the lowest level of subroutines. Afterwards, you pay similar attention to the subroutines that rely on the ones you just refined. In the process, you discard only a portion of the previous compilation efforts -- the you need to refine and recompile.

Forth comes pumped up with many tools for programming, including those for extending the compiler and those for compiling data structures. (The latter give you control over how values are actually stored in memory for variables and other types of data.) You can also extend the user interface or craft new tools to better facilitate development.


3. Friendly compiled-code tools (debuggers, etc.)

 Choose a development environment that provides powerful tools for inspecting and testing compiled code.

When compiling a new Forth routine, the compiler stores the executable addresses of its constituent subroutines in memory (or an equivalent process, depending on the Forth you use). This makes the memory image of a compiled routine subject to meaningful inspection. By passing a decompiler an appropriate address to start examining, the Forth source code that led to the values stored in memory can be closely reconstructed. Likewise, the debugger's display of Forth execution flow can closely match source code listings.


2. Interoperability

 Choose a development system that takes advantage of your computer's operating system. That way you retain the help of popular tools and applications during development.

Most Forth vendors offer Forth systems designed to run under a host operating system. Many can take advantage of external editors and code-management tools from numerous vendors. Recently, Forths have begin to appear that can use code resources (object files) created using other programming languages.


1. Forth

 Choose Forth. It is by far the most convenient way to meet the goals mentioned here.

Most embedded systems programmers using Forth have little or no need for linkers, preprocessors, logic analyzers, in-circuit emulators, specialized debuggers, object-oriented tools and libraries, real-time operating systems, cross-compilers, and so on down the list of currently available tools.

Forth orbits closely around an efficient engine for subroutine execution. It has been adorned with just the right initial subroutines to provide functionality that you normally would associate with a much larger development system. Nevertheless, Forth's simplicity serves your needs while increasing your productivity.


Mike writes a regular column (Fast Forthward) for Forth Dimensions magazine. In the distant past, he wrote Forth programs for the Apple II. Presently, he is developing Forth systems using C. To stay one step ahead of the bill collector, Mike has also been the author of user manuals, help systems, and developer documentation, besides tools used to compile UNIX reference manuals.


Copyright 1993 by Forth Interest Group, Inc. All rights reserved.
Send E-Mail
AMResearch Home

Last modified: 10March96 by AM Research