2021-01-20
I have been learning Forth this year!
As a child, I came across Forth in some books, but never had the chance to actually try programming in it. The language lodged itself in the back of my head, and 25 years later I came across it again. The first article that caught my attention was
by Elliot Williams on Hackaday. The article spurred a lot of conversation: 232 comments on his original post, not to mention plenty of reposts of the article. With that, my interest was whetted. The second article that that stood out to me was
"Forth: A Weird Programming Language: Here's Why You Might Love It Anyway" by Frank Moraes which extolls its features and links to different implementations and books. And with that, I wanted to really check out and learn the language.I read some of the books linked, but found entry to the language difficult. I saw occasional mentions of Forth pop up on the Merveilles.town mastodon instance. All of this, plus the idea that Forth has changed very little, that it's a unique minimalist language, that it's a poetic terse haiku-like language, and that it encourages one to shape the language into your own little personal language - all that excited me.
To say Forth is unique is an understatement. It's a paradigm so different from the C-influenced languages I know and use like Java, Javascript, C, C#, even Lua. Working with a stack language is a new way to think. Rather than storing values in variables (which is still possible in a way), one passes the output of a value to a stack. You can do that again. And again. And these values stack up, like a set of stacked index cards. When you need the output, you remove it from the stack, in reverse order from how it was added. I think this is called Last In, First Out? One other unique element is the language essentially runs in a kind of REPL (Read-Eval-Print-Loop) meaning that you write and run your code one line at a time, make some modifications or additions, run it again, and repeat in a loop, building up toward your final output. The whole operating system is made up of this REPL system. You can define what are called words, which are similar to the concept of a function in another language. These words can be remade, combined, and so your program gets built up slowly, built out of these words. Additionally, words are added permanently to Forth, so each person's Forth is essentially a custom build. This is doubly true because while the concept of Forth is computationally simple, there are dozens or hundreds of different variations.
There are many old Forth books one can read to learn the language. I did a search in the App store on my 7 year old iPad mini and found the Jupiter Ace app, an emulation of a circa 1982 home computer that was sold in England. Where most other home computers at that time simply shipped with BASIC, I believe the Jupiter Ace was the only one to ship with Forth instead. Consequently, it was a lot faster, though due to the perception of Forth as more difficult than BASIC, it sold poorly.
The Jupiter Ace emulation app is free. The original Jupiter Ace came with a 186-page manual. The manual assumes the purchaser had no previous experience with a computer (a good assumption in 1982), and proceeds to explain how to type in commands, how to take one's first steps in Forth, proceeding to explain bit by bit to the end of the book how to work with memory, sound, graphics and more. The book is really well written and I recommend it. I particularly found its tone and pace more to my own liking than other dryer Forth texts that proclaim its virtues but not its spirit.
The other Forth intro I'm reading is
by Nick Morgan. It includes an in-line mini code editor so you can try out code as you follow along. It breaks down learning Forth into clear categories that I found helpful to navigate.
Below are my notes as I'm learning some basics in Forth. I am using my own descriptions and language, not the *proper* computer science description. For example, a professional might balk at my description of a *word* as analogous to a function. Since each Forth implementation may be different, here I am describing gForth, which is pretty easy to install on any system, so if you are learning a different Forth you may have to look up your own language reference.
Items, like numbers, go onto the stack, you operate on them, and they come off in reverse order. Even basic mathematics!
Example: 2 + 2 in Forth is written 2 2 +
This is known as Postfix as well as Reverse Polish Notation. Incidentally, I looked into whether the *polish* in the title was a pejorative term making fun of Polish people. It's not! It's named in tribute to Polish logician Jan Ćukasiewicz who invented polish notation in 1924.
You can add items to the stack.
2 10 14 3
To print the top item as output and pop it off the stack, you type
.
Example:
2 10 14 3 . . .
Produces the following numbers and removes them from the stack: 3 14 10 ok
Now the only number left on the stack would be 2.
When you hit enter, you'll notice ok at the end of a line that runs properly. If your line has an error, you'll get a ? instead and can arrow over to fix your mistake.
Words are the function or code-blocks of Forth. When you define a new word, it becomes a global function you can reuse. Forth programs are built up of many words.
: wordname command1 [command2] [etc] [etc] ;
Note the space between your last word and the semicolon
#### Working with the Stackdup - make a duplicate of the item on top of the stack
drop - remove current top item of stack
swap - swap top two items of the stack
over - take item that's second from top, duplicate it so a copy is now on top of stack
rot - take element that is third from top and move it to the top (no duplicate this time)
.``` * remove item from stack and display out on standard output.
emit
cr
." [a string]"
variable variablename 100 variablename ! variablename @
The first line initializes a variable memory location named variablename.
Line 2 stores the value 100 at that variablename location.
Line 3 retrievs the value at variablename and prints it to output and places it on the stack.
variablename ? is a word defined as
@ .. It prints out the variable.
addsvariablename +!
Constants never change.
constant constantname
example:
eyeballs constant 2
There is no official boolean. 0 is treated as false. All other numbers are considered true, though -1 is the standard.
3 3 = .
Will produce output: -1, which tells us that this is true that 3 is equal to 3
`<` and `>` and `and` , `or` , `invert`invert is the same as ! or not in other languages.
#### Conditionals **May only be used inside definitions**simple If:
: is-zero? 0 = if ." yes" then ;*make sure you leave a space before final semicolon*
If else:
: is-negative? 0 < if ." yes" else ." no" then ;
And to use it:
-2 is-negative?
produces yes ok
Forth's do-loop is equivalent to a standard for-loop in C-based languages. Is exclusive of top value.
: loop-test 10 0 do i . loop ; loop-test
produces: 0 1 2 3 4 5 6 7 8 9 ok
No arrays. Instead, you can reserve a number of spaces in memory.
key
It's common to use this with a do-until loop.
The Jupiter Ace manual can be downloaded or purchased on many sites. Here is the current site to download pdf manuals on Forth.
If you're looking for a fast getting started and you have previous coding experience, this 30 page Introduction to pbForth, available on Internet Archive's Wayback Machine is a quick intro to Forth, with explanations of how the stack works, variables, words, and more, in a reference-style form. It was written for an intro to using Forth on the Lego Mindstorms power block, in a previous version.
pbForth manual on Internet Archive's Wayback machine
Forth.org maintains an extensive simple to navigate list of Forth Tutorials
(love the 1990s web style).