Penguin
Annotated edit history of Forth version 35, including all changes. View license author blame.
Rev Author # Line
25 AristotlePagaltzis 1 !!! <tt>YOU FORTH LOVE IF HONK THEN</tt>
24 AristotlePagaltzis 2
35 MahaloMarlin 3 [Forth] is a [Stack]-based ProgrammingLanguage developed by ChuckMoore in the 1960s (see the [Evolution of Forth | http://www.forth.com]). [Forth] code is written in ReversePolish notation, since it works directly with the stack (actually, several stacks). There is no implicit stack management, which means that function calls are very fast: the arguments are whatever is already on the [Stack] when the function is called and the return value is whatever is left on the [Stack] at return.
24 AristotlePagaltzis 4
29 AristotlePagaltzis 5 [Forth] is defined in terms of itself more so than probably any other language. A [Forth] system generally consists of only a tiny kernel and a small number of Forth functions written in AssemblyLanguage, but even most of the compiler is written in Forth, as is the standard library. Real [Forth] geeks write their own [Forth] kernels from the metal up. (ChuckMoore creates his own [Forth] machines from silicon.) It doesn't take much effort once you've absorbed the [Forth] philosophy – there is shockingly little holding [Forth] up. This is in tune with ChuckMoore's philosophy of brutal simplicity in software engineering.
24 AristotlePagaltzis 6
31 KragenSitaker 7 [Forth] produces very compact code. A whole interpreter and development system will easily fit into 8 kilobytes and leave plenty of room for user code. Back when architectures with 8 kilobytes of [RAM] weren't just the computers that you developed ''for'' but also the computers you developed ''on'', [Forth] was very popular. Today it is most popular in embedded systems and other highly constrained environments: f.ex., it is the language of choice for NASA on many satellites and planetary probes, where its compactness and functional correctness (see below in ''Comparison with Haskell'') outweigh the speed of AssemblyLanguage. It forms the basis for the OpenFirmware and the [RPL] language used in HewlettPackard calculators and is used in some of UCSD's music courses. It has been used successfully in ArtificialIntelligence research.
24 AristotlePagaltzis 8
29 AristotlePagaltzis 9 !!! Concepts
24 AristotlePagaltzis 10
29 AristotlePagaltzis 11 ''This is a general description of how [Forth] works. It's __different__. If you like [Brainf*ck] you will like [Forth].''
24 AristotlePagaltzis 12
29 AristotlePagaltzis 13 [Forth] functions are called ''words''. They are organised in the ''user dictionary''.
24 AristotlePagaltzis 14
25 AristotlePagaltzis 15 A [Forth] machine has two stacks. When subroutines (called ''words'' in [Forth] lingo) are called they pop arguments off the ''parameter stack'' and push back return values. The ''return stack'' holds the return addresses of word calls.
24 AristotlePagaltzis 16
29 AristotlePagaltzis 17 Finally, the ''input buffer'' for the [Forth] parser forms an integral part of a [Forth] system.
24 AristotlePagaltzis 18
29 AristotlePagaltzis 19 Words manipulate the parameter stack directly to perform calculations on their arguments and leave return values. Traditionally, there are no local variables in [Forth] (but there are global variables, which are simply pointers stored under a name in the dictionary): the parameter stack is used for all temporary storage. There are lots of words for many simple stack manipulations, such as pushing another copy of the top-most value, dropping it, rotating the stack in either direction, rotating part of the stack, etc. Programming in [Forth] means keeping track of what is supposed to be on the stack at any point.
24 AristotlePagaltzis 20
29 AristotlePagaltzis 21 The dictionary is also structured like a stack. As words are defined, they are added to the top of the stack. You can recycle memory by ''forgetting'', which means dropping all the entries at the top of the dictionary down to some word you specify (usually you do this implicitly by executing a word defined using <tt>MARKER</tt>). Sets of words are usually loaded/defined as a unit, and are usually referred to as a ''vocabulary'', analogous to libraries in other languages. The first vocabulary is a tiny kernel of word definitions written in MachineCode, then there is a standard library vocabulary defined in [Forth], and then optional vocabularies that define a simple text editor, assembler and disk OperatingSystem. (A modern [Forth] system might have a [TCP/IP] stack on there somewhere too.) Some [Forth]s permit multiple vocabularies to exist concurrently and independently, thus providing namespaces.
27 SamuelFalvo 22
29 AristotlePagaltzis 23 The word <tt>:</tt> tells [Forth] to begin compiling the subsequent words found on the input buffer, and the word <tt>;</tt> then tells it to stop. You use <tt>:</tt> to add new words to the [Forth] system until you've created a high-level [Forth] vocabulary that you can easily express your problem in. You just keep going until you've defined a single word that, when called, executes your entire program. [Forth] is very much a BottomUp language. :-)
24 AristotlePagaltzis 24
29 AristotlePagaltzis 25 Most words compile to <tt>call</tt> statements. Words that look like integers compile to <tt>push</tt> statements. Some words, however, have flags that tell [Forth] to execute them immediately while compiling: these create control structures in the ByteCode of a word, affect parsing, or perform other compiler or macro functions.
24 AristotlePagaltzis 26
29 AristotlePagaltzis 27 There is no syntax in [Forth], just words that manipulate other words and the input buffer and user dictionary.
25 AristotlePagaltzis 28
29 AristotlePagaltzis 29 !!! Examples
24 AristotlePagaltzis 30
29 AristotlePagaltzis 31 ''Sentences long extremely and notation Polish reverse in writing about wrong is what?''
32 <br>— Jarkko Hietaniemi
24 AristotlePagaltzis 33
29 AristotlePagaltzis 34 The following code is a simple text editor from [Retro Native Forth | http://retro.tunes.org]:
24 AristotlePagaltzis 35
29 AristotlePagaltzis 36 <verbatim>
37 0 variable lastBlock
38 asmbase $1024 + constant blockBase
24 AristotlePagaltzis 39
29 AristotlePagaltzis 40 : block 512 * blockBase + ;
41 : select dup lastBlock ! ;
42 : vl dup 40 type cr 40 + ;
43 : view lastBlock @ block vl vl vl vl vl vl vl vl vl vl vl vl ;
44 : edit select block s drop drop view ;
45 : delete select block 512 0 fill view ;
46 : edit-line 40 * lastBlock @ block + s drop drop view ;
47 : delete-line 40 * lastBlock @ block + 37 0 fill view ;
48 </verbatim>
24 AristotlePagaltzis 49
29 AristotlePagaltzis 50 This demonstrates the preferred programming style in [Forth]: short words laid out mostly horizontally, just like words in a college dictionary.
24 AristotlePagaltzis 51
29 AristotlePagaltzis 52 The next example is a utility word from the IRC bot in [ISForth | http://isforth.clss.net/].
24 AristotlePagaltzis 53
54 <verbatim>
55 \ receive up to 512 bytes from bot socket
56
57 : bot-read
58 off> #inbuff
59 inbuff \ where to receive into
60 begin
61 1 over bot-fd recv \ read one char from bot socket
62 1- \ result should be 0 now
63 if \ if its not then we didnt get any input
64 drop exit \ so discard buffer address and exit
65 then
66 incr> #inbuff \ we got a character
67 dup c@ \ get the character we just read
68 $0a <> \ while its not an eol
69 #inbuff 512 <> and
70 while
71 1+ \ advance buffer address
72 repeat
73 drop \ discard buffer address
74 ;
75 </verbatim>
76
29 AristotlePagaltzis 77 This is a single long word, written with a predominantly vertical layout. Such code is hard to read (eg. the while loop's condition check consists of the overwhelming bulk of the code), and is considered poor style.
27 SamuelFalvo 78
29 AristotlePagaltzis 79 For an almost poetic example of [Forth], see LifeInForth.
24 AristotlePagaltzis 80
29 AristotlePagaltzis 81 !!! Optimisations
27 SamuelFalvo 82
29 AristotlePagaltzis 83 Contemporary [Forth] systems are much more complex than naïve interpreters in order to avoid spending a lot of time executing call statements and to reduce the overhead of interpretation.
24 AristotlePagaltzis 84
29 AristotlePagaltzis 85 Instead of compiling words to <tt>call</tt> statements, they might be inlined, even as MachineCode instructions embedded in the ByteCode so the target [CPU] can execute them directly. One form of this is called ''subroutine threading''. Since many target architectures are register-based, numeric literals might be embedded as immediate operands in MachineCode instructions.
27 SamuelFalvo 86
29 AristotlePagaltzis 87 Optimising compilers will wait before putting anything in the dictionary until they encounter the <tt>;</tt> word, rather than building the definition piece-meal in the dictionary. They can then perform proper lexical analysis and parsing to help generate efficient code. Some highly optimizing compilers will even infer types based on the words called in a word!
27 SamuelFalvo 88
29 AristotlePagaltzis 89 !!! Comparison with [Haskell]
27 SamuelFalvo 90
29 AristotlePagaltzis 91 There are many similarities between [Forth] and functional programming languages. For example, this is the definition of <tt>block</tt> from the first example:
27 SamuelFalvo 92
29 AristotlePagaltzis 93 <verbatim>
94 : block 512 * blockBase + ;
95 </verbatim>
27 SamuelFalvo 96
29 AristotlePagaltzis 97 This can be likened to the more traditional functional style:
27 SamuelFalvo 98
29 AristotlePagaltzis 99 <verbatim>
100 let block b = blockBase + ( 512 * b )
101 </verbatim>
27 SamuelFalvo 102
29 AristotlePagaltzis 103 The similarities go far deeper though, and there are many deep dualities.
27 SamuelFalvo 104
29 AristotlePagaltzis 105 * [Haskell] compiles software to a tree of closures – bundles of code and data that together form a function in the mathematical sense. In [Forth], because parameters are placed on the stack, there is no need to store free or bound variables in the program structure. Hence, a poiner to a closure consists ''only'' of its code pointer; therefore, typical "threaded" [Forth] code maps 1:1 to [Haskell]'s closure-based code.
27 SamuelFalvo 106
29 AristotlePagaltzis 107 The fact that [bigFORTH | http://bigforth.sf.net/] and the [Glasgow Haskell Compiler | http://www.haskell.org] produce binaries that are about equally performant is no coincidence.
108
109 * [Forth] has issues using local variables, but can maintain global state with ease. [Haskell] has issues using global state, but can maintain local variables with ease. To address these issues, [ANSI] [Forth] introduced a portable locals wordset, while [Haskell] uses monads to deal with global state. Both constructs are fully expressable in the core language, and both address (essentially) different sides of the same problem.
30 AristotlePagaltzis 110
111 ''''
29 AristotlePagaltzis 112
113 * [Forth] allows the compiler to be extended by fundamentally altering the compiler in terms of words written in the base language itself. [Haskell] utilizes monads for this same purpose.
30 AristotlePagaltzis 114
115 ''''
29 AristotlePagaltzis 116
117 * [Haskell] uses the <tt>>>=</tt> operator to compose the right-hand monadic function onto the results returned by the left-hand computation. Save for the threading of state this is ''normal function composition.'' In [Forth], which is described mathematically as a purely combinator-based language, composition is performed by concatenation – e.g., simply listing one word after another. Hence, both [Forth] and [Haskell] code can be expressed via function composition, and therefore, reasoned about algebraically.
30 AristotlePagaltzis 118
119 ''''
29 AristotlePagaltzis 120
121 * [Forth] allows one to freely alter the return stack. Return stack items are (usually) return addresses ie. (partial) continuations. Freely altering the return stack is dangerous and can produce unstable software. However, there are nonetheless distinct patterns of return stack manipulations you can use to produce ''extremely'' compact representations of fairly high-level control flow structures. This introduces the concept of "return conventions," as distinct from "calling conventions." It turns out that [Haskell] uses return conventions as well, under the hood, to optimize pattern matching in case and function evaluation.
122
123 !!! See Also
124
125 [DragonForth | http://dragonforth.sf.net]:
126 [Free] [Forth] compiler for PalmPilot
127 [Quartus | http://www.quartus.net/products/forth/]:
128 A [Forth] compiler for the PalmPilot
129 [GForth | http://www.jwdt.com/~paysan/gforth.html]:
130 [GNU]'s Forth.
131 It's unusual for a [Forth] in that it comes with a manual.
132 [Forth] programmers aren't big on manuals <tt>:-(</tt>
133 [PFE | http://pfe.sourceforge.net]:
134 It has a VirtualMachine and kernel (see below) written in [C].
135 It might be a good one to study.
136 [RetroForth | http://retro.tunes.org]:
137 Both a ForthOS and a [Forth] for [Linux] systems.
138 [bigFORTH | http://bigforth.sf.net/]:
139 A native code compiler for [x86] which includes a [GUI] library and form editor.
34 JohnBillings 140 [StartingForth | http://home.iae.nl/users/mhx/sf.html]:
141 A good book for starting with forth. by Leo Brodie.
142 [ForthFortNight | http://forthfortnight.blogspot.com/]:
143 Ching's World. (WLUG member who blogs about forth)
26 LawrenceDoliveiro 144
29 AristotlePagaltzis 145 Finally, some [Forth humour at UserFriendly | http://ars.userfriendly.org/cartoons/?id=20070213&mode=classic].
24 AristotlePagaltzis 146
147 -----
148 CategoryProgrammingLanguages, CategoryMachineOrientedProgrammingLanguages, CategorySystemsProgrammingLanguages

PHP Warning

lib/blame.php:177: Warning: Invalid argument supplied for foreach()