Update
This commit is contained in:
parent
e47f0871fe
commit
ac9725b356
38 changed files with 1954 additions and 1872 deletions
20
forth.md
20
forth.md
|
@ -2,15 +2,15 @@
|
|||
|
||||
{ I'm a bit ashamed but I really got into Forth quite recently, it's possible I spread some misinformation here, please let me know if I do, thanks <3 ~drummyfish }
|
||||
|
||||
Forth ("fourth generation" shortened to four characters due to technical limitations) is a very [elegant](beauty.md), extremely [minimal](minimalism.md) [stack](stack.md)-based [programming language](programming_language.md) (and a general computing environment) that uses [postfix](notation.md) (reverse Polish) notation -- it is one of the very best programming languages ever conceived. Forth's vanilla form is super simple, much simpler than [C](c.md), its design is ingenious and a compiler/interpreter can be made with little effort, giving it high [practical freedom](freedom_distance.md) (that is to say Forth can really be in the hands of the people). As of writing this the smallest Forth implementation, [milliforth](milliforth.md), has just **340 bytes** (!!!) of [machine code](machine_code.md), that's just incredible. Forth is used for example in [space](space.md) computers (e.g. [RTX2010](rtx2010.md), a radiation hardened space computer directly executing Forth) and [embedded](embedded.md) systems as a way to write efficient [low level](low_level.md) programs that are, unlike those written in [assembly](assembly.md), [portable](portability.md). Forth was the main influence for [Comun](comun.md), the [LRS](lrs.md) programming language, it is also used by [Collapse OS](collapseos.md) and [Dusk OS](duskos.md) as the main language. In minimalism Forth competes a bit with [Lisp](lisp.md), however Forth is ultimately superior -- not just in efficiency but also in elegance.
|
||||
Forth ("fourth generation" shortened to four characters due to technical limitations) is a very [elegant](beauty.md), extremely [minimalist](minimalism.md) [stack](stack.md)-based [programming language](programming_language.md) (and a general computing environment) that uses [postfix](notation.md) (reverse Polish) notation -- it is one of the very best programming languages ever conceived. Forth's vanilla form is super simple, much simpler than [C](c.md), its design is ingenious and a compiler/interpreter can be made with relatively little effort, giving it high [practical freedom](freedom_distance.md) (that is to say Forth can really be in the hands of the people). As of writing this the smallest Forth implementation, [milliforth](milliforth.md), has just **340 bytes** (!!!) of [machine code](machine_code.md), that's just incredible. Forth finds use for example in [space](space.md) computers (e.g. [RTX2010](rtx2010.md), a radiation hardened space computer directly executing Forth) and [embedded](embedded.md) systems as a way to write efficient [low level](low_level.md) programs that are, unlike those written in [assembly](assembly.md), [portable](portability.md). Forth stood as the main influence for [Comun](comun.md), the [LRS](lrs.md) programming language, it is also used by [Collapse OS](collapseos.md) and [Dusk OS](duskos.md) as the main language. In minimalism Forth competes a bit with [Lisp](lisp.md), however, to Lisp fan's dismay, Forth seems to ultimately come out as superior, especially in performance, but ultimately probably even in its elegance (while Lisp may be more mathematically elegant, Forth appears to be the most elegant fit for real hardware).
|
||||
|
||||
**Forth may be one of best [programming](programming.md) systems yet conceived**, it is a pinnacle of programming genius. While in the world of "normal" programming languages we're used to suffering tradeoffs such as sacrificing performance for flexibility, Forth beats basically all such traditional languages at EVERYTHING at once: [simplicity](minimalism.md), [beauty](beauty.md), memory compactness, flexibility, performance and [portability](portability.md). It is also more than just a programming language, it is a system for computing, a calculator, programming language and its own debugger but can also serve for example as a [text editor](text_editor.md) and even a whole [operating system](os.md) (that is why e.g. DuskOS is written in Forth -- it is not as much written in Forth as it actually IS Forth). Of course you may ask: if it's so great, why isn't it used very much? Once someone summed it up as follow: Forth gives one unprecedented freedom and that allows [retards](soydev.md) to create bad design and fuck things up -- [capitalism](capitalism.md) needs languages for monkeys, that's why [bad languages](rust.md) are widely used. Remember: popularity has never been a measure of quality -- the best art will never be mainstream, it can only be understood and mastered by a few.
|
||||
Not wanting to invoke a fanboy mentality, the truth still has to be left known that **Forth may be one of best [programming](programming.md) systems yet conceived**, it is a pinnacle of programming genius. While in the realm of "normal" programming languages we're used to suffering tradeoffs such as sacrificing performance for flexibility, Forth dodges this seemingly inevitable mathematical curse and manages to beat virtually all such traditional languages at EVERYTHING at once: [simplicity](minimalism.md), [beauty](beauty.md), memory compactness, flexibility, performance and [portability](portability.md). It's also much more than a programming language, it is an overall system for computing, a calculator, programming language and its own debugger but may also serve for example as a [text editor](text_editor.md) and even, without exaggeration, a whole [operating system](os.md) (that is why e.g. DuskOS is written in Forth -- it is not as much written in Forth as it actually IS Forth). Understandably you may ask: if it's so great, why isn't it very much used "in the business"? Once someone summed it up as follow: Forth gives us unprecedented freedom and that allows [retards](soydev.md) to come up with bad design and unleash destruction -- [capitalism](capitalism.md) needs languages for monkeys, that's why [bad languages](rust.md) prosper. Remember: popularity has never been a measure of quality -- the best art will never be mainstream, it can only be understood and mastered by a few.
|
||||
|
||||
Forth is unique in its philosophy, it can really be hardly compared to traditional languages such as [C++](cpp.md) or [Java](java.md) -- while the "typical language" is always basically the same thing for the programmer (no matter the implementation) and provides a few predefined, highly complex, universal, hardcoded constructs that are simply there and cannot be changed (such as an [OOP](oop.md) system, templates, control structures, ...), **Forth adopts [Unix philosophy](unix_philosophy.md)** (maybe in a better way than Unix itself) by defining just the concept of a word and maybe providing a few simple words and letting the programmer extend the language (that is even the compiler/interpreter itself) by defining new words out of the simpler ones, and this includes even things such as control structures (branches, loops, ...), primitive data types, variables and constant. For instance: in traditional languages there are a few predefined formats in which numbers may be written -- let's say in C you may use decimal numbers as `123` or hexadecimal numbers as `0x7b` -- in Forth you may change the base at any time to any value by assigning to the `base` variable which will change how Forth parses and outputs numbers (while a number is considered any word that's not been found in dictionary), and it is even possible to completely rewrite the number parsing procedure itself. Almost everything in Forth can be modified this way, so pure Forth without any words is not much more than a description of a [data structure](data_structure.md) and simpler parser of space-separated words, it plainly dictates a format of how words will be represented and handled on a very basic level (that's on the simplicity level of, let's say, [lambda calculus](lambda_calculus.md)) and only a *Forth system* (i.e. one with a specific dictionary of defined words, such as that defined by ANS Forth standard) provides a basic "practically usable" language. The point is this can still be extended yet further, without any end or limitation.
|
||||
Forth is unique in its philosophy, we might almost go as far as calling Forth a programming [paradigm](paradigm.md) of its own. It can really be hardly compared to traditional languages such as [C++](cpp.md) or [Java](java.md) -- while the "typical language" is always more or less the same thing from the programmer's point of view by providing a few predefined, hardwired, usually complex but universal constructs that are simply there and cannot be changed in any way (such as an [OOP](oop.md) system, template system, macro language, control structures, primitive types, ...), **Forth adopts [Unix philosophy](unix_philosophy.md)** (and dare we say probably better than Unix itself) by defining just the concept of a *word*, maybe providing a handful of simple words for the start, and then letting the programmer extend the language (that is even the compiler/interpreter itself) by creating new words out of the simpler ones, and this includes even things such as control structures (branches, loops, ...), variables and constant. For instance: in traditional languages we find a few predefined formats in which numbers may be written -- let's say C lets us use decimal numbers as `123` or hexadecimal numbers as `0x7b` -- in Forth you may change the base at any time to any value by assigning to the `base` variable which will change how Forth parses and outputs numbers (while a number is considered any word that's not been found in dictionary), and it is even possible to completely rewrite the number parsing procedure itself. Almost everything in Forth can be modified this way, so pure Forth without any words is not much more than a description of a [data structure](data_structure.md) and simpler parser of space-separated words, it plainly dictates a format of how words will be represented and handled on a very basic level (that's on the simplicity level of, let's say, [lambda calculus](lambda_calculus.md)) and only a *Forth system* (i.e. one with a specific dictionary of defined words, such as that defined by ANS Forth standard) provides a basic "practically usable" language. The point is this can still be extended yet further, without any end or limitation.
|
||||
|
||||
{ Since Forth adopts a kind of unique philosophy, there are some discussion about how low level Forth really is, if it really is a language or something like a "metalanguage", or an "environment" to create your own language by defining your own words. Now this is not a place to go very deep on this but kind of a sum up may be this: Forth in its base version is very low level, however it's very extensible and many Forth systems extend the base language to some kind of much higher level language, hence the debates. ~drummyfish }
|
||||
|
||||
The language is usually presented as [interpreted](interpreter.md), however that's a bit misleading (interpreting Forth is almost like native execution), but may perfectly well be [compiled](compiler.md) to pure machine code too; it's actually very easy and natural to turn Forth source code into assembly, however (again, due to Forth's unique nature) it is not so easy to state with confidence whether the language is really interpreted or compiled because interpreting Forth happens on such a low level that it's almost native code execution -- any newly defined word is immediately compiled into a list of addresses of other words (i.e. in C terms function pointers) and the most basic words are typically written directly in [machine code](machine_code.md), so the interpreter doesn't perform any search for word names or anything like that (like a typical scripting language would), it just jumps between memory addresses, pushes numbers on stack and sometimes runs a native piece of code. For this Forth may be seen as a kind of "wrapper for assembly" as well, one that helps it be [portable](portability.md) (to port a program one will just have to replace the machine code of the basic words).
|
||||
Being somewhat of a misfit in terms of classification, the language is probably more often presented as [interpreted](interpreter.md), but that's a tiny bit misleading (interpreting Forth is almost like native execution), however it may perfectly well be [compiled](compiler.md) to pure machine code too; it's actually very easy and natural to turn Forth source code into assembly, however (again, due to Forth's unique nature) it is not so easy to state with confidence whether the language is really interpreted or compiled because interpreting Forth happens on such a low level that it's almost native code execution -- any newly defined word is immediately compiled into a list of addresses of other words (i.e. in C terms function pointers) and the most basic words are typically written directly in [machine code](machine_code.md), so the interpreter doesn't perform any search for word names or anything like that (like a typical scripting language would), it just jumps between memory addresses, pushes numbers on stack and sometimes runs a native piece of code. For this Forth may be seen as a kind of "wrapper for assembly" as well, one that helps it be [portable](portability.md) (to port a program one will just have to replace the machine code of the basic words).
|
||||
|
||||
Forth systems traditionally include not just a compiler/interpreter but also an **interactive environment** in which one is defining and compiling new words on the go. Again -- this is not just some kind of extra killer feature, an interactive environment naturally comes as a byproduct of Forth's design, it costs nothing to have such environment. This environment can serve for example as a debugger or even an operating system.
|
||||
|
||||
|
@ -46,9 +46,11 @@ For example a word that computes and average of the two values on top of the sta
|
|||
: average + 2 / ;
|
||||
```
|
||||
|
||||
Dictionary is a very important concept in Forth, it usually stores the words as a [linked list](list.md), starting with the oldest word -- this allows for example temporary shadowing of previously defined words with the same name.
|
||||
Note that even the `:` and `;` characters that serve to define new words are words themselves.
|
||||
|
||||
Forth programmers use so called **stack notation** to document the function's "signature", i.e. what it does with the stack -- they write this notation in a comment above a defined word to signify to others what the word will do. Stack notation has the format `( before -- after )`, for example the effect of the above defined `average` words would be written as `( a b -- avg )` in this notation.
|
||||
Dictionary constitutes one of the most important concept in Forth, it usually stores the words as a [linked list](list.md), starting with the oldest word -- this allows for example temporary shadowing of previously defined words with the same name.
|
||||
|
||||
Forth programmers utilize what's called a **stack notation** to document the "signature" of a function, i.e. what it does with the stack (this is important since the language doesn't have the traditional system of named, counted and checked function parameters) -- they write this notation in a comment above a defined word to communicate to others what the word will do. Stack notation has the format `( before -- after )`, for example the effect of the above defined `average` words would be written as `( a b -- avg )` in this notation.
|
||||
|
||||
Some predefined words usually present in Forth systems include:
|
||||
|
||||
|
@ -253,7 +255,9 @@ We can run this simply with `gforth my.fs`, the programs should write `120`.
|
|||
|
||||
## A Bit More Details
|
||||
|
||||
Genius of Forth resides under the hood. Here are some very basics about that.
|
||||
WIP
|
||||
|
||||
The genius of Forth resides under the hood -- to see it one has to study the internal working and see how it all ultimately ties together. So let's start here with some very basic overview of the internals.
|
||||
|
||||
There are several regions of memory, most importantly the parameter stack (the main kind of stack), the return stack and dictionary memory. Dictionary obviously stores the words. **Format of the word in memory** may differ between implementations, but typically a word record has the following fields:
|
||||
|
||||
|
@ -266,6 +270,8 @@ There are several regions of memory, most importantly the parameter stack (the m
|
|||
|
||||
Then there is a special pointer called *H* which points to the end of dictionary memory, i.e. at the end of the latest added word; adding a new word will happen here. This pointer is important e.g. for allocation: the word *ALLOT* (that allocated more memory cells for previously created pointer) just advanced the *H* pointer, making more room in the PFA. Quite clever, isn't it?
|
||||
|
||||
Forth system looks up words simply by traversing the linked list, i.e. out of words that share the same name the one created later will be found. If the system is given a word and it doesn't find it in the dictionary, it considers it a number; then it tries to parse the word as a number (using a special number parsing word which, of course, may also be redefined). This is another beautiful thing -- there is no hardwired format of a number, a number is simply anything that's not a word in the dictionary, and if for some reason we want to see say *123* as a special word rather than a number, we CAN.
|
||||
|
||||
TODO: compile time behavior, control structures, ...
|
||||
|
||||
## See Also
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue