Bootstrapping a Forth in 40 lines of Lua code
angg.twu.net
angg.twu.net
But I think the win here - these days - for Forth is in things like "running on small embedded devices".. I'm looking with interest at some of the activity around say Arduinos and am thinking that Forth is a rather nice fit for that sort of system. Have bought a kit, and am looking forwards to some non-work quality time to play further :)
(The Books I meantion can be found online very easily, but you'll forgive them for being written back in a time when systems were _simpler_ to grok ;) )
In principle that's not a bad idea, it's just that you're at least 40 years late to the party. FORTH was and propably is used in embedded systems for most of it's existence. Often simply with a minimal text console over UART, that being your "way in". Once you've got that going you can start builing up your system from the inside.
Reading line after line from a file was also difficult. I could not figure out, how to clear the storage used for the previous line properly. When I read a shorter line after a longer line, the storage would still contain the longer part of the longer line after the content of the shorter line. Perhaps there is a Forth that makes this easy?
But it also needs to support that library, FFL, so that I have useful data types, and don't need to roll my own arrays or something ...
Maybe my design philosophy is fundamentally different from what is needed for Forth?
Forth's selling points are mostly how compact a minimal environment can be, and how easy it is to extend that environment to do more useful things. The 'shell' is the compiler.
Forth is an obvious one. Basic another. There's some tiny Lisps out there. And Tcl.
Any other languages that go that small?
For example miniKanren is tiny and is used as a DSL, but is capable of expressing any computation so does that count? Some type systems are turing complete and a naive implementation could be tiny. Is conway's game of life a programming language. You could probably strip a bunch of useful stuff out of sqlite's sql parser and get it below 10k. etc.
Mine is the size of the runtime, usually. So the Forth is the size of Lua + the 40 line script, minKanren is the size of the .scm file + the Scheme implementation, and so on. This ignores the host environment, which I think is fair: generally these will be enormously larger than they would actually have to be to support the language.
I do award subjective bonus points to languages which actually have a freestanding runtime, that is, I could actually compile them and run them on a bare chip. Even then, I don't count the microcode which implements the instruction set of that chip, or the Verilog/VHDL which is needed to tape it out.
Usually! ColorForth on GreenArrays gets even more bonus points, because not only is the language exceedingly compact, and freestanding, but the VLSI tool used to create the chip is also tiny to an almost unbelievable degree. So it wins some kind of prize in the special "total system complexity" category.
That's what I was getting at with "trivial IO": when you ignore what's needed to get data in/out, and optional parts of a standard library (if included), how big is the remainder, the implementation of the language constructs?
(Potentially) standalone, self-hosting & small is indeed the bonus points I'm looking for. A tiny Basic or Forth running bare metal on a uC could be it. A 'tiny' language implemented using a multi-MB VM is not.
Yes, you read that correctly. Lua is truly amazing in terms of the amount of power you get for how little there really is. One of the reasons it's faster than most other VMs with no JIT functionality is because the entire VM fits in a typical L1 cache. My laptop's L1 is 192KiB, meaning it could fit 122KiB of program state in with the VM without breaking a sweat.
Well I was referring to what one could call a souped-up macro assembler: direct access to a machine's hardware, but with some (but important!) conveniences of higher-level languages.
Eg. many Forth systems provide a read-eval-print loop (REPL), allowing users to re-define Forth words on the fly, poke some memory mapped IO, etc. But still do so in a relatively comfortable manner using Forth words rather than (only) through editing assembly code.
The mapping (the "language", if you will) between Forth words, and assembly code that implements them, is fairly straightforward 1:1. And thus, allows for small implementations. Like, fit comfortably in a 16-bit address space.
Many esoteric languages do not fit this description, since they often discard the convenience factor.
C is on the fence here. It's got many of these aspects, but small-ish? Hmm.. And stripped down to a subset, is it still C?
That sounds pretty cool; do you know of an implementation of SML that fits into 10 KB of memory because it uses tiny Prolog?
After a rapidly scuttled attempt at Fortran, he created instead a language of his own, which he called B. B can be thought of as C without types; more accurately, it is BCPL squeezed into 8K bytes of memory and filtered through Thompson's brain.
https://www.gnu.org/software/gforth/
And the inventor of Forth has a very power efficient multi-computer chip that can be programmed with colorForth or array forth (he claims most power efficient):
https://www.greenarraychips.com/home/products/index.php
https://www.greenarraychips.com/home/documents/greg/cf-intro...
Here is a video about the chip, and some cool Forth demos with it:
PUC Lua also has a very solid coherent C implementation; it's basically a masterclass in making an effective, portable, but also necessarily complex C library.
Forth was never going to be the next Java or Rust, but in its own little niche, it's fantastic. ANS Forth isn't getting any new features anytime soon, but meanwhile forth spawned a whole family of interesting languages like Joy, Factor, and ColorForth. Besides, evolution is overrated: tardigrades are still doing fine :)
The evolution of tardigrades as super fascinating: https://eartharchives.org/articles/tardigrade-genome-reveals...
Ugh, "computers". I'm not even a stickler for terminology, but the whole "144 computers" thing somehow rubs me the wrong way, like it's some Best Buy salesdroid telling me that a quad-core means having four computers in one box.
They honestly do sound quite interesting, and if I could fork myself off a few times to look at fun & interesting things, this GreenArray stuff would be in the list ;)
So it's not like a computer with 144 1-core CPU:s sharing RAM and ports, or a CPU with 144 cores, it's something weirder and more reminiscent of a network of small computers.
And that’s not a bad pitch! Modern silicon certainly doesn’t like to be bent into a (single-layer) FPGA shape—the result is comparatively slow, expensive, and power-hungry—but accomodates specialized functional blocks very well, so a matrix of baby processors with accompanying memory sounds genuinely like a good idea for an FPGA-like application.
Unfortunately, the GA144 is the only game in town here, and at $500 per dev kit they sure aren’t interested in hobbyists. So I’m left to admire it from a distance. (And $20 per chip is not a bad price considering the competition—as I said, FPGAs are expensive—but it still falls into the expensive-chip bucket. Not a lot of places are going to build a design around a unique expensive chip from an obscure source.)
I've never implemented a gaussian blur on bitmaps with a FPGA, maybe it is simpler somehow than this example: https://www.youtube.com/watch?v=iwM0qfQqmdE
```
function eval(s)
load(s)()
end
```https://www.lua.org/manual/5.4/manual.html#pdf-load
A simple example that I tested:
local chunk = "return 2 + 2"
local func = load(chunk)
print(func()) -- Output: 4load is the replacement.
i assume the grandparent meant dostring and not eval?
Anyway, thanks for sharing.
It only counts if you use a magnetic needle and a very steady hand.