Remix.run Logo
zabzonk 4 days ago

Very fast (faster than naive assembler) but not at all high-level; having to look after the stack is a bit of a pain. Writing your own FORTH is fun - it doesn't need to be in assembler - I once wrote a FORTH-like scripting language in C++.

MaxBarraclough 3 days ago | parent | next [-]

> Very fast (faster than naive assembler)

Every Forth that uses conventional threaded-code interpretation pays a considerable performance penalty, execution times are likely to be very roughly quadruple the equivalent assembly. [0]

Forth's runtime performance can be competitive with C if 'proper' compilation is performed, though. [1]

[0] https://benhoyt.com/writings/count-words/

[1] (.fth file with their results in comments) http://www.mpeforth.com/arena/benchmrk.fth

PittleyDunkin 3 days ago | parent [-]

This is true. It's not terribly difficult to bootstrap an (inlining) compiler from a threaded interpreter, though, including eliding a lot of stack operations.

I'm curious if anyone has tried using futamura projections to do this in stages. I hadn't known about them when I last built a forth and it may yield more satisfying, incremental results than the last time.

codesnik 4 days ago | parent | prev | next [-]

but it's also very extendable. It's ability to slap on new control structures and DSL's is on par with Lisp. I'd say it's very low level and much higher level than the most languages simultaneously.

zabzonk 4 days ago | parent | next [-]

yes, that's what i did on the C++ implementation i mentioned. it was for writing the action parts (not the parser etc.) for a text adventure system.

tombert 4 days ago | parent | prev [-]

Yeah, that's what I was kind of getting at. It looks like it starts low level, but it seems like it allows effectively an infinite amount of abstraction.

Someone 4 days ago | parent | prev [-]

> Very fast (faster than naive assembler)

Depends on how naive the assembler programmer is, and, I would think rarely, if ever, on modern hardware because the many subroutine calls kill branch prediction benefits. Also, on lots of old 8-bit hardware, defaulting to 16-bit integers will kill performance relative to native assembly in cases where 8-bit integers suffice.

(Of course, you can fairly easily replace hot loops by assembly or (more difficult) change the forth compiler to compile parts to native code, fuse words, etc)