[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)