In my YouTube C language course in the latest episodes I'm implementing a Toy FORTH interpreter: I believe FORTH is nice even just for the educational value it contains, and also, together with Lisp, it shows another way to perform computations. In the mind of the novel programmer, being exposed to these different ways to express computation has deep effects even if most of the code will be written, in their career, in imperative or OOP languages.
I've always had a soft spot for FORTH. I think the magic of it is how little assembly you need to write before you are writing your FORTH system in FORTH.
So in my opinion this is somewhat antithetical to the idea of FORTH
> 100% C/C++ with multi-platform support. Though classic implementation of primitives in assembly language and scripted high-level words gave the power to Forth, it also became the hurtle for newbies. Because they have to learn the assembly and Forth syntax before peeking into the internal beauty of Forth.
Fair enough to write a core of FORTH in C as a kind of portable assembler but most of the system should be written in FORTH in my opinion, then you can change it from FORTH. As fast as I can see eForth is written entirely in C.
Anyway FORTH is fun, writing your own is fun too and a great educational experience, but despite being a fan, I wouldn't write anything serious in it today. It is much too low level and it has even less memory safety than C!
The elegance of it continues to impress though with functional programming to get the job done and compile time programming to mold the language into that DSL which expresses the problem perfectly.
The article doesn’t mention performance. Because Forth programs basically chain subroutine calls together, it’s a safe bet it is bad on modern hardware with its multitude of caches.
That’s something you could prevent with an advanced compiler that inlines lots of code and carefully tries to put functions often called together in cache lines, but this code doesn’t do that, and if you did, why spend that effort on your compiler if a simple traditional language makes that inlining easier?
Yes, I observe a 30-40x slowdown with that method on my interpreter. I was perfectly aware of the cost, Anton Ertl had shown in the 90ies that it wasn't the best on Pentium already [1].
The trick is that you can regain 100% the speed of C (or machine code) by native-coding the critical parts. It's pretty much the same cheating method as JIT or calling native code with an FFI, just manual.
In this regard, a simple, naive subroutine threaded scheme makes it very trivial to do. Think Lua extensions but even more easy because you don't have dynamic types or GC memory. Seriously, when I look hear that language X is "easy to extend" and I look at it... No, it is not.
I have come to the same conclusions as eForth "independently" (I have looked at many Forth systems before making my own, so there could be some influences), except I wasn't interested in compatibility with the standard, so I ditched the counted strings for C's ASCIIZ strings. This makes interfacing with C/C++ libraries as straightforward as you can get.
I quite don't understand why eForth goes for C++; I do see its value to parse more complex languages but Forth? I also don't see the value of multithreading. Cooperative schemes usually work well enough and are easier to handle. If concurrency is needed, multiple programs with RPC, shared memory or pipelines are options usually available (some options are more portable than others, though).
> So, the question is, how to encourage today's world of C programmers to take a look at Forth.
This is a huge mistake. If you make a Forth for others instead of doing it for your own needs, you are doing it wrong. Doing it for yourself, and not being tied by backwards compatibility because you have published your Forth and you don't want to lose your audience, leads to vastly different answers.
I wrote a FORTH for ARM which inlined short definitions (eg stack manipulation) then did peephole optimization keeping the stack in registers for that word.
The compiled code came out looking quite nice. I'm sure a decent C compiler would have done better, but it wasn't bad at all.
It meant all the stack noise was compiled as register move instructions leaving only calls to chunky words which were too big to inline.
No. Chaining subroutine calls is an implementation detail that is not inherent in the language, even if it may be a popular option because it is easy to do.
The usual implementation options are subroutine threading, indirect threading, and direct threading.
When looking at these kind of subcultures, I think the best policy is "learn from them, but remember that they don't learn from you". They may have a unique better take on some aspects, but they will try to convince you to scorn all other viewpoints, and that's always worse than the gain.
I am using a stack based language as an intermediate language for a C compiler I am writing. The language can be mapped to assembly and I wrote a memory safe interpreter for it. Both are not geared to performance as that is not a primary concern for the compiler and tool chain.
It has always fascinates me how Forth has been historically used for low level embedded programming, but also can be as high level as you’d like. I feel like this isn’t a concept that has really gone away.
Not really. The article was written 10+ years ago, saying that one cannot use Forth in commercial products, yet Forth Inc. and MPE are still in business.
> With all the advantages, it is unfortunate that Forth lost out to C language over the years and have been reduced to a niche. Per ChatGPT: due to C's broader appeal, standardization, and support ecosystem likely contributed to its greater adoption and use in mainstream computing.
Oh, please. I've written in Forth. It's useful when you have to do a cram job to fit in a really tiny machine. Otherwise, no.
In my YouTube C language course in the latest episodes I'm implementing a Toy FORTH interpreter: I believe FORTH is nice even just for the educational value it contains, and also, together with Lisp, it shows another way to perform computations. In the mind of the novel programmer, being exposed to these different ways to express computation has deep effects even if most of the code will be written, in their career, in imperative or OOP languages.
I've always had a soft spot for FORTH. I think the magic of it is how little assembly you need to write before you are writing your FORTH system in FORTH.
So in my opinion this is somewhat antithetical to the idea of FORTH
> 100% C/C++ with multi-platform support. Though classic implementation of primitives in assembly language and scripted high-level words gave the power to Forth, it also became the hurtle for newbies. Because they have to learn the assembly and Forth syntax before peeking into the internal beauty of Forth.
Fair enough to write a core of FORTH in C as a kind of portable assembler but most of the system should be written in FORTH in my opinion, then you can change it from FORTH. As fast as I can see eForth is written entirely in C.
Anyway FORTH is fun, writing your own is fun too and a great educational experience, but despite being a fan, I wouldn't write anything serious in it today. It is much too low level and it has even less memory safety than C!
The elegance of it continues to impress though with functional programming to get the job done and compile time programming to mold the language into that DSL which expresses the problem perfectly.
The article doesn’t mention performance. Because Forth programs basically chain subroutine calls together, it’s a safe bet it is bad on modern hardware with its multitude of caches.
That’s something you could prevent with an advanced compiler that inlines lots of code and carefully tries to put functions often called together in cache lines, but this code doesn’t do that, and if you did, why spend that effort on your compiler if a simple traditional language makes that inlining easier?
Yes, I observe a 30-40x slowdown with that method on my interpreter. I was perfectly aware of the cost, Anton Ertl had shown in the 90ies that it wasn't the best on Pentium already [1].
The trick is that you can regain 100% the speed of C (or machine code) by native-coding the critical parts. It's pretty much the same cheating method as JIT or calling native code with an FFI, just manual.
In this regard, a simple, naive subroutine threaded scheme makes it very trivial to do. Think Lua extensions but even more easy because you don't have dynamic types or GC memory. Seriously, when I look hear that language X is "easy to extend" and I look at it... No, it is not.
I have come to the same conclusions as eForth "independently" (I have looked at many Forth systems before making my own, so there could be some influences), except I wasn't interested in compatibility with the standard, so I ditched the counted strings for C's ASCIIZ strings. This makes interfacing with C/C++ libraries as straightforward as you can get.
I quite don't understand why eForth goes for C++; I do see its value to parse more complex languages but Forth? I also don't see the value of multithreading. Cooperative schemes usually work well enough and are easier to handle. If concurrency is needed, multiple programs with RPC, shared memory or pipelines are options usually available (some options are more portable than others, though).
> So, the question is, how to encourage today's world of C programmers to take a look at Forth.
This is a huge mistake. If you make a Forth for others instead of doing it for your own needs, you are doing it wrong. Doing it for yourself, and not being tied by backwards compatibility because you have published your Forth and you don't want to lose your audience, leads to vastly different answers.
[1] http://www.complang.tuwien.ac.at/projects/forth.html
I wrote a FORTH for ARM which inlined short definitions (eg stack manipulation) then did peephole optimization keeping the stack in registers for that word.
The compiled code came out looking quite nice. I'm sure a decent C compiler would have done better, but it wasn't bad at all.
It meant all the stack noise was compiled as register move instructions leaving only calls to chunky words which were too big to inline.
No. Chaining subroutine calls is an implementation detail that is not inherent in the language, even if it may be a popular option because it is easy to do.
The usual implementation options are subroutine threading, indirect threading, and direct threading.
I just wrote assembler for my custom virtual cpu. Now i plan to write Forth interpreter or compiler...
IMO Forth is easiest language to implement from scratch, especially on stack based CPUs :)
When looking at these kind of subcultures, I think the best policy is "learn from them, but remember that they don't learn from you". They may have a unique better take on some aspects, but they will try to convince you to scorn all other viewpoints, and that's always worse than the gain.
>but they will try to convince you to scorn all other viewpoints
How is that not what you are doing? Lay it all out and back up what you are claiming, some of us are willing to hear you out.
May I suggest this wonderful playground to everyone interested in both Forth and pixel shaders: https://forthsalon.appspot.com
I am using a stack based language as an intermediate language for a C compiler I am writing. The language can be mapped to assembly and I wrote a memory safe interpreter for it. Both are not geared to performance as that is not a primary concern for the compiler and tool chain.
I still feel like I need to learn Forth.
It has always fascinates me how Forth has been historically used for low level embedded programming, but also can be as high level as you’d like. I feel like this isn’t a concept that has really gone away.
Curious, I just got an LLM to write a small web server in Forth.
Phew - that is a terse language. I have heard it compared to assembly language and yeah I see that.
yosefk had the ultimate take on this: https://yosefk.com/blog/my-history-with-forth-stack-machines...
Not really. The article was written 10+ years ago, saying that one cannot use Forth in commercial products, yet Forth Inc. and MPE are still in business.
> With all the advantages, it is unfortunate that Forth lost out to C language over the years and have been reduced to a niche. Per ChatGPT: due to C's broader appeal, standardization, and support ecosystem likely contributed to its greater adoption and use in mainstream computing.
Oh, please. I've written in Forth. It's useful when you have to do a cram job to fit in a really tiny machine. Otherwise, no.
I don't know about now but it soon may be :)
An interesting project chose it as its lang: https://collapseos.org/