Softpanorama

May the source be with you, but remember the KISS principle ;-)
Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and  bastardization of classic Unix

Forth

News  Programming Languages Usage and Design Problems Recommended Links  Solaris Open Boot Real Insights into Architecture Come Only From Actual Programming Software Engineering Conway Law
Debugging KISS Principle SE quotes History   Humor Etc

Forth is a procedural programming language without type checking, which uses Stack_machine as run-type environment and due to this has one of the most compact interpreters for a real-time programming language.  This is connected with the initial domain for the language: it was developed by Charles H. Moore for controlling instruments during the sixties at the Stanford Linear Accelerator Center (Forth -- Wikipedia)

Forth evolved from Charles H. Moore's personal programming system, which had been in continuous development since 1968.[9] Forth was first exposed to other programmers in the early 1970s, starting with Elizabeth Rather at the US National Radio Astronomy Observatory.[9] After their work at NRAO, Charles Moore and Elizabeth Rather formed FORTH, Inc. in 1973, refining and porting Forth systems to dozens of other platforms in the next decade.

Forth was a brilliant idea to use abstract stack machine to implement a very compact interpreter.  Only many years later it was replicated in Java VM (which paradoxically also was initially designed for controlling hardware).  In this sense Charles H. Moore was far ahead of his time and this aspect of Frth was underappreciated by other developers. For example creators of Unix such as Steve Bourne might avoid many mistakes in creating Unix shell (Bourne shell - Wikipedia)  if they adopted the implementation of shell interpreter in Forth, which would allow dramatically cut memory footprint in comparison with C implementation and as such would allow to crate a more "normal" language with full scale conditional constructs, arithmetic expressions, string operations and other attributes of modern programming language (original version of Borne shell had neither test command which was introduced only in 1981, nor functions, nor comments) .  Work on Borne shell started in 1976  or six years after Forth was exposed to programming community.

Later Moore founded Novix, Inc., where he developed the NC4000 processor (1983). This design was licensed to Harris Semiconductor which marketed it as the RTX2000, a radiation hardened stack processor which has been used in numerous NASA missions.

You can imagine what was the power and capacities of mini/micro computers in sixties, when one megabyte of memory (not a gigabyte, a single megabyte) was a lot. Classic Forth systems traditionally use neither operating system, nor file system. Instead of storing code in files, source-code is stored in disk blocks written to physical disk addresses. The word BLOCK is employed to translate the number of a 1K-sized block of disk space into the address of a buffer containing the data, which is managed automatically by the Forth system. Block use became rare since the mid-nineties, in a hosted system those blocks too are allocated in a normal file in any case. Still due to this legacy Forth interpreter remains very compact. That's why it is was used a basic for BIOS in old Sun servers (see  Solaris Open Boot environment).   It is perfectly suitable for implementation in a calculator. This actually comes down to the stack-based way of doing things in HP-48.

A Forth environment combines the compiler with an interactive shell.  The distinctive feature of the language is usage of reverse Polish expressions.  From Wikipedia:

 The user interactively defines and runs subroutines, or "words," in a virtual machine similar to the runtime environment. Words can be tested, redefined, and debugged as the source is entered without recompiling or restarting the whole program. All syntactic elements, including variables and basic operators, appear as such procedures. Even if a particular word is optimized so as not to require a subroutine call, it is also still available as a subroutine. On the other hand, the shell may compile interactively typed commands into machine code before running them. (This behavior is common, but not required.) Forth environments vary in how the resulting program is stored, but ideally running the program has the same effect as manually re-entering the source. This contrasts with the combination of C with Unix shells, wherein compiled functions are a special class of program objects and interactive commands are strictly interpreted. Most of Forth's unique properties result from this principle. By including interaction, scripting, and compilation, Forth was popular on computers with limited resources, such as the BBC Micro and Apple II series, and remains so in applications such as firmware and small microcontrollers.

...Forth often does not have local variables, however, nor is it call-by-value. Instead, intermediate values are kept in a second stack. Words operate directly on the topmost values in the first stack. ... After execution, the parameters have been erased and replaced with any return values. For arithmetic operators, this follows the rule of reverse Polish notation

Currently Forth is politically incorrect language. That's why we cover it here despite being far from actually using the language. It does not have all this fancy OO staff and taking into account to what extent OO is oversold that's a plus.  In other words, conceptually Forth is anti-Java ;-)

As suggested by OpenBoot's Mitch Bradley, Forth is much tougher to sell to management than to actually use by developers. Forth allows to use an incremental, iterative development process that spans from analysis to design to development to testing and back. It looks like Forth "paradigm" is the idea of a single tool that spans all phases of development. In this sense it is conceptually somewhat similar to such later scripting languages such as TCL and LUA.

At the same time this is a pretty powerful language. Here is one comment from I Hate Forth

It is perfectly suitable as a glue language for the set of C primitives. Forth interpreter can be written in any high level language including Java (although this does not make sence). In this sense it is more like a scripting language. For example, it is using a typeless parameter stack. See below.

Being fully interactive Forth lets programmers to build code incrementally. In this sense it is close to original Basic.  Debugging is also interactive which is a strong feature of the language. Usually you seldom just simply debugging code, in reality you are debugging your requirements and design, as well

The language is simple with few keywords. Developers essentially extend it by writing new "words" which each do more complex things, each of which then become inherent language keywords. So you extend language as you write your program. Sort of.  Actually it's more like C use of functions.

It's a nice environment to experiment as well as figuring out what the hardware registers actually do: 

When we're confronted with a peripheral with 50 programmable registers, most probably poorly documented, we've got no choice but to sit down and play with the device.

Forth speed and reliability is enough for writing high-performance internet servers. For example, (www.forth.org.ru, www.eserv.ru, www.etype.net)

This is a good overview by Peter Knaggs (Forth: An underview) reproduced below unchanged. His  1994 Ph.D. thesis is now also available online in full [PDF (900K)] or as individual chapters.


This document is intended to give an informal overview of the Forth programming system and perhaps more importantly, the method and philosophy of programming in Forth. It illustrates the language's history, most prominent features, usage, etc. We also describe the most common implementation method (based on the PolyForth system from FORTH, Inc.).
  1. What's in a name?
  2. History
  3. Features
  4. Programming
  5. The Dictionary
  6. The Stacks
  7. The Interpreters
    1. Keyboard Interpreter
    2. Address Interpreter
  8. Assembler
  9. Virtual storage
  10. Data Structures
  11. Programming Example
  12. Extensions
  13. Multi-Tasking
  14. Forth in hardware
  15. Standards
  16. Conferences/Journals
  17. Summary
  18. References

1. What's in a name?

According to Charles "Chuck" Moore (picture), its creator, Forth is so called because:
The first time I combined the ideas I had been developing into a single entity, I was working on an IBM 1130, a "third-generation" computer. The result seemed so powerful that I considered it a "fourth generation computer language." I would have called it Fourth, except that the 1130 permitted only five-character identifiers. So Fourth became Forth, a nicer play on words anyway.

2. History

The language "Forth" was developed during the sixties while Moore was working as a computer programmer at the Stanford Linear Accelerator Center, and later as a freelance engineer. The object in developing this new "programming tool" was to overcome the need for an engineer to learn a large number of methods for controlling compilers (linkers, assemblers and directives plus high-level languages).

The first program to be called Forth was written in about 1970. The first complete implementation was used in 1971 on a DEC PDP-11 for the National Radio Astronomy Observatory's 11-meter radio telescope in Arizona. This system was responsible for pointing and tracking the telescope, collecting data and recording it on magnetic tape, supporting an interactive graphics terminal on which an astronomer could analyse previously recorded data. The multi-tasking nature of the system allowed all these function to be performed concurrently, without timing conflicts or other interference.

The system was so useful that astronomers from all over the world began asking for copies. Its use spread rapidly and in 1976 Forth was adopted as a standard language by the International Astronomical Union.

The success of this application enabled Moore and Elizabeth ("Bess") Rather in 1973 to form "FORTH, Inc.", to explore commercial uses of the language. FORTH, Inc., developed multi-user versions of Forth on minicomputers for diverse projects ranging from data-bases to scientific applications such as image processing. Like the first application these often required a mixture of various facilities.

A version was developed, in 1977, for the newly-introduced 8 Bit microprocessors called "microFORTH". This was complemented by their "miniFORTH" product for minicomputers. Later (in 1979) these systems where replaced by the "PolyForth" product. This has since become one of the largest selling Forth system on the market.

"microFORTH" was successfully used in embedded microprocessor application in the United States, Europe, and Japan. The success of microFORTH lead to the formation of the European Forth Users Group (EFUG), later, in 1978, a group of computer hobbyists in Northern California formed the Forth Interest Group (FIG).

The members of FIG obtained a Forth system from an observatory. From this they developed a simple model which they implemented on several systems and (with permission from FORTH, Inc.) published listings and disks at very low cost. This model later became known as the FIG-Forth model. This action helping the rapid spread of interest in Forth. FIG now has 60 "chapters" in 15 countries.

3. Features

Forth is an interactive programming environment originally designed for programmers developing applications using mini- and micro-computers. Its primary uses have been in scientific and industrial application such as instrumentation, robotics, process control, graphics and image processing, artificial intelligence and business applications. The principal advantage of Forth include rapid, interactive software development and efficient use of computer hardware.

Forth is often spoken of as a language because that is its most visible aspect. However, Forth is more than a conventional programming language in that all the capabilities normally associated with a large portfolio of separate programs (compilers, editors, assemblers, etc.) are included within its range. It is also less than a conventional programming language in its deliberate lack of complex syntax characteristic of most high-level languages.

The original implementations of Forth were stand-alone systems that included functions normally performed by separate operating systems, editors, compilers, assemblers, debuggers and other utilities. A single, simple, consistent set of rules governed this range of capabilities. Today, although very fast stand-alone version are sill marketed for many processors, there are also many versions that run co-resident with conventional operating systems, such as MS-DOS and Unix.

Forth was not derived from another other language. As a result, its appearance and internal characteristics may seem unfamiliar to new users. But Forth's simplicity, extreme modularity, and interactive nature offset the initial strangeness, making it easy to learn and use. A new Forth programmer must invest some time mastering its large command repertoire. After a month or so of full-time use, the programmer could understand more of its internal working than is possible with conventions operating systems and compilers.

The most unconventional feature of Forth is its extensibility. The programming process in Forth consists of defining new words, actually new commands in the language. These may be defined in terms of previously defined words, much as one teaches a child concepts by explaining them in terms of previously understood concepts. Such words are called "high level definitions." Alternatively, new words may also be defined in assembly code, since most Forth implementations include an assembler for the host processor.

As a result of this extensibility, developing an application has the collateral result of developing a special "application-oriented language" for that type of application which may be applied to a similar application or used to modify this one.

Forth's extensibility goes beyond just adding new commands to the language. With equivalent ease, one can also add new classes of words. That is, one may create a word which itself will define words. In creating such a defining word the programmer may specify a specialised behavior for the words it will create which will be effective at compile time, at run-time, or both. This capability allows one to define specialised data types, with complete control over both structure and behavior. Since the run-time behavior of such words may be defined either in high-level or in assembler, the words created by this new defining word are equivalent to all other kinds of Forth words in performance. The system will also allow one to add new "compiler directives" to implement special kinds of loops or other control structures, such as a CASE structure.

4. Programming

Forth is an English-like language whose elements are named data items, procedures, and defining words capable of creating data items with customised characteristics. Procedures and defining words may be defined in terms of previously defined words or in assembler code.

Forth words are similar to subroutines in other languages. They are also equivalent to commands in other languages. Forth allows one to type a function name at the keyboard, the function will then be executed. However, placing the function name in a definition will cause a reference to the function to be compiled.

High-level words are defined as a collection of other words. This can be thought of as a macro in other languages or as an English definition as given in a dictionary. The new word is then added to the store of words that can be used. Its definition is added to the dictionary of words. There are few characters that cannot be included in a word's name. Many programming groups adopt naming conventions, using punctuation characters, to improve readability.

When a word is encountered, the dictionary is searched to discover the word's definition. The function associated with the word is ether executed, or a reference is compiled into a new definition. If, however, the word can not be found in the dictionary, the system will attempt to convert the word into a number. If it succeeds the number is placed onto a parameter stack. If it fails to convert the word into a number it will display the word and an error message, indicating that the word is unknown to the system.

Forth adheres to the principles of "structured programming":

This approach offers two distinct advantages:
  1. Debugging becomes easier, as new words are always constructed from previously defined and tested words. Each module can be individually executed to test its function.

     

  2. The inherent modularity enables the use of Forth as a "design-language", allowing top-down design but retaining bottom-up testing. Words can be used in a variety of programs, but their function need only be defined once.
These ensure the Forth software is developed quickly and efficiently and, if properly managed, can form the basis of its own documentation.

Forth is characterised by five major elements:

  1. a dictionary of words.

     

  2. two stacks, one for parameters, one for nesting.

     

  3. Keyboard (input stream) interpreter.

     

  4. an assembler.

     

  5. virtual storage.
The following is a selection of projects that have used Forth:

5. The Dictionary

A Forth program is stored in a dictionary. The dictionary occupies most of the memory used by the system. It consists of a threaded list of variable-length items, each of which defines a word. The content of each definition depends upon the type of word (data item, constant, sequence of operations, etc.). The dictionary is extensible.

Words are added to the dictionary by "defining words", the most common of which is : (colon). When : is executed, it constructs a dictionary entry for the word that follows it and enters into "compilation" mode. There are many different compilation methods, the most common of which is "Threaded Code", where the definition consists of a list of addresses referencing previously defined words. The definition is terminated by ; (semicolon). Figure 1 shows the dictionary entry for the definition:

: NETWORK ( -- ) OPEN LINK TRXT. ECHO CLOSE LINK ;

When a name entry is compiled into the dictionary (called the head of the definition) it has a link which is a pointer to the head of the previous word in the dictionary. The name of the new word is then placed in the dictionary (in this case "NETWORK"). Finally a pointer to a routine called "(:)" is compiled into the dictionary as the first part of the definition. This is a pointer to some code that will perform the action necessary to interpret the body of the definition. This is not the only compilation technique, but it is the most popular. This technique is known as Indirect threaded code as the first entry in the definition is a reference to some code that knows how to interpret the rest of the definition.

The remainder of the definition is referred to as its body. In compilation mode the system will search for the head of each of the words in turn. The address of the head is placed into the body of the definition, thus producing a list of addresses. Finally, when the ; is reached, the address of a routine called "EXIT" is compiled into the definition. The EXIT routine is designed to return control to the invoking word, thus acting as a subroutine return.

[Figure 1: Compiled dictionary entry]

6. The Stacks

Forth maintains two push-down stacks, or Last-In, First-Out lists. These provide communication between Forth words in addition to an efficient mechanism for controlling logical flow.

Although the structure of both stacks is the same, they have very different uses. The user/programmer interacts most directly with the data stack, which holds the arguments being passed between words. This replaces parameter lists used by conventional languages. It is an efficient internal mechanism which makes definitions intrinsically re-entrant. The second stack is known as the return stack and is used to hold return addresses for nested definitions, although other kinds of data are occasionally held there temporarily.

The use of the Data Stack (often called just "the stack") leads to a notation in which operands precede operators. This is a postfix notation often called RPN or "Reverse Polish Notation". The notation is based on the "Sentential Calculus" as developed by Professor Jan Lukasiewicz in the 1920s whilst working at Warsaw University (Lukasiewicz, 1963).

For an example let us take the word BLANK. This expects an address and count on the stack, placing the specified number of ASCII blanks into the region of memory starting at the given address. Thus:

PAD 25 BLANK

will fill the scratch region, whose address is placed on the stack by the word PAD, with 25 blanks. Application word are usually defined to work similarly. For example,

100 SAMPLES

might be defined to record 100 measurements in a data array. Arithmetic operators also expect values and leave their results on the stack. For example, + adds the top two number on the stack, replacing them both by their sum. Since the results of operations are left on the stack, operations may be strung together without the need to define temporary storage variables. For example, the expression:

tempn + ((reading mod interval) / interval) * (tempn+1 - tempn)

becomes:

reading interval mod interval / tempn+1 tempn - * tempn +

7. The Interpreters

Forth is fundamentally an interpretive system, in that program execution is controlled by data items rather than machine code. Interpreters can be slow, but Forth maintains the high speed required of real-time application by having two levels of interpretation. This is assuming that we are using the popular indirect threaded code system and not one of the native code generating compilers.

The first is the text interpreter, which passes strings from the terminal (or mass storage) and looks each word up in the dictionary. When a word is found it is executed by invoking the second level, the address interpreter.

The second level is the "address interpreter." Although not all Forth systems are implemented in this way it was the first and is still the primary implementation method. The address interpreter processes strings of address (or tokens) compiled in definitions created by : (colon), by executing the definition pointed to be each.

7.1. Keyboard Interpreter

On power-up, Forth start to execute an infinite loop known as QUIT. This is the Forth interpreter or keyboard interpreter.

: QUIT ( -- ) BEGIN RESET QUERY INTERPRET AGAIN ;

RESET clears the stacks, QUERY waits for user entry from the keyboard (or reads a line from a mass storage device) for commands to be used by INTERPRET to search the dictionary for a match, followed by execution. BEGIN and AGAIN are the program-control words that make it an infinite loop.

The QUIT loop provides the "interactive" nature of the language as it carries out commands as soon as they have been entered. The results can be inspected by the same keyboard interpreter. A new definition can be tested and the trial/error cycle repeated in a fraction of the time required by other edit-compile-link-test languages.

7.2. Address Interpreter

The last field of the definition's head is a pointer to the code to be executed by the function, the address of this field in known as the "code field address" or "cfa". For all high-level Forth words (words defined as a : definition) this will be the address of the address interpreter. That is the word (:).

The address interpreter has a register I that contains the address of the next entry in the list to be executed. This entry is the address of the cfa of the word called by the higher-level word currently being executed. It is the cfa that determines the nature (or type) of word.

In the example given in figure 2 the word A calls the word B, which in turn calls the word X, etc. The cfa is kept in an intermediate register W. Because of these two levels of indirect addressing and the dictionary-list structure Forth is also known as "Indirect Threaded Code".

[Figure 2: Indirect Threaded Code]

The address interpreter reads I and loads W with the address next in the list. It then reads from W and executes the code indicated by the code pointer. I is automatically incremented for the next entry in the list, as the first entry was the cfa I now points to the body of the definition. This is useful when defining data-type structures such as look-up tables, where the body contains the elements of the table.

In the case of high-level commands, the code field address points to (:), a routine that saves the current I on the return stack, then loads I from W and repeats the process. At the end of the high-level definition, the word EXIT is executed. This will restore the old value of I and program execution continues as before. These three actions, read I pointer, save I pointer, and restore I pointer, are the basic mechanism by which the address interpreter works.

The address interpreter has three important properties.

Most of the words in a Forth system will be defined by : (colon) and interpreted by the address interpreter. Most of Forth itself is defined in this manner.

8. Assembler

Most Forth systems include a macro assembler for the CPU on which they run. By using the defining word CODE the programmer can create a definition whose behavior will consist of executing actual machine instructions. CODE definitions may be used for I/O, arithmetic primitives, and other machine-dependent (or time-critical) processing. When using CODE the programmer has full control over the CPU, as with any other assembler. CODE definitions run at full machine speed.

This is an important feature of Forth. It permits explicit computer-dependent code in manageable pieces with specific interfacing conventions that are machine-independent. To move an application to a different processor one is only required to recode the CODE words, which will interact with other Forth words in exactly the same manner.

Forth assemblers are sufficiently compact (typically a KByte) that they can be resident in the system (as are the compiler, editor, and other programming tools). This means that the programmer can type in short CODE definitions and execute them immediately. This capability is especially valuable in testing custom hardware (See an example of testing hardware).

9. Virtual storage

The final unique element of Forth is its way of using disk (or other mass storage) as a form of "virtual memory" for data and program source. As in the case of the address interpreter, this approach is historically characteristic of Forth, but is by no means universal. The disk is divided into 1024 Byte blocks. Two (or more) buffers are provided in memory, into which blocks are read automatically when referred to. Each block has a fixed block number, which in native systems is a direct function of its physical location. If a block is changed in memory, it will automatically be written out when its buffer must be reused. Explicit reads and writes are not needed; the program will find the data in memory whenever it is accessed.

Such block orientated disk handling is efficient and easy for native Forth systems to implement. As a result, blocks provide a completely transportable mechanism for handling program source and data across both native and co-resident implementations.

Definitions in program source blocks are compiled into memory by the word LOAD. Most systems include an editor, which formats a block for display into 16 lines of 64 characters each and provides commands to modify the source. An example of a Forth source block is given in figure 5.

Source blocks have historically been an important element in Forth style. Just as Forth definitions may be considered the linguistic equivalent of sentences in natural languages, a block is analogous to a paragraph. A block normally contains definitions related to a common theme, such as "vector arithmetic". A comment on the top line of the block identifies this theme. An application may selectively load the blocks it needs.

Blocks are also used to store data. Small records can be combined into a block, or large records spread over several blocks. The programmer may allocate blocks in whatever way suits the application, native systems can increase performance by organising data to minimise disk head motion. Several vendors have developed sophisticated file and data base systems based on Forth blocks.

Versions of Forth that run co-resident with a host Operating System often implement blocks using files. In addition to providing a more common file based environment.

10. Data Structures

All high-level words share the same data structure (figure 1). The head of a word contains the data required by the keyboard interpreter to identify the word (see figure 3).

[Figure 3: Definition Header]

The "link" field contains the address of the head of the previous command in the dictionary list. This is required when searching the dictionary.

The "name length" field contains the number of characters in the full name of the word, followed by those characters. This is required to match the name of a command to that presented during interpretation. Most Forth systems only store the first 3 characters of the name, to avoid name clashing while minimising the space used (most systems allow one to select from between 3 to 31 characters).

The process of interpretation starts with the last entry in the dictionary and follows the link list backwards until a match is found. Although many systems now provide a hashing algorithm that splits the dictionary into separate lists, only one of which is searched, considerably reducing the search time.

The "code pointer" is the cfa of the first instruction to be executed for the word, this forms the first entry in the body of the definition. It is the address of the code that will interpret the rest of the definition, thus points to different code for different data types.

[Figure 4: Pointer to actions for Various language-level words]

The body of a word varies for different data types (see figure 4):
  1. In low-level assembler (CODE) definitions, the body contains a list of op-codes which defines the behavior of the command. The cfa therefore contains the address of the body.

     

  2. In data-structure commands such as VARIABLE and CONSTANT, the body contains the actual data. The cfa contains the address of a routine that manipulates this data as required. An example of a user defined data-structure is given in figure 5.

     

  3. In high-level : (colon) definitions, the body contains a list of addresses for all the previously defined words that make up its definition. The cfa is the address of the address interpreter (:).

11. Programming Example

Figure 5 contains a typical block of Forth source. It represents a portion of an application that controls a bank of eight LEDs used as indicator lamps on an instrument. It also indicates how Forth definitions can be combine to form an application environment.

 

Block: 180
0: ( LED control )
1: HEX 40 CONSTANT LIGHTS DECIMAL
2: : LIGHT ( n -- ) LIGHTS OUTPUT ;
3:  
4: VARIABLE DELAY
5: : SLOW 500 DELAY ! ;
6: : FAST 100 DELAY ! ;
7: : COUNTS 256 0 DO I LIGHT DELAY @ MS LOOP ;
8:  
9: : LAMP ( n -- ) CREATE , DOES> ( a -- n ) @ ;
10: 1 LAMP POWER      2 LAMP HV       4 LAMP TORCH
11: 8 LAMP SAMPLING  16 LAMP IDLING
12:  
13: VARIABLE LAMPS    0 LAMPS !
14: : LAMP-ON  ( n -- )        LAMPS @  OR DUP LAMPS ! LIGHT ;
15: : LAMP-OFF ( n -- ) INVERT LAMPS @ AND DUP LAMPS ! LIGHT ;     

Figure 5: Forth source block containing words that control a set of LEDs

Notice the comment on the first line (line 0) indicating the nature of the code given in the rest of the block. This is usually called the index line. Most Forth systems allow one to look at the first line of each block to discover what blocks are required for a particular application.

The LEDs are interfaced through a single 8 Bit port mapped to the address 40H. This location is defined as a CONSTANT on Line 1, so that it may be referred to by name; should the address change, one need only adjust the value of this constant. The word LIGHTS returns this address on the stack. The definition LIGHT takes a value on the stack and sends it to the device. The nature of this value is a bit mask, whose bits correspond directly to the individual lights. Thus, the command:

255 LIGHTS

will turn on all lights, while:

0 LIGHTS

will turn them all off. If the hardware changes, such that this is no longer the case, one only needs to change the definition of LIGHTS to suit the new hardware, while the rest of the application code need not be changed.

Lines 4-6 contain a simple diagnostic of the sort one might type in from the terminal to confirm that everything is working. The variable DELAY contains a delay time in milliseconds; execution of the word DELAY returns the address of this variable. Two values of DELAY are set by the definitions SLOW and FAST, using the Forth operator ! (pronounced "store") which takes a value and an address, storing the value in the address. The definition COUNTS runs a loop from 0 though 255 (the loop is started by the word DO and ended by the word LOOP). The word I places the current loop index on the stack, this is then sent to the lights. The system will then wait for the period specified by DELAY. The word @ (pronounced "fetch") fetches a value from an address, in this case the address supplied by DELAY. This value is passed to MS, which waits the specified number of milliseconds. The result of executing COUNTS is that the light will count from 0 to 255 at the desired rate. To run this one would type:

SLOW COUNTS   or   FAST COUNTS

Lines 8-10 provide the capability of "naming" individual lamps. In this application they are being used as indicator lights. The word LAMP is a defining word which takes a bit mask (representing a particular lamp) as an argument, and compiles it as a named entity. The word CREATE compiles a header into the dictionary, while the word , (comma) places the mask into the body of the definition. The word DOES> places the address of the following code into the cfa of the new word. Therefore when the new word is executed its action is to fetch the contents of the first item in the body of the new word. Lines 9 and 10 contain five uses of LAMP to name particular indicators. When one of these words, such as POWER, is executed, the mask is returned on the stack. In fact, this behavior is identical to the behavior of a Forth CONSTANT. The LAMP definition is included here for example. The ability to define such a "defining word" with the use of CREATE and DOES> is one of the most powerful features of the language, allowing one to define "intelligent" application based data structures.

Finally, on lines 13-15, we have the words that will control the light panel. LAMPS is a variable that contains the current state of the lamps. The word LAMP-ON takes a mask (supplied by one of the LAMP words) and turns the lamp on. It changes the state of that particular lamp, saving the result in LAMPS. LAMP-OFF will turn the given lamp off, also changing the LAMPS state.

In the remainder of the application, the lamp names and LAMP-ON, LAMP-OFF are probably the only words that will be executed directly. The usage will be for example:

POWER LAMP-ON   or   SAMPLING LAMP-OFF

as appropriate, whenever the system indicators need to be reset.

The time to compile this block of code on the system was about half a second, including time to fetch it from disk. So it is quite practical (and normal practice) for a programmer to simply type in a definition and try it immediately. In addition, one always has the capability of communicating with external devices directly. The first thing one would do when told about the lamps would be to type:

HEX FF 40 OUTPUT

and see if all the lamps come on. If not, the presumption is that something is amiss, since this phrase directly transmits the "all ones" mask to the device. This type of direct interaction is useful in application involving custom hardware, as it reduces hardware debugging time.

12. Extensions

As the Forth language is extensible large vendors have produced a number of "extensions" to there Forth systems to allow for special needs. Such extensions include auto documentation, terminal drives, disk file maintenance, data base management, target-compilers, cross-compilers and meta-compilers.

A "target-compiler" allows the use of a host CPU, such as an IBM PC, for developing systems. Programs can be edited and interactively tested at the keyboard. These programs can then be compiled for the target environment and the appropriate ROM code produced. One function of the target compiler is to strip out any unproductive required code, such as the compiler, editor and assembler. By doing this, run time ROM overhead can be reduced from the 8 KBytes of development system to a minimum of approximately 600 Bytes.

The "cross-compiler" acts in much the same way as the target-compiler. Allowing the user to develop (and test) code on a host system. The cross-compiler will then compile the Forth system, in much the same manner as the target-compiler, except the target of the cross-compiler is a different CPU, with a different machine language. This facility allows us to develop systems for new CPU's very quickly. As the majority of Forth systems are written in Forth we need only write an assembler for the new processor and cross-compile the Forth system for the new processor. Most Forth systems are developed using this method. As a result, Forth is usually one of the first languages to be implemented on a new processor.

The process of writing one Forth compiler in another is referred to as "meta-compilation".

13. Multi-Tasking

Multi-tasking Forth systems have existed since the beginning. These systems are not just language processors, but contain operating system characteristics as well. Many of these integrated systems run entirely stand-alone, performing all necessary operating system functions.

The Forth operating environment is fast and as a result, Forth-based systems can support both multi-tasking and multi-user operation even on computers whose hardware is usually thought incapable of such operation. For example, one producer of telephone switchboards is running over 50 tasks on a Z80. There are several multiprogrammed products for the IBM PC, some of which even support multiple users. Even on computers that are commonly used in multi-user operations, the number of users that can be supported may be much larger than expected. One large data-base application running on a single 68000 processor has over 100 terminal updating and querying its data-base, with no significant degradation.

Multi-user systems may also support multiple programmers, each of which has a private dictionary, stacks and a set of variables controlling that task. The private dictionary is linked to a shared, re-entrant dictionary containing all the standard Forth functions. The private dictionary can be used to develop application code which may later be integrated into the shared dictionary.

Figure 6 shows the classical method of multi-tasking in a Forth system. This is a "voluntary round robin" scheduler. It is the most common implementation of multi-tasking found in Forth systems. However, some implementations use time slicing or priority scheduling and other preemptive algorithms. In this system each task has a user area where its control variables, private dictionary, and stacks are kept. The first field of this user area is the STATUS variable. A task has two possible values for this variable, awake or asleep.

[Figure 6: Four tasks in a voluntary round robin scheduler]

For a task to be selected for execution it must be awake. When the task has been selected its status is reset to asleep. The task executes until it voluntary re-enters the scheduler by executing the word PAUSE. This will reset the task's status back to awake prior to re-entering the scheduler. When the scheduler comes around again the task will continue execution from after the PAUSE.

In addition to the PAUSE word, a task could also re-enter the scheduler by executing the STOP word. This is similar to PAUSE except that it does not reset the task's status to awake, thus it will re-enter the scheduler with the task's status set to asleep. This means that the task will not be executed again, until such time as its status is set to awake by another task, or an interrupt.

The system is programmed in this manner so as to allow for interrupts. When an interrupt occurs, some machine dependent code will set a given task's status to awake, thus when the scheduler next comes to that task it will be executed. The STATUS variable is set to asleep when the task is executed, to allow for an interrupt occurring while the task is executing. Hence, if a task executes a STOP its status is not changed, thus if an interrupt has set the task's status to awake whilst the task was executing it will re-enter the scheduler with its status set to awake. Thus allowing us to buffer an interrupt. However, this means that when a task is giving up the processor voluntarily and wishes to continue execution next time the scheduler comes around, it must set its status to awake.

The round robin scheduler takes the address stored in the LINK user variable as the address of the next task. If that task's STATUS is set to awake, it is executed, otherwise the scheduler will take its LINK address and move on to the next task. This can be seen in the figure 6. There are two main problems with this method:

  1. When a task voluntarily gives up the processor, so that other tasks may run, the time between relinquishing the processor and regaining it is unknown.

     

  2. The time between an interrupt setting a task's status to awake and that task being executed is also unknown.
The careful use of PAUSE in the underlying system and the speed of the Forth system overcome these problems in the majority of applications.

14. Forth in hardware

In the early 1980s, Rockwell produced the 65F11. This was a variant of the 6502 processor with Forth primitives in on-board ROM. This chip has been used (and still is being used) successfully in many embedded microprocessor applications.

In 1981, Chuck Moore undertook to design a chip-level implementation of the Forth virtual machine. Working first at FORTH, Inc. and subsequently with a start-up company formed to develop the chip, Moore completed the design in 1984 and the first prototypes were produced in early 1985. More recently, Forth processors have been developed by Harris Semiconductor Corp., Johns Hopkins University and others. Forth-based chips offer extremely high performance, generally comparable with RISC chips but without the programming difficulties that accompany conventional RISC processors.

15. Standards

The Forth community has agreed that a standard base from which extensions and application can be built is required. The first of these standards was started in the mid-1970's by FIG (the Forth Interest Group). This was later to become known as the FIG-Forth standard.

However, the first major effort to standardise Forth was a meeting in Utrecht in 1977. The attendees produced a preliminary standard and agreed to meet in the following year. The 1978 meeting was also attended by members of the California based FIG. Over the next couple of years a series of meetings, attended by both users and vendors, produced a more comprehensive standard called Forth-79.

Although Forth-79 was very influential, many Forth users and vendors found serious flaws in it. In 1983 two further meetings where held to produce the refined Forth-83 standard.

Encouraged by the widespread acceptance of Forth-83, a group of users and vendors met in 1986 to investigate the feasibility of an American National Standard. The Technical Committee for American National Standard Forth, the ANS ASC X3/X3J14 committee held its first meeting in 1987 with the objective "to achieve an acceptable standard which will result in broad compliance among all major vendors of Forth language products, with minimum adverse impact upon transportability from existing systems in use." In 1994, some seven years later, the new standard was finally produced. This is the most far reaching of all the standards. It was open to public review thought its development, with comments coming from 5 different countriess. The International Standards Organisation accepted this as an international standard some two years later (although it was not published until the following year, 1997).

16. Conferences/Journals

As people work with Forth and develop useful extensions, so the language is developed. There are three annual conferences held with regard to the development of the Forth language: Many of the ideas are first presented, discussed, and debated in one of the various Forth related Journals:

17. Summary

Forth may be seen as a processor with two stacks (parameter and return), whose assembly code is extendible. The Forth interpreter can be seen as a full macro-assembler and fully integrated operating system for this abstract processor.

This provides us with an interactive debugging environment where we can add new macros (high-level definitions) and new instructions (low-level (CODE) definitions). It even allows us to extend the macro system by defining new data types (defining words (CREATE/DOES>)). As this interpreter can also act as a fully integrated operating system the programmer need only learn the one tool.

Forth has four primitive virtues: (a) Intimacy, (b) Immediacy, (c) Extensibility, and (d) Economy. It has two derived virtues: Total Comprehension, and Symbiosis.

Forth is not just a language, its more of a philosophy for solving problems. This can be summarised with the acronym K.I.S.S. (Keep It Simple and Stupid). To quote from Jerry Boutelle (owner of Nautilus Systems in Santa Cruz, California) when asked "How does using Forth affect your thinking?" replied:

Forth has changed my thinking in many ways. Since learning Forth I've coded in other languages, including assembler, Basic and Fortran. I've found that I use the same kind of decomposition we do in Forth, in the sense of creating words and grouping them together. For example, in handling strings I would define subroutines analogous to Forth's CMOVE, -TRAILING, FILL, etc. More fundamentally, Forth has reaffirmed my faith in simplicity. Most people go out and attack problems with complicated tools. But simpler tools are available and more useful. I try to simplify all the aspects of my life. There's a quote I like from Tao Te Ching by the Chinese philosopher Lao Tzu: "To attain knowledge, add things every day; to obtain wisdom, remove things every day".
Or to quote Antoine Lavoisier (1789):
It is impossible to disassociate language from science or science from language, because every natural science always involves three things: the sequence of phenomena on which the science is based, the abstract concepts which call these phenomena to mind, and the words in which the concepts are expressed. To call forth a concept, a word is needed; to portray a phenomenon, a concept is needed. All three mirror one and the same reality.
This embodies the philosophy behind Forth.

18. References

The Forth Monitor

The Forth Monitor, the default mode in OpenBoot, is an interactive command interpreter that gives you access to an extensive set of functions for hardware and software diagnosis. You'll also see the Forth Monitor referred to as new command mode. These functions are available to anyone who has access to the system console.


Top Visited
Switchboard
Latest
Past week
Past month

NEWS CONTENTS

Old News ;-)

[Sep 10, 2019] Thinking Forth by Leo Brodie is available online

Aug 31, 2019 | developers.slashdot.org

mccoma ( 64578 ) , Friday February 22, 2019 @06:10PM ( #58166468 )

Thinking Forth ( Score: 3 )

I wish I had read Thinking Forth by Leo Brodie ISBN-10: 0976458705 ISBN-13: 978-0976458708 much earlier. It is an amazing book to really show you a different way to approach programming problems. It is available online these days.

Itsy-Forth: the Dictionary and Inner Interpreter

April 3, 2012 | retroprogramming.com

Itsy Forth is a minimal Forth compiler implemented in under 1kB. Earlier we examined Itsy's outer interpreter. Now we take a closer look at the dictionary and inner interpreter.

Forth Dictionary

Itsy's dictionary is a linked list holding the name and code for each word (subroutine). Each entry in the list has a header containing a link, counted string and XT (execution token). For example here's the dictionary entry for nip:

        ; header
        dw link_to_previous_word
        db 3, 'nip'
xt_nip  dw docolon
        ; body
        dw xt_swap
        dw xt_drop
        dw xt_exit

The first line of the header links to the previous word in the dictionary. The second line holds the word's name preceded by its length. The final line contains the XT, a pointer to the routine which performs the actual operation of the word. Itsy uses four different XTs:

Macros

I'm not a big fan of macros. They're ugly and lock the code to a particular assembler. On the other hand they can add flexibility and make the code less prone to errors. Compare the definition of + with and without macros:

Without macros:

        dw link_to_previous_word
        db 1, '+'
xt_plus dw mc_plus
mc_plus pop ax
        add bx,ax
        jmp next

With macros:

        primitive '+',plus
        pop ax
        add bx,ax
        jmp next

The NASM macros to set up headers and maintain the linked list are pretty simple:

        %define link 0
        %define immediate 080h

        %macro head 4
        %%link dw link
        %define link %%link
        %strlen %%count %1
        db %3 + %%count,%1
        xt_ %+ %2 dw %4
        %endmacro

        %macro primitive 2-3 0
        head %1,%2,%3,$+2
        %endmacro

        %macro colon 2-3 0
        head %1,%2,%3,docolon
        %endmacro

        %macro constant 3
        head %1,%2,0,doconst
        val_ %+ %2 dw %3
        %endmacro

        %macro variable 3
        head %1,%2,0,dovar
        val_ %+ %2 dw %3
        %endmacro

Macro Examples

constant is used to define a Forth constant. E.g. to define false = 0:

        constant 'false',false,0

variable creates a Forth variable. E.g. to create base and initialise to 10:

        variable 'base',base,10

primitive sets up an assembly language word. E.g. to create drop:

        primitive 'drop',drop
        pop bx
        jmp next

colon defines a compiled Forth word. E.g. to define nip:

        colon 'nip',nip
        dw xt_swap
        dw xt_drop
        dw xt_exit

Register Allocation

Itsy's use of the registers is similar to most 8086 Forths. The system stack is used for the data stack while a register is used for the return stack. Note the top element of the data stack is kept in a register to enhance performance:

Itsy's Inner Interpreter

The Forth inner interpreter needs only three simple routines:

docolon dec bp
        dec bp
        mov word[bp],si
        lea si,[di+2]

next    lodsw
        xchg di,ax
        jmp word[di]

        primitive 'exit',exit
        mov si,word[bp]
        inc bp
        inc bp
        jmp next

Next we'll define approx 30 words and finally get the interpreter up and running. In the meantime I'd love to hear any comments on the code so far :-)

Posted by John Metcalf

Labels: forth, programming

5 April 2012 at 08:30

Instead of using assembler-specific macros, you could use a general macro processor. Even though "the C pre-processor is for C," that hasn't stopped people from using it to pre-process assembly -- myself included :-). Something like m4 might also be an option.

17 April 2012 at 10:20

I second the M4, it is pretty awesome (was made for this kind of stuff). I have also seen people use FASM macro's for things other than assembler. It has a very powerful macro language. You could also use forth as a macro language, it works really well for writing assemblers.

13 July 2012 at 18:08

Any examples of FASM macros implementing FORTH elements would be useful to me. [email protected]
Thanks, Clyde

17 June 2014 at 11:40

I thought that RevaForth was an example, since that's what Google told me ... but when I downloaded it and looked at the sources, its NASM format. Don't know if that helped, but if it does, google for Reva201101.zip

Delete

Programming a Problem-Oriented Language by Chuck Moore

12/10/2012 | forth.org

This is an unpublished book that Chuck wrote around June 1970, just after he'd written the first versions of Forth. The original document was made web-accessible in 2011 and can be found here. This pdf version has been cleaned up and reformatted by Juergen Pintaske.

[Jan 07, 2014] I Hate Forth by Jack Ganssle

Comments to the article are much more interesting the article, which with its pretentious title belongs to classic "Goto is harmful" category (aka religious zealots argumentation). Title alone undermines author arguments and demonstrates the limits of his ability to think about the problem ;-)
July 31, 2001 | Embedded.com
David Graham

Your arguments against Forth sound like you are concerned that its interactive convenience allows programmers to be lazy. Maybe we should not be allowed to have upholstered chairs either.

Your assertion that there is no better environment for figuring out hardware reassures me that I would gain little from becoming proficient in C. I am an embedded software contractor and have programmed with Forth for over 10 years, writing 3 or 4 applications a year, each with 20-30K bytes of compiled code.

Since every project involves a significant investment of time in figuring out hardware, it sounds like I am already using the best tool for the job. I have learned enough C to translate example C code into Forth a few times, and each time the Forth compiled code has required less code space, so I am not sure why you disparage Forth's efficiency. No Forth I have ever used compiles comments.

David Graham
President
Graham Automation, Inc.

Don Warbritton

Jack - You forgot to mention that Forth also saves the cost of a debugger. I currently have a $4000 MMDS from Motorola and a $9000 Hitachi emulator on my desk.

So Forth eliminates expensive emulators, and simplifies test of hardware and software.

What it doesn't do is force you to write well documented, structured code. I'm afraid this argument suffers from a small flaw. "C", the most popular embedded software language also does not force you to write well documented, structured code. As one who has to work on code written by others, I am much more comfortable working on "Programmer A's" assembly code than "Programmer B's" C code. The quality of the code is not dependent on the language used, but, outside of a well defined process, is dependent entirely on the quality of the programmer.

I wouldn't force anyone to use Forth. An important factor in choosing a High Level Language (HLL) is maintainability. It can be bad enough learning the tricks of the different flavors of any HLL from different vendors, or for different processors, there's no need to throw in a new language too. And Forth is not supported by enough vendors to cover all applications. I could argue more on the merits of Forth, but like the Apple Macintosh, or UNIX, the marketplace has decided that "C" is the HLL of choice, and the embedded systems market is apparently not big enough to support multiple languages. Like the Mac, Forth may be best for those who work by themselves on a small number of products.

Don Warbritton
Software Engineer
Ametek/Dixson

Andrey Cherezov

I'm using Forth for 11 years for DOS/Windows (financial and internet software) and embedded development. Before that I few years used C/C++, Pascal, Assembler, Lisp, Smalltalk. I select Forth, because it gives me possibility to do my work quickly, so less expensive for customers. And it makes strong code... Forth code don't need to be extensively documented, because it is self-documented. Where you've seen "50-lines function"? Most of Forth functions - 1-2 lines. It is impossible to make an error in such function, so coding is highly modular, reliable, stable and reusable. Forth code reliability is enough for writing high-performance internet servers. For example, some our web-servers (www.forth.org.ru, www.eserv.ru, www.etype.net) are "powered by Forth", i.e. web-servers, ftp-servers and mail-servers on these computers are written in Forth language. You can see source code of our Forth web-server at http://acweb.sourceforge.net/. It is written using SP-Forth (it also open source).


[Sorry for my poor English].

Andrey Cherezov
Software Engineer
Delosoft.com

Tamara Cravit

As a software developer for the past decade, I have coded in a wide variety of languages. I've seen and worked on a lot of code written by others. The issues raised by this article are not unique to Forth. Any programmer can undocumented code which is difficult to understand. Any programmer can write well-documented code which is easy to understand. I find badly written Forth code to be no more or less readable than badly written C or Perl code. The problem isn't the tool, but is how the tools are used. I've developed a number of PalmOS applications in Forth lately, and other than getting re-accustomed to the stack-based way of doing things that I used to use on my HP-48, I've not found the adjustment to be a difficult one. I do comment my code, extensively, and that's a good thing no matter what language one uses.

Another poster in this thread wrote that Forth "instills bad design from the very onset of a project that tends to follow it till it's slow painful death". In my experience, if you have a bad design, it doesn't matter what tools you implement it with. If you're willing to take the time, you can write well-designed software in most any language.

Tamara Cravit
Partner
Taylored Software

Recommended Links

Google matched content

Softpanorama Recommended

Top articles

Sites

Top articles

Sites

Ebooks

Implementations (Wikipedia)

Because the Forth virtual machine is simple to implement and has no standard reference implementation, there are numerous implementations of the language. In addition to supporting the standard varieties of desktop computer systems (POSIX, Microsoft Windows, Mac OS X), many of these Forth systems also target a variety of embedded systems. Listed here are some of the more prominent systems which conform to the 1994 ANS Forth standard.



Etc

Society

Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy

Quotes

War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes

Bulletin:

Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law

History:

Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D


Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to to buy a cup of coffee for authors of this site

Disclaimer:

The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Last modified: September, 10, 2019