Live data from Hacker News

Easy Forth (2015)

skilldrick.github.io

41–50 of 128 posts

Re: Easy Forth (2015)

#41
post #19

Earlier quoted context omitted.

As I like to say: "C is a language that solves a million problems. Forth is a million languages that solve almost nothing." :-P I've been reading about Forth for 30-40 years. The dual stack is easy to understand. My problem is that I cannot see how control flow works in Forth, e.g. a simple if-then-else. I think that something as fundamental as an if-then-else should be obvious in a useful language. Heck, it's obviou…

> My problem is that I cannot see how control flow works in Forth, e.g. a simple if-then-else. Hopefully this is helpful: https://www.forth.com/starting-forth/4-conditional-if-then-s...

Thanks for that. I kinda know how it "works" at the user-level. I meant to say, I don't know how it is implemented.

My mental model of Forth is that there is a simple parser that consumes space-delimited keywords. The interpreter looks up that keyword in a dictionary, which gives the address of the machine code that handles that word. The interpreter either makes a subroutine call to that address (subroutine threaded), or jumps to that address (called "direct threaded" if I recall, where the handler jumps back to the interpreter instead of executing a RET).

But that's where my mental model of Forth breaks down, because IF-THEN-ELSE cannot be implemented in that model. So there must be something else fundamental in the Forth interpreter that I don't understand.

Re: Easy Forth (2015)

#42
post #35
post #7

Earlier quoted context omitted.

Right. And once again, you’ll also notice that no one is actually coding anything useful in Forth.

I've done: - Accounting system used for real life taxation in my self-employment: https://gist.github.com/lf94/fcdf41776e14fcc289bac652ea8cb4f... - Software shader rasterizer for image generation: https://gist.github.com/lf94/f74c927e59b4010d9de001fa2ba8791... - PS4 controller macro system via an RP2040 & ZeptoForth: https://youtu.be/exayMSQfyqk , https://gist.github.com/lf94/2d64917728594516dee6caf7667d2e4... - Iamb…

This is pretty impressive!

I don't think it takes billions of dollars in development to write a C compiler, but it does seem like everyone's first C compiler does take at least a year, so US$100k is a good ballpark. I agree that Forth is about an order of magnitude easier. You probably shouldn't consider https://github.com/kragen/stoneknifeforth to actually be a Forth (it's not interactive and doesn't have immediate words) but it did compile itself into a working ELF executable and it did take me almost exactly a month to write (October 02008, specifically). I could probably write a real Forth now in a month.

I would be very excited to read your small Forth novella. Or your small Haskell novella.

Re: Easy Forth (2015)

#43
post #37
post #19

Earlier quoted context omitted.

As I like to say: "C is a language that solves a million problems. Forth is a million languages that solve almost nothing." :-P I've been reading about Forth for 30-40 years. The dual stack is easy to understand. My problem is that I cannot see how control flow works in Forth, e.g. a simple if-then-else. I think that something as fundamental as an if-then-else should be obvious in a useful language. Heck, it's obviou…

It's funny that you say that, because from my point of view, control flow in Forth is one of its strong points over assembly language, because it has properly nesting control-flow structures. The syntax is a little strange; the literal translation of if (siz != 0) *d = '\0'; is (untested) siz @ 0 if 0 d @ c! then when what you'd normally expect is something like if siz @ 0 then 0 d @ c! fi but that's sort of a questi…

I kinda know how it works at the user-level, I meant to write that I don't understand how control-flow is implemented in Forth. I say more about that in my reply to a sibling comment: https://news.ycombinator.com/item?id=45334556

Re: Easy Forth (2015)

#44
post #14

Forth is very enjoyable, and it's always exciting to see someone new discovering it, but it has three big problems. The first is a technical problem: the forte of Forth is self-hosted developer tooling in restricted environments: say, under 256KiB of RAM, no SSD, under 1 MIPS, under 10 megabytes of hard disk or maybe just a floppy. In that kind of environment, you can't really afford to duplicate mechanism very much,…

The description of F83 sounds interesting - any way I can see it in action, or use it on my own?

Re: Easy Forth (2015)

#45
post #43
post #37

Earlier quoted context omitted.

It's funny that you say that, because from my point of view, control flow in Forth is one of its strong points over assembly language, because it has properly nesting control-flow structures. The syntax is a little strange; the literal translation of if (siz != 0) *d = '\0'; is (untested) siz @ 0 if 0 d @ c! then when what you'd normally expect is something like if siz @ 0 then 0 d @ c! fi but that's sort of a questi…

I kinda know how it works at the user-level, I meant to write that I don't understand how control-flow is implemented in Forth. I say more about that in my reply to a sibling comment: https://news.ycombinator.com/item?id=45334556

Oh! I see. I've commented there.

Re: Easy Forth (2015)

#46
post #41

Earlier quoted context omitted.

> My problem is that I cannot see how control flow works in Forth, e.g. a simple if-then-else. Hopefully this is helpful: https://www.forth.com/starting-forth/4-conditional-if-then-s...

Thanks for that. I kinda know how it "works" at the user-level. I meant to say, I don't know how it is implemented . My mental model of Forth is that there is a simple parser that consumes space-delimited keywords. The interpreter looks up that keyword in a dictionary, which gives the address of the machine code that handles that word. The interpreter either makes a subroutine call to that address (subroutine threade…

> So there must be something else fundamental in the Forth interpreter that I don't understand.

The missing bit is IMMEDIATE mode. Words can be tagged as IMMEDIATE, which means that they get executed at compile time (or parse time, for an interpreter), rather than a call to them getting compiled (executed at run time, for an interpreter). IF/ELSE/THEN are then "just" IMMEDIATE mode words -- but you can add your own. The "special sauce" is that IF compiles (easier to talk about for a compiler; generalize as needed) a conditional branch to an unknown address, and puts the address of that branch instruction (or an equivalent) on the /compile time/ data stack; THEN then looks at the address on the /compile time/ data stack and patches that instruction to branch to the correct address. Plenty of subtlety possible, but the basic primitive of IMMEDIATE mode is the key.

Re: Easy Forth (2015)

#47
post #10
post #6

>> The thing that separates Forth from most other languages is its use of the stack. In Forth, everything revolves around the stack I mean, that's pretty much every language. The main difference is that the programmer's access to it is unconstrained by things like method call definitions.

Unlike most languages, Forth has two stacks. It sounds trivial, but it changes many things. It allows for a leaner call convention. With a single stack, every function call has to "shovel forward" its arguments over the function return address, where Forth "glides" through its arguments, making function calls significantly lighter.

> Unlike most languages, Forth has two stacks.

Like Forth, Ada has two stacks. Unlike Forth, which uses two stacks to simplify the language, Ada uses two stacks to complexify the language. This generalizes to other language features.

Re: Easy Forth (2015)

#48
post #46
post #41

Earlier quoted context omitted.

Thanks for that. I kinda know how it "works" at the user-level. I meant to say, I don't know how it is implemented . My mental model of Forth is that there is a simple parser that consumes space-delimited keywords. The interpreter looks up that keyword in a dictionary, which gives the address of the machine code that handles that word. The interpreter either makes a subroutine call to that address (subroutine threade…

> So there must be something else fundamental in the Forth interpreter that I don't understand. The missing bit is IMMEDIATE mode. Words can be tagged as IMMEDIATE, which means that they get executed at compile time (or parse time, for an interpreter), rather than a call to them getting compiled (executed at run time, for an interpreter). IF/ELSE/THEN are then "just" IMMEDIATE mode words -- but you can add your own.…

Ah I see, this is peeling back a few layers of obscurity about the Forth interpreter for me. Let's stick with a Forth interpreter because that seems easier to think about for me.

Are you saying that the Forth interpreter is a 2-pass interpreter? Or does the interpreter go into a special IMMEDIATE mode upon hitting the IF keyword, then it just consumes subsequent tokens without doing any dispatching, until it hits the THEN token? It sounds like nested IF-THEN-ELSE becomes tricky to handle.

How does the FORTH interpreter handle loops? Does the interpreter hit the WHILE token, goes into IMMEDIATE mode, remembers the location of the WHILE, then dispatches all the subsequent code, until it hits the REPEAT token, then branches back to the WHILE?

Re: Easy Forth (2015)

#49
post #41

Earlier quoted context omitted.

> My problem is that I cannot see how control flow works in Forth, e.g. a simple if-then-else. Hopefully this is helpful: https://www.forth.com/starting-forth/4-conditional-if-then-s...

Thanks for that. I kinda know how it "works" at the user-level. I meant to say, I don't know how it is implemented . My mental model of Forth is that there is a simple parser that consumes space-delimited keywords. The interpreter looks up that keyword in a dictionary, which gives the address of the machine code that handles that word. The interpreter either makes a subroutine call to that address (subroutine threade…

As @addaon writes, your missing ingredient is immediateness. This is one of the most powerful, yet mind-boggling aspects of Forth. I encourage you to check it out, it will make you grow as a developer.

Re: Easy Forth (2015)

#50
post #48
post #46

Earlier quoted context omitted.

> So there must be something else fundamental in the Forth interpreter that I don't understand. The missing bit is IMMEDIATE mode. Words can be tagged as IMMEDIATE, which means that they get executed at compile time (or parse time, for an interpreter), rather than a call to them getting compiled (executed at run time, for an interpreter). IF/ELSE/THEN are then "just" IMMEDIATE mode words -- but you can add your own.…

Ah I see, this is peeling back a few layers of obscurity about the Forth interpreter for me. Let's stick with a Forth interpreter because that seems easier to think about for me. Are you saying that the Forth interpreter is a 2-pass interpreter? Or does the interpreter go into a special IMMEDIATE mode upon hitting the IF keyword, then it just consumes subsequent tokens without doing any dispatching, until it hits the…

No, that's not it. It's much simpler than that, yet has much deeper implications than you think. You don't see it in other languages. The closest thing would maybe be compile-time macros in Zig? But in Forth, the power it unlocks comes in its purest form, without any fluff around it.
Post reply on HN