[HN Gopher] Forth: Stack-Manipulation Operators ___________________________________________________________________ Forth: Stack-Manipulation Operators Author : optimalsolver Score : 77 points Date : 2021-05-14 17:37 UTC (5 hours ago) (HTM) web link (www.forth.com) (TXT) w3m dump (www.forth.com) | jnwatson wrote: | This reminds me of the excellent shareware game for the Mac | called RoboWar [1] by David Harris. In it, you programmed a robot | to destroy other programmed robots in an arena. You could spend | points on different weapons, shields, and processor speed. | | The programming language was a custom stack-based language like | Forth. It worked quite well for its purpose, as you could easily | count instructions. | | 1. https://en.wikipedia.org/wiki/RoboWar | huachimingo wrote: | Minecraft had a mod with Forth support: | https://technicpack.fandom.com/wiki/Forth_language | astrobe_ wrote: | And so those Minetest: | https://github.com/Ekdohibs/forth_computer (it seems to be an | unsafe mod tho cause I see it loads shared libraries). | kragen wrote: | As I wrote here a month ago, I worry that the stack manipulation | operators can be a cognitive danger to people who are newly | learning Forth: https://news.ycombinator.com/item?id=26884231 | | It's _cool_ to be able to write : CAB ( c a b -- ) - SWAP / ; | but that very coolness can easily lead you into giving up on | Forth. It's natural to work to do everything on the stacks, since | you _can_ , but that's not a practical way to program; this | function is fine, but in sufficiently complicated cases, you end | up with unreadable code where you're struggling to play mental | chess with the stack. And then you sigh, decide that Forth is for | people smarter than you (which is reinforced by some of the self- | aggrandizing nonsense around Forth), and you go back to Python. | | Maybe a _better_ way to teach Forth would be to teach people | about VARIABLEs or VALUEs _first_ , so they can write 0 VALUE C : | CAB TO C - C / ; or possibly VARIABLE C : CAB C ! - C @ / ; and | then _only later_ introduce SWAP, DUP, and the rest as | _shortcuts_. VALUE or VARIABLE is _simpler_ than stack | manipulation operators -- with either VALUE and TO, or with @, !, | and VARIABLE, you can write _every possible_ stack manipulation | operator. So it 's less to learn than the whole zoo of DUP, DROP, | SWAP, 2DUP, 2DROP, OVER, >R, R>, TUCK, NIP, 2SWAP, ROT, 2OVER, | -ROT, R@, and RDROP. | | But then, later on -- look! With this new SWAP shortcut, you can | write this CAB function without a variable! And you probably | should. But if you ever find yourself writing code with -ROT you | probably should seriously consider rewriting it. | | Of course mutable variables are themselves bug-prone -- you can | forget to set them on some control path, for example, or forget | to redeclare them and so accidentally share a variable with some | subroutine you're calling -- but in my experience these are much | less serious pitfalls than ending up with a bunch of @ ROT + SWAP | and OVER + SWAP 0 >R. | | On the other hand, I don't have a great track record with either | writing difficult programs in Forth _or_ teaching people things. | So I might be off base here. | retrac wrote: | It's Forth tradition to make your own slightly incompatible | Forth. Honouring that tradition, I suggest an extension to the | VM. Either with a few registers, or a second stack. For | pointers. That way, memory access to a single or handful of | variables becomes a single word. Add things like dereference- | and-increment load/store primitives and it becomes very C-like, | and a rather nice target for compilers. | | (I can't take credit for this idea: | https://www.complang.tuwien.ac.at/anton/euroforth/ef08/paper... | "Updating the Forth Virtual Machine" by Stephen Pelc for | EuroForth 2008, which is probably also not the first time | someone suggested this.) | kragen wrote: | Interesting! Some way to distinguish pointers from integers | is kind of a sine qua non for memory safety; I've been kind | of thinking along the lines of Smalltalk object descriptors, | where each memory allocation is in a "segment" of its own, | into which you can index with integers. That would save you | from debugging segfaults. (But then, so does Hindley-Milner | typing, and that doesn't cost a bounds-check on every memory | access.) | | Pelc's proposal is to add scratch/index registers A and B | (notably, not segregating integers from pointers) and base | pointers X or LP (the frame pointer) and Y or UP (thread- | local data pointer). His motivation seems to be primarily | efficiency and clarity rather than memory-safety. | | Probably you want at least LP and UP to be callee-saved. If | you make LP into an additional stack rather than just a | register, then you save yourself a Y> >R on entry to | subroutines that allocate stack frames, and half of a R> >Y | on exit. (The CPU still has to do the same amount of work, | but plausibly you spend less on op dispatch overhead and code | space.) Doing the same with the A and B scratch/index | registers might make sense, or you could just treat them as | caller-saved. At some point restoring individual shallow- | bound variables one by one stops being a good tradeoff, and | it starts making more sense to put them in a stack frame or | instance-variable vector and access them by indexing off a | base pointer. | | Adding a small number of local-variable registers like this | is kind of a pain for hand-programming, though, as opposed to | as a compiler target. Instead of having to remember whether | the quantity two levels down in the stack is the voltage or | the current, you have to remember whether the A register is | currently the voltage or the current. Much easier to say 0 | VALUE VOLTAGE 0 VALUE CURRENT, or maybe VARIABLE V VARIABLE | I, and then your code is always explicit about which one it's | expecting. | threatofrain wrote: | It seems that as interesting as Forth is, the community of such | languages is very niche and small, even smaller than Lisp. Can | anyone speak to recent changes in velocity or energy? | PaulHoule wrote: | Who cares? If you need some minimal programming language with | some special characteristics, you can write a FORTH in 2k lines | of assembler or so. | | The first time I used 32 bit ints on an 8 bit computer was in a | FORTH that implemented 32 bit math, for instance. | protomyth wrote: | Because of the original 128K Mac's limited memory, FORTH was | one of the first actually useful language you could host on | it. | colllectorof wrote: | https://factorcode.org/ | | One of the most impressive languages you've never heard about. | | https://www.youtube.com/watch?v=f_0QlhYlS8g | ww520 wrote: | There's something very practical about postfix and stack based | languages like Forth - compactness and simplicity. Just couple | weeks ago I had the need to build a small language with the | requirement of terse and compact syntax. I settled on a Forth- | like stack based language and was able to build the parser, | compiler, and code gen to GPU in about 80 lines of JS code in a | short time. | haolez wrote: | Forth has almost no syntax, which leads to every project | becoming some kind of domain specific DSL. This is not | necessarily a problem, but it leaves Forth without a strong | sense of identity as a programming language. This is my | opinion, of course. | Someone wrote: | Not only your opinion. It is fairly common among Forth | enthousiasts to talk about "a Forth", rather than "Forth", as | two Forths can be hugely different, yet be recognized as | Forths (lisp is similar in that regard) | | The ideal system is optimized for its problem domain. That | means not only adding needed functionality, but also dropping | unneeded functionality, and tweaking functionality to better | fit the problem at hand. That's not surprising for a system | that shines when running with very little memory. | | That's different from, say C++. Nobody says clang, gcc and | Visual C++ are "a C++". | | If they were philosophically similar to Forths and Lisps, | those writing programs in them would be happy to change int | promotion rules, operator precedence, vtable layout, etc, and | different compilers would make different choices there. | macintux wrote: | Presumably that's compounded by the fact that the inventor, | Chuck Moore, feels strongly that Forth is more of a concept | to be reimplemented for each project, customized along with | the hardware, than a programming language to be standardized. | throwaway17_17 wrote: | Moore's talks and quotes of his from various lecture notes | on this point really inspired the underlying theory of my | personal programming language. I wanted something that I | could adapt to different use cases when I saw fit, but with | a solid underlying theoretical base. I have been using it | for my personal work for about 8 months now (compiling to | JS, C or C++ depending on project) and I'm enjoying it | greatly as well as being productive. | macintux wrote: | Do you have a blog post about your language? If not, you | should write one. | Syzygies wrote: | The Wikipedia entry | https://en.wikipedia.org/wiki/Forth_(programming_language) is | terse but matches what I've read elsewhere over the years: | | Forth is both easy to implement and yields very compact | binaries, so it has been favored as the first environment | implemented on new hardware, and as the controller for | satellites. This has become less important as resource | constraints ease. | | Forth's progeny PostScript continues unabated. Humans tend not | to code directly in PDF format, as that is grave-digging. The | "specification" has many geological layers (the earliest are | easiest to code in) and no verification or even machine- | readable definition, so one is at the mercy of testing PDF | files with multiple applications. All the problems associated | with Markdown, only on steroids. But one can easily write code | that generates valid PostScript, and have the results | translated to PDF. | openfuture wrote: | I don't think forth has a smaller community than lisp just a | less web-friendly one. Lots of embedded people. | | Lisp is top down, forth is bottom up. | anthk wrote: | Sadly for CollapseOS' users, this Forth implementation doesn't | have ".S". | sigjuice wrote: | I came across this implementation of .S a couple of days ago | (Starting-FORTH.pdf, page 50). : .S CR 'S S0 @ | 2- DO I @ . -2 +LOOP ; | | I'm not sure if this could be adapted to work on CollapseOS. | For starters, I can't quite figure out what 'S is. S0 is the | (non-standard) stack pointer according to | https://www.forth.com/starting-forth/9-forth-execution/ . The | rest of it appears to be standard Forth, but I'm not sure how | much of it is actually implemented. ___________________________________________________________________ (page generated 2021-05-14 23:00 UTC)