5 ms·
The specific issue with reading Forth is that unlike other languages, you, the reader, need to be intimately familiar with the call semantics of every word that
by whartung 5y ago
The specific issue with reading Forth is that unlike other languages, you, the reader, need to be intimately familiar with the call semantics of every word that you're trying to read. In most other languages, this is not a problem as (most) are explicit in what's being passed and returned. And Forth is unlike BASIC where most most everything is implicitly global.
This issue with Forth is because you have the "invisible" stack as a first class parameter passing system. So, given a string of Forth words, while the stack may be apparent at the start (perhaps as a comment at the entry of a high level word), what happens to that stack during processing is opaque to the reader. Then you have have issue within individual words of stack gymnastics to get everything lined up for the interior processing, or readying to call something else. Now, if the reader knows each word and its behavior, then they can follow along but under the cognitive load of effectively "executing" each word they see to visualize its stack impact. You can learn to skip a bunch of the gymnastics because, assuming it works, you "don't care", it's just the noise of processing "knowing" it's converting from X to Y, and just knowing the Word W needs Y, how it gets Y is, often, less important. But it can impact the logic standing out buried in the manipulations to invoke everything properly. In Lisp, for example, I do a lot of "converting" in the (let ...) section, then the code works on the results of that. If you "ignore" the (let ...) section, the code is usually reasonably clear. That tends to be difficult in classic Forth as that gets all intermixed.
It's one thing when you've built up your code base over time, and are familiar and intimate with it incrementally. But it's quite another approaching a foreign code base.
Over time, familiarity reigns and lowers the impact, but on an initial read it can be quite challenging.
It's also fair that at some point, at the higher levels of abstraction, all of that goes away, and the code just "reads", but, inevitably there's a bunch of sausage makings supporting it that you need to make sense of.
- ngcc_hk 5y ago“ for example, I do a lot of "converting" in the (let ...) section, then the code works on the results of that. If you "ignore" the (let ...) section, the code is usually reasonably clear. That tends to be difficult in classic Forth as that gets all intermixed.” !!! Never occur to me. Great found of the day.
- kazinator 5y ago> is that unlike other languages, you, the reader, need to be intimately familiar with the call semantics of every word that you're trying to read Not really "unlike other languages". You can hardly read any language if you don't know what the words mean. In Forth, even if you know what every word means and how many operands it consumes and produces, it's not obvious what in the program produces the operands and what consumes them. There is no syntactic enclosure or other such clue which links them together. Forth could be like getangle ... hundreds of words ... cos where getangle produces the operand that is consumed by cos, hundreds of words away. Nothing links these two locations together visibly. No syntactic enclosure, no def/ref of a shared identifier. Probably, the answer in Forth programming is: don't do that. Don't have code that has hundreds of words in one definition. If no word definition consists of a large number of items, then you minimize this problem. In "mainstream" languages, though, we can have a large body of code such as a big function that is hundreds of lines long, and it can be reasonably easy to deal with if it is otherwise well structured. If a variable is defined at line 50, which is then used at line 550, you can fairly easily track that in your editor. Not as nicely as 50 verus 65, but the linkage is visible enough.
- Someone 5y agoHistorically, code was written in 1k blocks of 16 lines of 64 characters (https://wiki.c2.com/?ForthBlocks https://wiki.c2.com/?ForthBlocks). That gave programmers good incentives not to write words that had that problem
- DonHopkins 5y agoThat also gave programmers good incentives to write decent text editors and file systems that could deal with any number of lines, to get around that historic annoying limitation of FORTH. ;) Granted it was nice to have a dead simple file system for embedded devices, but forcing you to keep your word definitions short always seemed like a lazy excuse for not having a real text editor and file system. Sometimes you don't, but don't blame that on trying to incentivize programmer behavior. FORTH hardly ever "forces" programmers to do anything, so that excuse never rang true to me. The "block" approach also forced you to not write comprehensive stack comments and documentation too, which is more important than keeping your word definitions short. Otherwise you get dense sparsely documented code like this (which came from my Apple ][ Forth 40x24 screens): https://donhopkins.com/home/archive/forth/supdup.f https://donhopkins.com/home/archive/forth/supdup.f Instead of documented code with stack comments like this (in spite of the fact that the attribution in the documentation is wrong ;) ): https://donhopkins.com/home/archive/forth/alloc.f https://donhopkins.com/home/archive/forth/alloc.f https://news.ycombinator.com/item?id=27484426 https://news.ycombinator.com/item?id=27484426 Here's some IBM-PC Forth for the CAM-6 cellular automata machine that was block based -- check out the unique idiosyncratic right-justified reverse-indentation style (starting with KGET), which is not standard Forth style, but sure looks cool and poetic, like E E CUMMINGS ON CAPS LOCK: https://donhopkins.com/home/code/tomt-cam-forth-scr.txt https://donhopkins.com/home/code/tomt-cam-forth-scr.txt https://donhopkins.com/home/code/tomt-users-forth-scr.txt https://donhopkins.com/home/code/tomt-users-forth-scr.txt Tommaso Toffoli and Norman Margolus use that style of formatting in the CAM-6 book code samples too (i.e. page 20, Game of Life): https://donhopkins.com/home/Tommaso_Toffoli_Norman_Margolus_Cellular_Automata_Machines.pdf https://donhopkins.com/home/Tommaso_Toffoli_Norman_Margolus_... Also the code in this paper by Rudy Rucker: https://content.wolfram.com/uploads/sites/13/2018/02/03-1-6.pdf https://content.wolfram.com/uploads/sites/13/2018/02/03-1-6.... I wrote lots more about FORTH and the CAM-6 before: https://news.ycombinator.com/item?id=23058545 https://news.ycombinator.com/item?id=23058545 DonHopkins on May 3, 2020 | parent | context | favorite | on: History of Logo FORTH is the ultimate macro-assembler! The assembler is just written in and integrated with FORTH, so you have the full power of the FORTH language to write macros and procedural code generators! And it makes it really easy to call back and forth ;) between FORTH and machine code, with convenient word definitions for accessing the FORTH interpreter state. Here's part of my SUPDUP terminal emulator for the Apple ][ with some 6502 code for saving and restoring lines of text in a bank-switched memory expansion card: https://donhopkins.com/home/archive/forth/supdup.f https://donhopkins.com/home/archive/forth/supdup.f Here is a great example of FORTH and 8086 assembly code for hardware control (written by Toffoli and Margolus for controlling their CAM-6 cellular automata machine hardware), starting with "CAM driver routines" and also "creates fast code words for picking out bits of variable X": https://donhopkins.com/home/code/tomt-cam-forth-scr.txt https://donhopkins.com/home/code/tomt-cam-forth-scr.txt https://en.wikipedia.org/wiki/Cam-6 https://en.wikipedia.org/wiki/Cam-6 Rudy Rucker wrote about learning FORTH just to play with that hardware: https://www.fourmilab.ch/cellab/manual/chap5.html https://www.fourmilab.ch/cellab/manual/chap5.html >Starting to write programs for the CAM-6 took a little bit of time because the language it uses is Forth. This is an offbeat computer language that uses reverse Polish notation. Once you get used to it, Forth is very clean and nice, but it makes you worry about things you shouldn't really have to worry about. But, hey, if I needed to know Forth to see cellular automata, then by God I'd know Forth. I picked it up fast and spent the next four or five months hacking the CAM-6. >The big turning point came in October, when I was invited to Hackers 3.0, the 1987 edition of the great annual Hackers' conference held at a camp near Saratoga, CA. I got invited thanks to James Blinn, a graphics wizard who also happens to be a fan of my science fiction books. As a relative novice to computing, I felt a little diffident showing up at Hackers, but everyone there was really nice. It was like, “Come on in! The more the merrier! We're having fun, yeeeeee-haw!” >I brought my AT along with the CAM-6 in it, and did demos all night long. People were blown away by the images, though not too many of them sounded like they were ready to a) cough up $1500, b) beg Systems Concepts for delivery, and c) learn Forth in order to use a CAM-6 themselves. A bunch of the hackers made me take the board out of my computer and let them look at it. Not knowing too much about hardware, I'd imagined all along that the CAM-6 had some special processors on it. But the hackers informed me that all it really had was a few latches and a lot of fast RAM memory chips.
- Karrot_Kream 5y agoA productive Forth system, for me, has stack effects commented into each of the words, in Thinking Forth style has a literate style which flows, has plenty of testing words which help you build up mock objects that you can test your words on, and often real tests which tests each word to make sure it does what it's supposed to (e.g. place a file id on the stack, run your word, and then test the file id to make sure it has the contents that you expect.) Developing and testing should happen often and frequently in the REPL; it's a very dynamic process. This style is very different from ALGOL or Lisp style structured programming where it can be annoying to test things (though in Common Lisp you should just be able to jump into a running function and see what's going wrong), but in its stead the compiler gives you a lot of assurance as to what's going on.
- DonHopkins 5y agohttps://news.ycombinator.com/item?id=9843962 https://news.ycombinator.com/item?id=9843962 DonHopkins on July 7, 2015 | parent | context | favorite | on: Thinking Forth (1984) Thinking Forth is a FANTASTIC book -- by all means read it to learn the most important universal lessons from Forth, even if you're not going to program in it! Forth is a "glass box" instead of a "black box", and it's simple enough that you can easily understand EVERYTHING about how it works right down to the most primitive words defined by machine instructions. It like scheme in that it's great for meta programming and creating higher level domain specific languages, but its approach is different enough and much lower level than Scheme that it's worth learning scheme as well as forth, to contrast them for a better perspective. Another interesting related language is PostScript, which is a lot like Forth in some ways (rpn stack based, separate return and parameter (and dictionary scope) stacks, how the threaded interpreter works, and its extreme simplicity and power) but a lot like scheme in other ways (data is code, polymorphic arrays and dictionaries, typed object references instead of raw untyped pointers, with typed objects bound to names in dictionaries as opposed to typed variables holding values (you can redefine the same name to different types, since the object with its type is associated with the key in a dict, the type is not declared for the variable name itself like C), a safe high level language with bounds checking, garbage collection (in a modern implementation -- old printers tend to use simpler heaps), etc). PostScript (and scheme) is a lot more of a "black box" than Forth is, since there's a lot of magic stuff going on under the hood that you can't see, to make it seem simple on the surface. And I'd say that on the surface, PostScript is simpler than Forth, because of how it's higher level and you don't have to worry about a lot of details. But Forth is actually extremely simple all the way down! \ First you should: FORTH ?KNOW IF HONK! ELSE FORTH LEARN! THEN \ Then you can: BEGIN FORTH THINK! AGAIN