Hacker News new | past | comments | ask | show | jobs | submit login
Thinking Forth (1984) (sourceforge.net)
133 points by susam on Nov 20, 2022 | hide | past | favorite | 49 comments



Recent and related:

Starting FORTH (1981) [pdf] - https://news.ycombinator.com/item?id=33674486 - Nov 2022 (22 comments)

Lots more links here: https://news.ycombinator.com/item?id=33676237


I treasure my copy of Thinking Forth. I was at a formative age when I read it and I learnt so many great programming concepts from it. The most important being keep breaking the problem down into simpler bits so you can understand and name each bit.

It is a Forth book, but I think anyone could get things out of it.

Leo Brodie's cartoons are very good too. One of my favourite ones is of a machine called the "Universal Processor" with a blender on top and computer keyboard underneath and a knob on the front which has three positions "Word", "Food", "Data" illustrating the danger of building over general solutions.


My introduction to Forth was tinkering first with Sun SPARC machines in the late 90s and then PowerMacs in the early 00s.

At the time, I had no idea that it was a discrete programming language; it only registered in my mind as part of the OpenBoot/OpenFirmware environments. Then I ran into the FreeBSD bootloader and things finally clicked. "Aha," I thought, "this is an actual programming language." But what made it so popular for the early boot process, and where else was it used?

The modularity was stunning. It was easy- almost absurdly so- to build complex code up from a series of tiny individual functions. That, coupled with the minuscule interpreters and simple stack-based approach, made perfect sense for situations where developers need to perform complex tasks with minimum of storage overhead, and with portability as a first class citizen.


> But what made it so popular for the early boot process, and where else was it used?

Probably simplicity. You can get a very basic Forth system going in a few dozen assembly instructions. Then, you write some Forth "primitives", words written in assembly, to do things like basic arithmetic, branching, stack manipulation, and memory manipulation. There are endless debates about how many primitives you really need, but in general a couple of dozen primitives ought to get you started.

Then the rest of Forth is just written in Forth! You might not really have recognisable Forth source at this stage but more complex words can be written out as lists of the addresses of primitives. Think of it as like rolling your own macro assembler. The "inner interpreter" reads these lists of addresses and either jumps directly to the machine code in a primitive, or into a command that starts the inner interpreter chewing on a new word, pushing the one you've just come from onto the return stack.

It seems really really complex until at some point as you stare at it, it'll just snap into focus and you see it's actually a very simple thing that does a very clever trick.


Sectorforth and sectorlisp are interesting studies in minimalism. One of the goals of sectorforth’s author was to know whether

> if you have an interactive terminal, a dictionary, and the colon compiler, can you really build everything else based on just eight primitives?

> Turns out the answer is yes

The eight primitives come from an old usenet thread: https://groups.google.com/g/comp.lang.forth/c/NS2icrCj1jQ


I've frequently written about Mitch Bradley's Forthmacs / Sun Forth / CForth / OpenBoot / OpenFirmware on HN. I was his summer intern at Sun in 1987, and used his Forth systems in many projects!

https://github.com/openbios

https://wiki.laptop.org/go/FORTH

https://news.ycombinator.com/item?id=29261810

Speaking of Forth experts -- there's Mitch Bradley, who created OpenFirmware:

https://news.ycombinator.com/item?id=21822840

Here's the interview with Mitch Bradley saved on archive.org:

https://web.archive.org/web/20120118132847/http://howsoftwar...

[...]

https://news.ycombinator.com/item?id=27484426

I wrote malloc.fth for Mitch Bradley's ForthMacs, which ended up in OpenFirmware:

https://github.com/openbios/openfirmware/blob/master/ofw/cor...

[...]

https://news.ycombinator.com/item?id=26892629

In a lot of FORTH implementations, constant numbers like 0, 1, -1 and others are hard coded, not just for speed but also for space: a call to a code word only takes one cell, instead of using two cells with a LIT [value].

Here's some Breshenham line code I first wrote in FORTH (Mitch Bradley's SunForth on a 68k Sun-2 with cg2 graphics board), then translated to 68k code (using the rpn FORTH assembler) -- the FORTH code is commented out before the corresponding assembly code:

https://donhopkins.com/home/archive/forth/cg/line.f

[...]

https://news.ycombinator.com/item?id=17480298

Cool! Does it include a FORTH 6502 assembler written in FORTH? I love writing assembly code in RPN with Forth macros!

You can write FORTH code with loops and conditionals and any kind of logic and parameters, that dynamically assembles machine code! Much better than your typical macro assembler.

Here's some 6502 assembler for an Apple ][ SUPDUP terminal emulator that does ram card bank switching:

http://www.donhopkins.com/home/archive/forth/supdup.f

[...]

https://news.ycombinator.com/item?id=22456471

In what way is PostScript worse than Forth? Please answer with specific details, and provide links to code if you can. I programmed a lot of Forth code before learning and moving on to programming a lot of PostScript code, so I've used each of them extensively, and much prefer PostScript, and I'm happy to show you why and explain by showing you code.

[...]

https://news.ycombinator.com/item?id=21968175

Kragen is right that PostScript is a lot more like Lisp or Smalltalk than Forth, especially when you use Owen Densmore's object oriented PostScript programming system (which NeWS was based on). PostScript is semantically very different and much higher level that Forth, and syntactically similar to Forth but uses totally different names (exch instead of swap, pop instead of drop, etc).

[...]


Aw, I'm flattered my comments merited a mention


I love Chuck Moore's minimalism applied to programming. [^1][^2] It goes hand in hand with the UNIX philosophy of keeping things simple that we can see in other software (linux) or languages (LISP, Go, Erlang )...

Also, I've always said that `Thinking Forth` is great for beginners even nowadays. It was published in the 80s yes. But it touches several "modern" topics like unit testing, function composition, modular design...

[^1]http://www.ultratechnology.com/method.htm [^2]http://www.ultratechnology.com/forththoughts.htm


One of the best programming books ever!

    FORTH ?KNOW IF
        HONK!
    ELSE
        FORTH LEARN!
    THEN


Beside embedded system or firmware, what are Forth's popular use cases these days?

Personally I never see backend development or mobile frontend job vacancies that require Forth skill, for example.


Forth has not won any popularity awards since the end of the '90s but it is still used by a small group of engineers around the world to solve their custom needs. This can be for embedded projects or firmware yes, but it has crept into larger projects.

IMHO opinion Forth is hard to learn, takes more effort to bootstrap your project (more like Assembler) and more importantly it is hard to switch gears to think with Chuck Moore's methodology. However once learned it can make one very productive.

Forth was (is?) used for experimental control in the ISS quite regularly. The ability to wip up a simple DSL that talks directly to hardware and will compile or can be used as a script is a win for those custom projects.

It's running in the FEDEX handheld package scanner from what I understand. (may be dated information) Funny story that. Way back, Version I was started in C but they hit the ROM size limits on the hardware that was already finished. Forth Inc. was asked if they could help. Using their Forth RTOS they re-wrote it and it all fit with room to spare. (Indirect-threaded-code is tight)

Years later, Version II hardware was designed with waaay more memory. Re-write in C fit nicely. All good.

But... the batteries would not last for an entire shift. Forth Inc was brought in again and they own their task scheduler so they modified it to put the CPU to sleep at every chance they could. Batteries lasted.

Largest known Forth program is on Windows. https://ribccs.com/candy/ 1M+ LOC. Compiles with VFX Forth by MPE UK.

</sermon>


YES! I worked on the FedEx Enhanced SuperTracker software from 1999-2006, which I believe is the "Version II" you're referencing. The core software was still written in Forth, but we rebuilt the package routing logic in in C, which might be what you're referring to. Very curious to know how you are familiar with all the history, did you work there or at Forth, Inc?


I worked in a Forth shop for a few years and attended a few conferences. The FEDEX story made its way around the community.


You are correct, Forth is not a institutional tool, more of a individual choice. IMO, one that allows you to prototype and debug interactively as you write your code and has been like that since the beginning.

It allows you to train yourself to have a complete control and command of your code making for tighter, simpler solutions for complex problems ( In my personal experience and comments for those that have been introduced to FORTH.)

If you consider that Embedded is a highly constrained resourced environment, then FORTH is a fantastic choice. Now step back, consider that statement once more, and you could be onto something even greater, as there is lots of resource waste-gates on modern OS and Computers. Now that Power is becoming a greater constrain resource, there might be an opportunity for someone to build something great in forth.

BTW the biggest back en used case is the bitcoint smart contract which is based on FORTH.

As you can see, and in full agreement in your statement, FORTH is a not a job magnet, IMO, you get better at programing understanding FORTH.

See Bret Victors talk, https://youtu.be/PUv66718DII you most of that already @ Forth ...! :;

Try it, you'll never go back! :)


> IMO, you get better at programing understanding FORTH.

Modern cars don't have a magneto or carburettor, but you'll have a far better ability to fix your Jag if you also know how to fix your lawnmower.


In the car analogy, it's more like learning and understanding the limitations of the Otto Engine so that you can build a better one... IMO. :) BTW, in aviation, where reliability, constancy, and longevity, they still use magnetos and carbs... :D :;


>> IMO, you get better at programing understanding FORTH

Isn't assembly fit the place better?

:)


Yes. People just don’t see it. I would argue the stack based VM’s are Forth based or inspired. Language VMs are running everywhere, billions of devices.


IIRC WebAssembly is at least partially inspired by Forth — both in syntax and being stack-based.


Python too, and of course PostScript.


Python has nothing to do with Forth, they couldn't be more opposite to each other if they tried. I recall Chuck Moore in a Silicon Valley Forth Interest Group meeting express his disappointment at how modern programming languages (and Python was among the ones mentioned) that are advertised as "simple" are anything but.

Python is an enormously complex language, full of inconsistencies and bad design. However, it masks that complexity behind a facade of user-friendliness which has done wonders for its popularity. Forth is not only as simple as it gets, but also an elegant and totally honest language. That Chuck Moore managed to distill the essence of programming in this form, speaks to his genius. Unfortunately, as is often the case with genius, it can be decades to centuries until the ideas percolate and emerge in a popular fashion.


> Python has nothing to do with Forth, they couldn't be more opposite to each other if they tried

Really? You don't look at the stack machine that runs the .pyc files and go "jeez this is just Forth with some syntactic sugar on"?


> Really? You don't look at the stack machine that runs the .pyc files and go "jeez this is just Forth with some syntactic sugar on"?

No, because stack machines, including stack machines for use as interpreters of compiled languages, pre-date Forth by many years: https://en.wikipedia.org/wiki/Stack_machine


That's literally what it's for. Forth is the simplest language to get running on hardware which you have no idea how to program directly. Much easier than doing it for C.


I'd love to learn (a) Forth. As a beginner, where do you begin? Like Lisp there seems to be different variants. I always struggle with where to start.


Write one! Forths are so simple that you can write one in minutes if you understand it, and a bit more if you don't know anything about it. Having your own forth is both really gratifying, and gives you an opportunity to play around with the internals and change things up to see what happens (and why the choices made were made).

Forth is one of the languages where you have to know the internals to write it, but the internals are really simple.


Sounds good. Any recommended starter guides? Thanks!


If you know C, retroforth's nga vm is ~300 lines and quite simple. I found it to be enlightening.

https://git.sr.ht/~crc_/retroforth/tree/master/item/doc/Nga.... - this is the "literate" version, there are a few variants of the source in the tree if you look.


Jones Forth[0] is a good literate programming implementation that explains the internals as he goes.

[0]https://github.com/nornagon/jonesforth/blob/master/jonesfort...


I'd recommend gforth. It runs on lots of systems and is well maintained.

https://gforth.org/

Eventually you'll build your own forth (seems to be a right of passage!)


“rite of passage”


"write of passage" too!


No.


I'm no Forth expert, but I've found Gforth highly educational. It's interactive, runs under Linux, is free software, supports the ANS standard, is well documented, is widely used (at least as widely used as any Forth these days), is still maintained after 27 years, and supports SEE so you can disassemble words and see how they're written. Since Gforth 1.0 it has context-sensitive help ("help begin", etc.) Before Gforth I used PFE, which shares most of these attributes.

Richard W. M. Jones's Jonesforth is pretty interesting reading, and maybe the best explanation around of how to build a Forth, but keep in mind he wasn't by any means a Forth expert when he wrote it; at first he had the rotation direction backwards for ROT. But he was already a first-class hacker, and that matters more.

But more recently my understanding of Forth has changed. I never did understand why such a janky programming language had such enthusiastic fans; even though C doesn't have closures, C is a better programming language for any situation that doesn't involve an existing Forth codebase, and for many situations that do.

My epiphany was that Forth isn't a programming language. I mean, it does have a programming language in it, but it's not a very good programming language, just the tiniest step past assembly language that can give you structured control flow and nested expressions. What's excellent about Forth is that it contains an interactive programming system with virtual memory, multithreading, compile-time metaprogramming, higher-order run-time programming, and instant recompilation, in about 8 kilobytes of memory. You can even get a substantial fraction of it in much less than that.

You know how it's useful to be able to log into the flaky web or database server and run some commands to see what's going on, maybe restart an errant process or two, or tweak a config file parameter? (Even if you don't actually do this because you push all your config changes through Git and Kubernetes, surely you've at least felt the temptation if you've ever administered a server.) Forth gives you an interactive shell on almost the tiniest microcontrollers, and it's a scriptable interactive shell that has full access to the machine's I/O ports and memory. Which is what you want when you're trying to get a weird new peripheral working. You want an interactive environment (maybe like target debugging with GDB, but with a more efficient scripting language, or OpenOCD), not a batch-mode setup where every new experiment requires waiting for a compile and reflash.

It's in that spirit that Frank Sergeant described his 66-byte target-debugging stub/bootloader for the 68HC11, which has 192 bytes of RAM, as a "three-instruction Forth": https://pages.cs.wisc.edu/~bolo/shipyard/3ins4th.html It clearly isn't a programming language he's after.

And, from that point of view, things like Gforth and Jonesforth are likely to mislead, because they're "Forth without Forth": the Forth language, but without the Forth "operating system", and only runnable in environments that are far too large to justify the tradeoffs Forth makes. They do work, but they aren't compelling.

I think this is sort of like conflating Unix with bash. People who use Unix intensively tend to use bash intensively (or, previously, tcsh or ksh, and nowadays sometimes oil, zsh, or fish, but usually bash). And part of the reason for that is that you can actually whip up some pretty cool stuff pretty quickly as a shell script. For example, here's a thing I wrote in a few minutes the other day which generates a random incorrect acronym expansion for "STC" (reformatted for readability):

    echo stc | while :;
    do
      dd of=/tmp/tmp.c.$$ bs=1 count=1 2>/dev/null;
      c=$(cat /tmp/tmp.c.$$);
      if [ -z "$c" ]; then break; fi;
      grep "^$c" /usr/share/dict/words | 
        shuf -n 1 | 
        tr '\n' ' ';
    done; echo
Result:

    spoil transform circumference 
But imagine trying to apply bash in an environment without disk caching for your filesystem, multitasking, grep, cat, dd, shuf, tr, or /usr/share/dict/words. All you're left with is the programming language! And bash is honestly a pretty shitty programming language. You'd wonder why anybody ever bothered with Unix in the first place! And that's because Unix isn't bash or the Bourne shell. They're an important part of it but not the bulk of it; bash outside of the context that makes it so insanely useful is a bit like a fish out of water, or maybe an elevator operator in a modern automatic elevator.

I don't know what embedded Forth to recommend, though, because I've never actually used Forth on a microcontroller. The only time I've ever used Forth without another OS under it is in OpenBootPROM/OpenFirmware. So I might be all wrong about this! Hopefully more experienced people can correct me. Paging DonHopkins! Paging abecedarius!


I also love your comments, this and others!

Of course OpenFirmware has some code for paging! ;)

purpose: Set up page tables and turn on paging

https://github.com/openbios/openfirmware/blob/master/cpu/x86...

    start-assembling
    protected-mode

    \ RAM is on and mem-info-pa tells the memory layout
    label entry
       \ Initialize virtual page table
       \ Initialize linear=physical page table (redundant page table entries)
       \ Enable paging  (note that page fault handler is not in place yet)

    [ifdef] notdef
       \ clear page tables
       ax ax  xor
       /ptab /l / #  cx  mov
       pt-pa #  di  mov
       rep  ax stos
    [then]


What do you think about the Forth-as-language vs. Forth-as-OS distinction?


Thank you, wonderful comment. Favorited.


I'm delighted you liked it! Your opinion here is especially important to me, given the work you've done.


See Starting Forth by the same author; it's good and short. It is even older, so it won't help on choosing an implementation and will be affected by a few differences in dialect.


For the forths, pforth is certainly portable, pfe on windows, 8th is ok. ficl is supposed to be for scripting, awhile back (years) measured and it turns out its the fastest one in certain cases.

For the new agey stuff I'd say start with factor if you're on x86. if you're not maybe try retro[0], or write your own.

[0]: http://forthworks.com/retro/


Loved the language - first as an embedded developer (late 80s), then with Harris Semi's RTX microcontroller team. I see a Forth reference about once per month on HN but nothing in developer-specific forums, so I have to assume Forth is dead.

What gives? Is there some use case that only Forth can satisfy? Is it just the simplicity and "strangeness"?


I haven't gone as deep as I'd like to into Forth, but I liken it somewhere in between Assembly and C in terms of level of abstraction, and from what I can see the trends of programming languages are features that move further away from hardware and computer specifics towards higher level concepts (the first thing that jumps to mind is Lisp)


It's a bit like rolling your own macro assembler, in a way.


Yes indeed, but even more so: Forth is vastly more powerful than a mere macro assembler, because you have the full power of Forth to write arbitrary functions and mini-compilers to assemble code, no just simple macros! It comes with structured control flow constructs, and you can even write your own. Not only is the assembler itself written in Forth, but you can seamlessly extend and build on top of the it too, building high level interfaces and domain specific languages on top of low level assembly code and hardware.

Check out the amazingly powerful x86 assembler in OpenFirmware, which is deeply integrated with the hardware, operating system, bootstrapping, debugging, tracing, breakpointing, disassembling, cross assembling, meta compiling, and calling back and forth with C code:

purpose: x86 assembler

https://github.com/openbios/openfirmware/tree/master/cpu/x86

purpose: From Forth, call the C subroutine whose address is on the stack

https://github.com/openbios/openfirmware/blob/master/cpu/x86...

purpose: Tools for creating disembodied assembly code sequences

https://github.com/openbios/openfirmware/blob/master/cpu/x86...

purpose: Forth access words for special 386 registers

https://github.com/openbios/openfirmware/blob/master/cpu/x86...

purpose: After a breakpoint, displays a backtrace of C stack frames.

https://github.com/openbios/openfirmware/blob/master/cpu/x86...

purpose: 386 disassembler.

https://github.com/openbios/openfirmware/blob/master/cpu/x86...

purpose: Access to I/O ports and physical addresses under Linux

https://github.com/openbios/openfirmware/blob/master/cpu/x86...

https://github.com/openbios/openfirmware/blob/master/cpu/x86...

    \ One of the very best features of FORTH assemblers is the ability
    \ to use structured conditionals instead of branching to nonsense
    \ labels.
    : IF
       >MARK swap
       long-offsets @  if
          dup h# eb =  if
             drop h# e9 asm8,
          else
             prefix-0f  h# 10 + asm8,
          then
          real?  if  0 asm16,  else  0 asm32,  then
       else
          ASM8,  0 asm8,
       then
    ;
    : THEN    >RESOLVE   ;
    : BEGIN   <MARK   ;
    : UNTIL   <RESOLVE   ;
    : AHEAD   0EB IF          ;
    : ELSE    AHEAD  BUT   THEN   ;
    : AGAIN   0EB UNTIL   ;
    : WHILE   IF   BUT  ;
    : REPEAT  AGAIN   THEN   ;

    \ These conditional test words leave the opcodes of conditional
    \ branches to be used by the structured conditional words.
    \   For example,
    \    5 # ECX CMP   0< IF   EAX EBX ADD   ELSE   EAX EBX SUB   THEN
    \    begin   dx al in   tbe # al and   0<> until
https://github.com/openbios/openfirmware/blob/master/cpu/x86...

    \ Some x86 assembler macros to make it easier to write x86 early
    \ startup code.  There are macros to set MSRs to specific values,
    \ to set and clear individual MSR bits, to read and write PCI
    \ configuration registers with the common CF8/CFC mechanism,
    \ and to read and write I/O ports.

    \ The code keeps the MSR register number in %ecx, the low 32 bits
    \ of the value in %eax, and the high 32 bits in %edx, consistent
    \ with the way the rdmsr and wrmsr machine instructions work.

    \ The bitset and bitclr operations work on %eax, and the -hi versions
    \ work on %edx.

    \ The I/O port operations also leave the data in %eax, so you can
    \ use bitset and bitclr with them too.


> I see a Forth reference about once per month on HN but nothing in developer-specific forums, so I have to assume Forth is dead.

Depends on your definition of dead |1].

> Is there some use case that only Forth can satisfy?

Interactive programming with really low resources, or the advantage of having an interpreter that you can tune and adapt at will.

[1] https://forth-standard.org/


I’m in the middle of reading it (a paperback version) this week coincidentally. Seeing this on HN just now made me do a double-take.


Sourceforge is still around?


They should specialize in Forth hosting and call it Forthsourge.


are there any webprojects or cgis in forth to study?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: