I was always fond of the Jupiter Ace [1] which was a Sinclair ZX-81 clone made in the UK in the early 80s. It had FORTH in ROM as the system language and operating system/interface, rather than BASIC.
> ACE's Forth was based mostly on Forth-79, with some relevant differences. Runtime error checking could be turned off to further raise speed by 25% to 50%. [...] The ACE's dialect of FORTH introduced several innovations. [I]t added syntax checking to control structures and definer constructions [...] as well as decompiling capabilities.
I think they only sold about three of them; I certainly never saw one in the shops. It was overtaken by machines like the BBC B, Commodore 64 and ZX Spectrum 48k, which were better specced (more than 1Kib RAM, colour output etc.) and had more software. Even the ZX-81, which I owned at one point and programmed in its idiosyncratic BASIC (including features like using the screen buffer as a few extra bytes of scratch memory!) was more popular. But, a nice idea, and I keep scanning eBay to try and find one to buy second-hand, just to see what they were like...
I wonder how to IT world would have turned out if we who played with the home computers in 80's as kids would have been exposed to Forth or Lisp instead of Basic.
That right there is an excellent question. I was one of those whose first language was Basic, and I really wonder of Dijkstra was right: was I permanently damaged by learning it?
For comparison, the QNX Neutrino operating system fits (no, used to fit: I last played with it ~15 years ago) on a 1.44mb floppy disk, which is a bit bigger, but also contained a decent browser for the time as well as a media player and other goodies.
They released some of it under a look-but-don't-touch license for a while, in an attempt to build a community, and you could get a free license for the desktop version of QNX (with all the developer tools in it). I think I still have a CD somewhere. It worked pretty well.
It may even be still available, but after digging up my old Foundry27 username and password (which, surprisingly, still works), their download site is an impossible trainwreck and I was unable to find it any more.
OpenFirmware was also the firmware (~BIOS) for the One Laptop Per Child XO. The software was open sourced for OLPC and is online here: https://www.openfirmware.info/Open_Firmware. This is the same code that was developed at Sun and evolved for Mitch Bradley's projects ever since. (I _think_ that Apple wrote their own interface-compatible implementation mostly in C.)
Yes, and before that there was polyForth. I had a summer job working on it in 1986 -- there were three variants for the PC, to either run under DOS or boot to it directly and use or skip the BIOS. Had preemptive threading with no memory protection, but on the 8086 what can you do? Sometimes we'd run it multi-user, such as for a class, and then any student could crash it, and we'd just reboot. This happened, of course, but surprisingly (looking back) not enough to make a big nuisance.
The programming environment on a system like this feels kinda like a cut-down Smalltalk or Lisp, in the sense of a live environment with all the code accessible and tweakable.
Yup! That was actually what I used at home back then-- you too? But Wycove Forth was relatively amateurish and iirc called on built-in ROM routines for OS operations like reading a disk.
I remember at uni we used to use the forth boot prompt to hack root on the Sun workstations at uni; you could type it all out on one line. You had to search for the symbol table and then jump through some hoops to find the kernel task list, find the pid of your shell process, edit the user struct and set the effective uid to zero.
We moved our production server cluster (approximately 50 machines) over to 4os recently and the results have been great. Customers love it, the product is faster, easier to maintain, and new developers onboard quickly. We were able to get our existing team of 200 developers up to speed on Forth in about 30 days, and everything we do now is written in Forth for an OS built in Forth. For us it was a no brainer.
Aren't the horrors of legacy and the lines of tech hipsterism often blurry though? I was born late, I often look at things older than me for an understanding where stuff came from. But then I have to help out my boss' friend debugging this 15yo Microbus-centered DOS-Application running on a SuSE machine from just after the invention of fire, and I don't regret growing up on BASIC as much.
Built using the Forth EDA tools with booleanForth and realForth for modeling the mixed-signal circuits. All on a Forth CPU hand-assembled from a stack of transistors.
lol, can someone write a generator that generates this kind of non sense ? This is the kind of bullshit statement that gets often upvoted on HN and I love it !
I truly believe every programmer needs to learn and use Forth for a while. Same with assembler. And bring up a machine using both not aided by anything else. In other words, if you need a text editor to edit Forth screens you need to write it yourself, in Forth.
This does not mean I think Forth has a future in or is suitable for larger scale work these days. I do think it, and assembler, and the process of accomplishing the above can provide a massive learning experience that will only enhance what work a programmer might do in the future with modern languages and platforms.
So I've done what you suggest, both of them. The assembler was useful, got close to the metal. The forth, for me, was a waste of time. I remember writing something like less(1) in forth just so I could scroll forwards/backwards through code, search, you know, basic stuff.
I don't feel like learning forth did much for me. Learning assembler, hell yes, reused that knowledge over and over (I rewrote assembly versions of Unix stuff like ls, cp, rm, etc in Z80 for a CPM machine I had at University).
It's been a while so I might not recall all the details. This is what I did on a 6502 in the 80's (the order might not be exactly right):
- Write drivers (in assembler) for external UARTs and parallel port chips
- Write (in assembler) enough code to get the very basics of Forth going
- Now in Forth, write the standard set of Forth words
- Write a rudimentary text editor
- Write a floppy disk driver and file system management code
- Now I have a Forth computer
At that point I started to use Forth for robotics. Quadrature encoder inputs. A/D, D/A and digital I/O. Eventually doing real-time PID loop. Control a single motor. Build a robot arm. Control five or six motors. Build an external LED hexadecimal display. Talk to it in Forth. Build a buttons and knobs control panel for the robot. Talk to it in Forth. Have loads of fun and learn a ton.
In other words, I had a very specific project in mind and saw it through from a bunch of chips on the workbench to a finished robot arm with user interface.
There are a million lessons to be learned in such a project.
I've actually thought about dusting off my old files and designs and putting together some kind of an educational kit to launch on Kickstarter. It could be a lot of fun.
I was a big fan of Postscript and Forth. I loved Forth for the way it made you think about dividing up a program. It felt so natural to build a dictionary of words in pursuit of defining a higher level solution. I don't get the people who think its a write-only language. I came upon one of my old programs a decade after I first wrote it. Its was really easy to understand even now. Stack notation for comments with a bit of explanation are some fine documentation.
Postscript was a better Forth IMHO. I loved creating Postscript files for reports. My Turbo C, foxbase, and a Postscript printer were my main tools at my first job.
Question: I've looked at Forth a number of times and I think it's a fascinating looking language but I've never bothered picking it up. I've also never had a chance to talk to a Forth programmer. Can you tell me what type of application you're working on, if it's legacy or new development, and your thoughts on when to choose Forth over something else?
From what I understand, Forth is mostly used as an embedded "OS" when a traditional OS wouldn't cut it. Is that accurate?
Sorry, it's just not a terribly common language, but it certainly is interesting.
I cut my teeth using Forth for writing automated tests for storage products (pretty legacy, I'm not sure if the company uses it any more), and got hooked on it afterwards. The test system was based on a custom real time OS, and Forth was a really good fit, but it would be really hard to find developers now that understood how to work with the system. I had also bought Threaded Interperative Languages (https://www.amazon.com/Threaded-Interpretive-Languages-Desig...) and chose to roll a Forth interpreter for an 8051 dev board I had laying around, which was pretty fun, and wasn't too difficult. It's mostly just a hobby now, as I don't think there's a lot of companies out there still using Forth.
I think Forth is still useful for embedded systems, often even more so than C, especially given that it can go places that C can't. I would personally choose it for my own embedded projects, but the paradigm is sufficiently different that I would worry about finding other people who have the mental capability to write Forth that doesn't immediately devolve into something unmaintainable, or who even want to learn it in the first place. I still write little scripts with GForth sometimes too, but it's not nearly as productive as just writing some Perl or Python. If you're interested in playing with a slightly more modern concatenative language, Factor is a good choice.
I tried to learn it, and found Forth to be an obfuscated, write-only language.
Forth programmers give a lot of lip service to writing short, well documented, elegant words (functions) but in real-world programs I've seen the opposite: the tendency has been to long, poorly documented, and convoluted words. (At least that's been my experience with open-source Forth programs. I've heard the libraries for commercial Forths are of much higher quality, but I have not verified this myself)
Forth has been compared favorably to Lisp, but I found them to be like night and day, and Lisp (and especially Scheme) to be far more elegant and easy to both read and write.
Forth might arguably be better than assembly, but unless you have a pressing need to write the tiniest programs possible (like on some resource-starved microcontroller), I'd be hard pressed to find a reason why you'd want to use Forth instead of some higher level language that is far less painful to work with.
In fact, I've even heard some Forth fans themselves say that the point of using Forth is to write yourself something as quickly as possible that lets you program in a higher level language.
Don't get me wrong, I really, really wanted to like Forth and spent a lot of time trying to learn it, but in the end it felt like it just wasn't worth it. I might give it another go if I get heavily in to programming microcontrollers where Lisp or Scheme is not an option.
In some contexts, that's true. Lisp needs insane amounts of RAM to get a decent REPL running (I can't find figures for the original 704 implementation (did it even have a REPL or was it compiled?), but I guess easily 20kB or more), while forth runs its REPL happily in a tenth of that space.
If you are bootstrapping the firmware for a device, where bootstrapping means that you have to write the code interfacing with any of the hardware before you can use it, and you can find enough I/O pins to use for a serial port, a forth REPL is both easier to implement and way more useful than a lisp one. And if your device doesn't have much memory, it may be your only realistic option.
> In fact, I've even heard some Forth fans themselves say that the point of using Forth is to write yourself something as quickly as possible that lets you program in a higher level language.
That was the main point for someone I know: Forth was how they'd bootstrap a new system to be useful in a few days.
I don't think they do this anymore. This mattered more in say the 1980s when truly new personal computer hardware was coming on the market fairly frequently.
I use it for scripting and as an embedded debugging language for other programs.
For instance I wrote a logging program that collects log messages sent by various sources via UDP, displays them in colours on the console and records them in different log files. It is also a HTTP 1.1 server that I use to monitor a few key data about the logs from a browser on an other machine.
The right way to use Forth nowadays is, in my humble opinion, as a template to build yourself your own interpreter that does exactly what you want (as long as you know how to do it ;-), because it has a very low barrier-of-entry implementation-wise.
The "Forth is good for embedded stuff" pitch becomes less and less true every year, because embedded micro-controllers become more and more powerful. Other small languages like Lua are becoming "good enough" on these and are more "user-friendly".
Extrapolating from myself I would say that those who stick with Forth are just liking it and/or like to have absolute control over their tools.
You may have mostly implemented one of the things on my list of "ridiculous things I would like to see": a forth-based web server that accepts code URLs. For example
GET foo.com/2/3/+/.
would return a text file containing the number '5', and
GET foo.com/:/square/dup/*/;
would define a new function (technically, that should be a PUT, but who cares, for a ridiculous idea?)
Of course, this should follow the forth philosophy, so URLs like
GET foo.com/forget/forget
would work 'fine'. Connecting such a contraption to the internet might not be the brightest idea, but I think it can be made (more or less) safe by executing every request from within a highly restricted vocabulary. I would guess that's how you implemented your http request handling, but likely only for one-word URLs.
If so, the rest is just a REPL that uses slashes as word separators, so it is easy to write.
Forth also makes a good scripting language for many applications due to being compact and very easy to implement. Warren Wilkinson used Forth for scripting in his Common Lisp-based web forms/reports/documentation app: http://lambda-the-ultimate.org/node/3999
A while back I wrote a Forth interpreter and ended up posting a bit of a rant here about what I'd learnt from the experience, which I won't repeat; but after some more thought, I think Forth is best described as a kind of interactive super assembly language.
Writing Forth requires the same level of attention to detail and obsession with minutiae that assembly does. There's no runtime safety whatsoever. There's no syntactical safety whatsoever. It will do exactly what you tell it, even if what you tell it makes no sense. (I found myself thinking of the interpreter as the worst kind of passive-agressive cow orker. "I just assumed you had a reason for writing that floating point number to the program counter! I'm not a mind reader, you know!" "But if you wanted that loop closed at the end of the word definition, why didn't you close it yourself?" "It's not my job to remember whether that word left a float or an int on the stack. Don't you know?")
But this also gets coupled to the Forth programmer mindset, which is the ultimate YAGNI. Forth programmers don't just avoid abstraction, they consider it evil. I found a good example from Chuck Moore's website, where he compares the Linux IDE driver (thousands of lines of code) with an equivalent Forth one (two lines).
...except, of course, the Linux driver is a command scheduler to the VFS block layer. The Forth driver's just a couple of words which read and write bytes from an IDE channel. They are in no way equivalent, except that in Chuck Moore's eyes they are. The same philosphy permeates the entire language. Good Forth programmers appear to solve hard problems by ruthlessly stripping away everything irrelevant from the problem to end up with an easy one.
So, a traditional Forth system has no file system; it's easier to just remember which disk blocks you put your data in. Code portability's unimportant --- each program runs in its own customised Forth environment; avoiding platform-specific features is a waste of time. (Most Forthers I've talked to hold the ANS Forth spec in active contempt.) There's very little reusable code because each Forth solution is so tightly tied to the problem it's solving to be useless for any other problem.
Where it really excels is in an environment where you don't want any abstractions between you and the hardware --- it's brilliant on tiny, embedded devices. I don't know any other environment which can do so much in so little; being able to connect a serial terminal to a embedded processor with 2kB RAM and run commands on it is so, so useful.
I'd strongly recommend learning at least the basics of it, even if you're never going to use it. There's that wonderful Aha! moment as your mind reconfigures itself.
Been dead for sometime. There is a lot of references to 4os on Google Groups where people were discussing if the company would open source the OS before they went under.
Judging by the fact there aren't many other references to 4os I don't believe they did.
> ACE's Forth was based mostly on Forth-79, with some relevant differences. Runtime error checking could be turned off to further raise speed by 25% to 50%. [...] The ACE's dialect of FORTH introduced several innovations. [I]t added syntax checking to control structures and definer constructions [...] as well as decompiling capabilities.
I think they only sold about three of them; I certainly never saw one in the shops. It was overtaken by machines like the BBC B, Commodore 64 and ZX Spectrum 48k, which were better specced (more than 1Kib RAM, colour output etc.) and had more software. Even the ZX-81, which I owned at one point and programmed in its idiosyncratic BASIC (including features like using the screen buffer as a few extra bytes of scratch memory!) was more popular. But, a nice idea, and I keep scanning eBay to try and find one to buy second-hand, just to see what they were like...
[1] https://en.wikipedia.org/wiki/Jupiter_Ace