5 ms·
Write-only, because only the functions (‘WORDS’) are named - no parameter names. There are also no local variables in standard Forth, you have to push (and pop
by wrycoder 7y ago
Write-only, because only the functions (‘WORDS’) are named - no parameter names. There are also no local variables in standard Forth, you have to push (and pop!) them from the separate return stack. Accessing parameters is done by manipulating the stack, which makes the code opaque after a year or so. Named constants and variables are all global. So, it is very difficult for a team to use, since most of the legibility of software comes from insightfully selected names. Two thirds of those names, at least, are missing in Forth.
Like assembler, Forth is untyped.
These failings could be at least partly forgiven if Forth was fast. But it isn’t, because most words are short and all the stack manipulations are done with subroutine calls. It’s possible to write an inlining, optimizing compiler, but then the simple layout of code in memory is lost, and quick introspection using a memory dump becomes nearly impossible.
But, it is a neat tool to bootstrap a working system quickly on new, embedded hardware with limited resources. Definitely a black belt tool for lightweight systems written by a single person. Hard on maintenance programmers.
See Jonesforth for a tutorial example.
I wrote a Forth a few decades ago. The insight gained reminds me of Nand2tetris, but the latter is far more mainstream.
- szemet 7y agoall the stack manipulations are done with subroutine calls This can have an advantage: one can stuff much more code (and functionality) in a very memory limited system (e.g. smart cards), especially with WORDS compression: "Huffman threaded code is one of the most compact representations known for a computer program" https://en.wikipedia.org/wiki/Threaded_code#Huffman_threading https://en.wikipedia.org/wiki/Threaded_code#Huffman_threadin...
- 0815test 7y ago> Write-only, because only the functions (‘WORDS’) are named - no parameter names You could use lambda notation to name the parameters of a function, while still preserving postfix function application as in FORTH. This would effectively give you De Bruijn notation, in which named lambda was often denoted `[var] expr`. Though, ironically, De Bruijn is also known for his "nameless" De Bruijn indexes, which dispense with the very naming of function parameters, replacing these names with what are in effect references to positions on some abstract argument stack.
- astrobe_ 7y ago> Write-only, because only the functions (‘WORDS’) are named - no parameter names. Depends on who is the writer... > There are also no local variables in standard Forth Named locals variables are in the standard, as an optional extension. Because not everyone want them. > you have to push (and pop!) them from the separate return stack That's the main reason why the return stack is exposed to the programmer, yes, but there are other techniques like putting some of the data that are used throughout the program in (global) variables. you generally choose depending on how much simplification you gain and how much modularity you lose etc. > Accessing parameters is done by manipulating the stack, which makes the code opaque after a year or so Depends on how you write and comment. > Named constants and variables are all global. So, it is very difficult for a team to use Standard Forth as vocabularies to isolate functions, constants, and variables that is supposed to help with name clashes. Many variants like Retro have some sort of namespace mechanism. Did you actually use Forth in a team context? > These failings could be at least partly forgiven if Forth was fast. But it isn’t, because most words are short and all the stack manipulations are done with subroutine calls Not a problem, because you design your programs to minimize stack juggling. Less overhead, more readable, one stone, two birds. My dialect which uses very naive subroutine threading (it just executes lists of function pointers) can rival with Lua (non JIT) on certain tasks because my Forth doesn't spend its time doing useless stuff like looking up an hash table. The speed of Forth is not in its bytecode interpreter. It's in the simplifications it encourages. > It’s possible to write an inlining, optimizing compiler, but then the simple layout of code in memory is lost, and quick introspection using a memory dump becomes nearly impossible I have written a few decades such a thing for the 8086, and I would say the lack of introspection was never a problem. When you write such a system, the hex machine codes sticks quickly in your head. I think I wrote a disassembler for the lulz, but an hex dump was probably my main "introspection" tool. > I wrote a Forth a few decades ago I wrote several Forth systems in the last few decades. The latest one I wrote is my goto-tool and serves me almost daily.
- kazinator 7y ago> Depends on how you write and comment. Unless working in assembly or something of that sort, tend to I comment only on noteworthy matters pertaining to specific logic, not recurring units of basic program structure and their routine connections.