
Thoughts on Forth Programming - andyjpb
http://www.call-with-current-continuation.org/articles/forth.txt
======
markus_zhang
Can you please give some examples on those who are extremely productive using
FORTH? I'm intrigued. I think FORTH could be very useful to someone who
prefers to work alone or in small group, but I'm not sure how do they use it
in daily life.

~~~
lukego
Mitch Bradley. He wrote the firmware for Sun machines, made an IEEE standard
of it, open sourced it for OLPC. Highly productive guy.

Interview with him seems to have disappeared from the web?
[http://mitchbradley.blogspot.com/2010/08/open-firmware-
and-o...](http://mitchbradley.blogspot.com/2010/08/open-firmware-and-one-
laptop-per-child.html?m=1)

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

[https://web.archive.org/web/20120118132847/http://howsoftwar...](https://web.archive.org/web/20120118132847/http://howsoftwareisbuilt.com/2008/03/27/interview-
with-mitch-bradley-firmware-olpc/)

I've previously posted some stuff about Mitch Bradley -- I have used various
versions of his ForthMacs / CForth / OpenFirmware systems, and I was his
summer intern at Sun in '87!

Mitch is an EXTREMELY productive FORTH programmer! He explains that FORTH is a
"Glass Box": you just have to memorize its relatively simple set of standard
words, and then you can have a complete understanding and full visibility into
exactly how every part of the system works: there is no mysterious "magic",
you can grok and extend every part of the system all the way down to the
metal. It's especially nice when you have a good decompiler / dissassembler
("SEE") like ForthMacs, CForth, and OpenFirmware do.

[https://news.ycombinator.com/item?id=9271644](https://news.ycombinator.com/item?id=9271644)

>DonHopkins on Mar 26, 2015 | parent | favorite | on: The Elusive Universal
Web Bytecode

>The other "universal bytecode" that came out of Sun and actually has seen a
lot of use is Mitch Bradley's Open Firmware Forth based boot ROMs, used by
Suns' 68k, SPARC and x86 boxes, Apple's PPC Macs, IBM, ARM, OLCP XO-1, and
many other systems.

>[http://en.wikipedia.org/wiki/Open_Firmware](http://en.wikipedia.org/wiki/Open_Firmware)

[https://news.ycombinator.com/item?id=12240478](https://news.ycombinator.com/item?id=12240478)

DonHopkins on Aug 7, 2016 | parent | favorite | on: “EFI? Intel has been
trying to shove that down ou...

>Mitch Bradley originally developed a Forth system at Sun for use diagnosing
and developing hardware, by burning it into ROM and running it via a serial
port.

>It was based on Langston and Perry's Forth-83, and had a meta compiler that
could target different word sizes and architectures. He made it even more
architecture and word size independent, implemented interactive top level
loops and conditionals, emacs-like line editing, all kinds of low level device
drivers and testers that ran in stand-alone mode, and many other features,
including full 16 and 32 bit support with a vocabulary for writing word size
and endian independent code.

>He ported Sun Forth to 68K and SPARC Sun workstations, as well as the Amiga
and other systems. It ran in both stand-alone mode (from disk, tftp or ROM),
or under Unix. Under Unix, it could dynamically relocate and link in Unix
libraries, and you could call back and forth between Forth and C.

>Sun Forth eventually evolved and standardized into the Open Firmware [1],
whose purpose was to support machine independent byte code [2], so plug-in
hardware cards could include ROMs with Forth byte code drivers that ran on
68K, SPARC, x86 and other systems.

>Sun shipped it with the SPARC workstations, Apple adopted it and shipped it
on their PowerPC Macs, IBM shipped with their POWER servers, and Mitch worked
directly with the OLPC project extending OpenFirmware to support the OLPC XO-1
Children's Computer secure and power efficient hardware. [3]

>>OLPC Wiki: Open Firmware

>>Open Firmware is the hardware-independent firmware (computer software which
loads the operating system) that the XO runs.

>>It was developed by Mitch Bradley at Sun Microsystems, and used in post-
NuBus PowerPC-based Apple Macintosh computers (though it has been dropped with
Apple's transition to Intel processors), Sun Microsystems SPARC based
workstations and servers, IBM POWER systems, and PegasosPPC systems, among
others. On those computers, Open Firmware fulfills the same tasks as BIOS does
on PC computers.

>>For example Fedora and Debian use the YaBoot BootLoader for Open Firmware.

>>The Open Firmware user interface includes a FORTH-based shell interface.
FORTH is a powerful high level language that is remarkably compact. A complete
Forth development environment including compiler, decompiler, assembler,
disassembler, source level debugger, and assembly language debugger is present
in the XO boot ROM (SPI FLASH). With the Open Firmware Forth system, you can
directly access all of the hardware devices on the XO, use built-in functions
like selftest diagnostics and games, and even write complete applications,
without needing any external tools. The bulk of Open Firmware is written in
Forth, so the source level debugger can be used to debug Open Firmware itself.

>[1] [http://www.openfirmware.info](http://www.openfirmware.info)

>[2]
[http://www.openfirmware.info/FCODE_suite](http://www.openfirmware.info/FCODE_suite)

>[3]
[http://wiki.laptop.org/go/Open_Firmware](http://wiki.laptop.org/go/Open_Firmware)

[https://news.ycombinator.com/item?id=15040859](https://news.ycombinator.com/item?id=15040859)

>DonHopkins on Aug 17, 2017 [-]

>Emacs qualifies as a window manager in my book! ;)

>That code you linked to is from Mitch Bradley's "Forthmacs", which ran on Sun
workstations including 68k i86 and SPARC, and also Atari ST, Mac and other
systems. He developed it into the "Open Boot ROM" architecture, which was used
in Sun workstations and Apple PowerPC Macs as well as the OLPC children's
laptop.

>[https://github.com/ForthHub/ForthFreak/blob/master/Forthmacs](https://github.com/ForthHub/ForthFreak/blob/master/Forthmacs)

>[https://en.wikipedia.org/wiki/Open_Firmware](https://en.wikipedia.org/wiki/Open_Firmware)

>[http://wiki.laptop.org/go/Open_Firmware](http://wiki.laptop.org/go/Open_Firmware)

>On SunOS, Forthmacs had a library clink.f with the ability to dynamically
relocate and link Unix libraries so that you could call them from Forthmacs,
pass arguments on the stack, etc. SunOS didn't actually support shared
libraries or dynamic address relocating at that time, so Forthmacs simply ran
the Unix linker utility to create a file with the library relocated to the
desired address space in the FORTH dictionary, and then read that file into
memory, define its symbols in the FORTH dictionary, and let you access its
variables and call its functions directly from FORTH!

>That's how Mitch originally integrated MicroEmacs with Forth to make
Forthmacs, and how I later integrated "uwm" into FORTH: I refactored uwm so
instead of having an event loop in the main function, it was a library that
could be called by FORTH, which would link the library in and run the main
loop itself, calling into the library as needed to initialize and handle
specific events (_uwm_init, _uwm_poop).

>[http://www.donhopkins.com/home/archive/piemenu/uwm1/fuwm-
mai...](http://www.donhopkins.com/home/archive/piemenu/uwm1/fuwm-main.f)

>Here's the glue that links in the uwm library from fuwm.out:

>[http://www.donhopkins.com/home/archive/piemenu/uwm1/load-
fuw...](http://www.donhopkins.com/home/archive/piemenu/uwm1/load-fuwm.f)

    
    
        .( Loading...) cr
        requires tasking.f
        requires uwm.f
        requires clink.f
        .( Linking...) cr
        "" fuwm.out clink
        .( Linked!) cr
    

[https://news.ycombinator.com/item?id=17480298](https://news.ycombinator.com/item?id=17480298)

>DonHopkins on July 7, 2018 | parent | favorite | on: Tali Forth 2 for the
6502

>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](http://www.donhopkins.com/home/archive/forth/supdup.f)

>Here's some Forth 68k assembler that draws lines on a weird Sun-2 CGONE
graphics board.

>[http://www.donhopkins.com/home/archive/forth/cg/bline.f](http://www.donhopkins.com/home/archive/forth/cg/bline.f)

>Mitch Bradley's 68k forth lets you use interactive conditionals and loops in
the top level outer interpreter!

>I think he wrote a paper about that feature, which I might be able to dig up
... Here's something related he wrote about refactoring the outer interpreter,
but not what I'm thinking of:

>[https://groups.google.com/forum/#!topic/comp.lang.forth/lKQj...](https://groups.google.com/forum/#!topic/comp.lang.forth/lKQjcJL_o54)

>avhon1 on July 7, 2018 [-]

>> Does it include a FORTH 6502 assembler written in FORTH?

>[https://github.com/scotws/TaliForth2/blob/master/docs/manual...](https://github.com/scotws/TaliForth2/blob/master/docs/manual.adoc)

>>Currently, there is no assembler included. The plan is to include a simple
assembler based on Simpler Assembler Notation (SAN).

>It does include a disassembler:
[https://github.com/scotws/TaliForth2/blob/master/docs/ch_dis...](https://github.com/scotws/TaliForth2/blob/master/docs/ch_dis..).

>The author has written a 6502 assembler in gforth:
[https://github.com/scotws/tasm65c02](https://github.com/scotws/tasm65c02)

>Here is a document describing the notation:
[https://docs.google.com/document/d/16Sv3Y-3rHPXyxT1J3zLBVq4r...](https://docs.google.com/document/d/16Sv3Y-3rHPXyxT1J3zLBVq4reSPYtY2G6OSojNTm4SQ/edit#heading=h.ik059qk0tz7r)

>DonHopkins on July 7, 2018 [-]

>I got a quick reply from Mitch Bradley!

>Yes I wrote a paper but I probably can't find it. The easiest place to look
would be in the Open Firmware source.

>[https://github.com/MitchBradley/openfirmware/blob/master/for...](https://github.com/MitchBradley/openfirmware/blob/master/forth/kernel/kernel.fth#L771)

>The magic is all in +level and -level. Search for those in kernel.fth to see
other places they are used to achieve a similar effect, e.g. in abort"

>For an alternative but effectively equivalent formulation, see:

>[https://github.com/MitchBradley/cforth/blob/master/src/cfort...](https://github.com/MitchBradley/cforth/blob/master/src/cforth/forth.c#L652)

>and

>[https://github.com/MitchBradley/cforth/blob/master/src/cfort...](https://github.com/MitchBradley/cforth/blob/master/src/cforth/control.fth)

~~~
lukego
I love your posts about this stuff :)

I was also an "intern" of sorts for Mitch as recently as 2009 or so. I wrote
the audio driver for OLPC XO 1.5 and went to Taipei to help with the bringup.
I was amazed to watch Mitch using Forth to interactively tweak the DDR memory
settings, find bugs in the motherboard, and find bugs in the CPU which was a
godawful x86 from VIA that had seemingly only been debugged enough to boot
windows :)

~~~
DonHopkins
That must have been a fun and unique opportunity! His programming and
debugging process has to be seen to be believed. OpenFirmware is definitely a
highly polished work of love. Its well-commented and meticulously organized
source code reads like fine literature or classical music! Stuff like the
metacompiler and kernel, for example:

[https://github.com/MitchBradley/openfirmware/blob/master/for...](https://github.com/MitchBradley/openfirmware/blob/master/forth/kernel/metacompile.fth)

[https://github.com/MitchBradley/openfirmware/blob/master/for...](https://github.com/MitchBradley/openfirmware/blob/master/forth/kernel/kernel.fth)

------
bcheung
Forth style is great for writing but very hard for reading. I'm playing around
with the idea that you use a Forth-like language to interactively develop
code. The steps you perform become AST nodes. Then when you want to read it,
it comes out in another form.

This is more ideal because it is more interactive and you can see the
immediate result every step of the way. This is different than writing
traditional code because sometimes variables and functions are not returning
what you expect and you are working blind under the wrong assumption. You then
need to debug it to find out where the value is not what you expected and why.
Forth wins for writing in my book because you have immediate feedback which
lifts some of the cognitive load and saves time on debugging.

However, the problem with reading Forth is that it forces the cognitive load
of having to know what is on that stack at every moment. If you make one
little mundane mistake then it completely changes the meaning of the code and
you get lost. So for reading I think you need to read it in the more
traditional language forms.

Some kind of IDE could let you interactively write. But once you save it, you
can read it in a more traditional prefix / infix syntax.

~~~
yiyus
What I would like to have (and looks quite similar to what you are describing)
is some APL interpreter (or J or K...) with an RPN input method. The idea
comes from HP calculators, where you use RPN to "build" algebraic expressions.

I have many ideas for such a system, but it will require much experimentation
to get it right and, at this moment, is just vaporware.

~~~
9214
Have you seen Lang5? It's a stack-based array language.

[http://lang5.sourceforge.net/tiki-
index.php](http://lang5.sourceforge.net/tiki-index.php)

------
it
This quote stood out as sounding quite far-fetched: "on many CPUs the
interpreter consists of two or three machine instructions". Can someone point
to an example?

~~~
DonHopkins
FORTH has both an "inner interpreter" and an "outer interpreter" (aka the
compiler, but that also works interactively like an interpreter).

The inner interpreter is the thing that threads between words, and is
typically an assembly function named "NEXT", which can be just a few
instructions. Here is the FIG-FORTH 6502 implementation of "NEXT" (which is a
bunch of instructions since the 6502 has 8 bit registers and simple addressing
modes):

[https://ksquiggle.neocities.org/ff6502.htm](https://ksquiggle.neocities.org/ff6502.htm)

    
    
        0122  0244            ;
        0123  0244            ;     NEXT is the address interpreter that moves from
        0124  0244            ;     machine level word to word.
        0125  0244            ;
        0126  0244  A0 01     NEXT   LDY #1
        0127  0246  B1 AE            LDA (IP),Y    Fetch code field address pointed
        0128  0248  85 B2            STA W+1       to by IP
        0129  024A  88               DEY
        0130  024B  B1 AE            LDA (IP),Y
        0131  024D  85 B1            STA W
        0132  024F  20 6F 02         JSR TRACE   Remove this when all is well
        0133  0252  18               CLC           Increment IP by two
        0134  0253  A5 AE            LDA IP
        0135  0255  69 02            ADC #2
        0136  0257  85 AE            STA IP
        0137  0259  90 02            BCC L54
        0138  025B  E6 AF            INC IP+1
        0139  025D  4C B0 00  L54    JMP W-1     Jump to an indirect jump (W)
    

(This is actually self-modifying code that write the indirect address to jump
to into W, the operand of an indirect JMP instruction at W-1, then does an
absolute JMP to W-1 to jump indirect through W.)

Some CPUs can implement "NEXT" in one or only a few instructions, and FORTH
implementations can use "indirect threading" (like the above 6502
implementation that indirectly jumps through each word's CFA (Code Field
Address)) or "direct threading" where the word pointers refer directly to
code, or they can even compile words directly to machine language instructions
instead of threaded pointers (so there's effectively no inner interpreter,
just direct machine language calls), and in that case they can even inline
"NEXT" at the end of every word definition for speed, instead of jumping to a
global "NEXT" implementation (subroutine threaded machine code).

[https://en.wikipedia.org/wiki/Threaded_code#Threading_models](https://en.wikipedia.org/wiki/Threaded_code#Threading_models)

And there are other possible variations and hybrid combinations, like
"subroutine threading" or "token threading", which you might want to use to
implement FORTH systems in C or other higher level languages, using function
pointers (like CForth) or switch statement tokens for built-in primitives
(like machine-independent OpenFirmware byte code):

[https://github.com/MitchBradley/cforth](https://github.com/MitchBradley/cforth)

[https://www.complang.tuwien.ac.at/forth/gforth/Docs-
html/Dir...](https://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Direct-
or-Indirect-Threaded_003f.html)

The outer interpreter is the parser and compiler, which is written in FORTH,
and includes a bunch of words, but is extremely simple (and extremely
extensible) compared to other language interpreters. The outer interpreter can
be in interpret or compile mode (controlled by a variable called "STATE"):
when you're typing expressions interactively in interpret state, it executes
them immediately, but when you start a word definition (with ":") it goes into
compile state and compiles the words instead of executing them.

Except that in compile mode it does execute specially marked "immediate"
words, with which you can implement control flow and macros. There are
immediate words [ and ] that switch between compile/interpret states, so in
the middle of a word definition you can pop out into interpret mode and
execute arbitrary computations (like macros or meta programming), then pop
back into compile mode. For example you could compute a number, and then
compile it as an inline literal!

And then there's <builds and does>, which are word defining words, that let
you do certain kinds of meta-programming, implement your own domain specific
languages, data types, object systems, and extend the FORTH interpreter and
compiler in FORTH.

[http://www.forth.org/svfig/Len/definwds.htm](http://www.forth.org/svfig/Len/definwds.htm)

>It has been said that one does not write a program in Forth. Rather, one
extends Forth to make a new language specifically designed for the application
at hand. An important part of this process is the defining word, by which it
is possible to combine a data structure with an action to create multiple
instances that differ only in detail. One thinks of a cookie-cutter; all the
cookies are the same shape but have different-colored icing.

~~~
DonHopkins
Here's a cool dynamic WebAssembly based Forth:

[https://el-tramo.be/blog/waforth/](https://el-tramo.be/blog/waforth/)

>The Interpreter

>The interpreter runs a loop that processes commands, and switches to and from
compiler mode.

>Contrary to some other Forth systems, WAForth doesn’t use direct threading
for executing code, where generated code is interleaved with data, and the
program jumps between these pieces of code. WebAssembly doesn’t allow
unstructured jumps, let alone dynamic jumps. Instead, WAForth uses subroutine
threading, where each word is implemented as a single WebAssembly function,
and the system uses calls and indirect calls (see below) to execute words.

>The Compiler

>While in compile mode for a word, the compiler generates WebAssembly
instructions in binary format (as there is no assembler infrastructure in the
browser). Because WebAssembly doesn’t support JIT compilation yet, a finished
word is bundled into a separate binary WebAssembly module, and sent to the
loader, which dynamically loads it and registers it in a shared function table
at the next offset, which in turn is recorded in the word dictionary.

>Because words reside in different modules, all calls to and from the words
need to happen as indirect call_indirect calls through the shared function
table. This of course introduces some overhead.

>As WebAssembly doesn’t support unstructured jumps, control flow words
(IF/ELSE/THEN, LOOP, REPEAT, …) can’t be implemented in terms of more basic
words, unlike in jonesforth. However, since Forth only requires structured
jumps, the compiler can easily be implemented using the loop and branch
instructions available in WebAssembly.

~~~
arethuza
Someone has done a port of PostScript (GhostScript) to WebAssembly:

[https://chrome.google.com/webstore/detail/postscript-
viewer/...](https://chrome.google.com/webstore/detail/postscript-
viewer/ebpiondkhkldijolgmhfenknngkkjola)

I wonder if NeWS, or something similar, could be resurrected in-browser?

------
cjfd
The main problem with such a stack based language for 'serious' programming
would, I think, be the lack of dynamic allocations. The stack is all nice and
fine if pieces of memory only need to be preserved inside functions and their
children but if memory is to be allocated for an amount of time that is
determined at run time there basically does not seem to be anything to do
that. Any kind of solution to this would probably be pretty convoluted.

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

[https://github.com/openbios/openfirmware/blob/d5cc657ce81c0f...](https://github.com/openbios/openfirmware/blob/d5cc657ce81c0f7d1857b4687766b64d75a4145d/ofw/core/ofwcore.fth#L3449)

    
    
        \ Forth dynamic storage managment.
        \
        \ By Don Hopkins, University of Maryland
        \ Modified by Mitch Bradley, Bradley Forthware
        \ Public Domain
        \
        \ First fit storage allocation of blocks of varying size.
        \ Blocks are prefixed with a usage flag and a length count.
        \ Free blocks are collapsed downwards during free-memory and while
        \ searching during allocate-memory.  Based on the algorithm described
        \ in Knuth's _An_Introduction_To_Data_Structures_With_Applications_,
        \ sections 5-6.2 and 5-6.3, pp. 501-511.
    

Forth systems running on C libraries can also call back to the native
malloc/free implementation, but it's nice to have a pure FORTH implementation
for embedded applications.

~~~
cjfd
Fair enough, sounds like a workable solution.

------
arnautdaniel
Anyone who wants to see a modern forth with elements of common lisp that is
focused on application development should check out Factor.

Concatenative languages are really fun to use once you get over the initial
hump.

[https://github.com/factor/factor](https://github.com/factor/factor)

~~~
upofadown
Factor is a good example of what the writer of the linked article considers:

>...what just ends up being some sort of Lisp with a funny notation.

~~~
vanderZwan
Where do you think Kitten would end up?

[http://kittenlang.org/](http://kittenlang.org/)

------
shrubble
I have been looking at Forth programming and one thing I would like to figure
out is how to use gforth under Linux in a pipeline of shell and awk. I haven't
yet found a practical use for Forth in this environment yet...

~~~
marttt
Maybe Retro forth is worth looking into in this regard (I haven't really used
it myself, but the conception and minimalism around it are really appealing):

[http://forthworks.com/retro](http://forthworks.com/retro)

[http://forthworks.com/retro/book.html#using-in-a-
pipe](http://forthworks.com/retro/book.html#using-in-a-pipe)

------
jancsika
> One such property is the use of reverse polish notation and the lack or
> eschewal of local variables.

What do you gain by eschewing local variables in favor of reverse polish
notation that throws values onto a stack?

~~~
rabidrat
There are two hard problems in computer science: cache invalidation, naming
things, and off-by-one errors. Eschewing local variables means you have fewer
things to name.

~~~
tom_mellior
I never understood the "naming things" part to be about temporary variables.
IMO it's about exported APIs, global identifiers, and especially about finding
resources by some useful name in a distributed system.

In any case, Forth is a language for implementing your own DSLs by defining a
whole bunch of "words" that all need to be named. So it's not like you get
around the _harder_ part of "naming things".

------
nvahalik
> In Forth there is only memory - word and byte-sized cells of storage in
> memory, and stacks. You step down on the level of assembly language which
> may sound daunting, yet gives you full control over every aspect of memory
> layout.

Other than in niche or pet projects, can this even work?

If you deal with any sort of multibyte data like Unicode, doesn’t this become
way harder?

Or do you just punt and use ascii code pages?

~~~
LessDmesg
This can work, but it's incredibly tedious and not worth the trouble. Writing
in Forth is like writing in pure CIL or JVM bytecode (they're both stack
machines like Forth). Sure, you can do it, but if it was so rewarding, people
wouldn't be using Java or C#.

~~~
kick
That's not true at all. I know multiple people who are _incredibly_ productive
in Forth environments, though I don't use it myself. Pretending that it's like
writing in JVM bytecode (despite some overlap between the two) is completely
unfounded.

Your claim that C# and Java won based on merits is similarly unfounded: they
won because they have major corporate backing. There are countless languages
before and after that did what they did, better. Limbo beats Java at almost
everything Java aims to do, for example.

~~~
kabdib
I've met a couple of really good FORTH programmers over the years. They were
humble about it, were also happy to use other tools in their work, and they
just happened to be working on projects that were really good fits for FORTH's
strengths.

I've met a lot more FORTH fanatics, people for whom FORTH was the answer no
matter the problem; people who just would not shut up about how superior and
fantastic it was, and have you seen the light, brother? Okay, most of them
weren't that bad, but a few were (one guy I worked with got fired because (a)
he told his boss that FORTH was all he was going to use, (b) the FORTH runtime
was over half of his code budget and he had kinda been keeping that secret,
and (c) none of that fantastically <insert some adjectives here> FORTH code
was compatible with the ROM it needed to run on . . . so you can imagine that
fun little tete a tete).

Whatever the languages's wins or faults, it's still a great idea to write your
own FORTH at some point. It's a ton of fun, and quite instructive when you've
gotten a fully functional programming environment that fits in a few tens of
kilobytes.

~~~
jacquesm
> I've met a lot more FORTH fanatics, people for whom FORTH was the answer no
> matter the problem; people who just would not shut up about how superior and
> fantastic it was, and have you seen the light, brother?

I've seen exactly one Forth programmer like that, they are simply too rare.
But the stereotype language fanatic is easily recognized in other language
eco-systems, Perl and Rust have a disproportionately high share of this and
I'm sure there are others. Typically this stems from either insecurity or a
lack of exposure to other eco-systems or the drive to create camps of in and
out groups to attempt to gain mindshare.

Very tiring and counterproductive in the long run, I think to some extent this
is what killed Perl, simply that no matter how good the language was/is
regular people simply don't want to be associated with fanatics and recognize
that no tool will ever be perfect.

~~~
roywiggins
I think some of it may come from being forced to use X language, and then
finding Y language, and realizing that it fits your mindset perfectly, and
deciding that everyone using X must be idiots. Ie, these partisans _were_
exposed to other languages, but never particularly liked them, until this new
thing came along that seemed like a revelation. The zeal of a convert, sort of
thing.

I haven't spent enough time with Forth or Rust to say, but I can see why both
of them could seem like that to people. Forth, especially, has a sort of
philosophical/hacker bent that is inherently appealing to a certain kind of
person (including me!). Whereas I can't imagine Java ever winning someone over
like that (though I'm sure it has).

------
markus_zhang
I feel like, from the "individualism" perspective, Forth is really a tool for
hackers.

Hackers usually work alone or in very small groups, and the tools they need
are usually handcrafted. They do not need corporate-level software, and long
do they strive to be left alone, without being bothered.

~~~
Rerarom
What kind of projects are generally done by individuals even inside companies?
I'm thinking maybe some simple device drivers but could be others.

~~~
exikyut
Low-level hardware bringup?

Perhaps the reason this only ever ends up being managed by one or two people
is that >2 people simply do not need to manage the fussy details once they've
been abstracted/normalized out.

Also, I lurked in comp.lang.forth for a week or so a while back and learned
that Mattel were using Forth as a runtime for their toys back in 2004, at
least:
[https://groups.google.com/d/msg/comp.lang.forth/omi6PUvymEE/...](https://groups.google.com/d/msg/comp.lang.forth/omi6PUvymEE/Glm6a5JFxXQJ),
[https://groups.google.com/d/msg/comp.lang.forth/LzOasFOyIMg/...](https://groups.google.com/d/msg/comp.lang.forth/LzOasFOyIMg/6H5XhX5UOxoJ)

~~~
Rerarom
Thanks, I did not know the word bringup

------
skybrian
The classic problem with inventing your own language is that now you can't
understand anyone else. If we're going to have widespread communication then
we need widely-understood languages and libraries. The goal should be to
replicate understanding. We need to evolve a _common_ vocabulary rather than
ending up with nearly as many private dialects as programmers. Publishing
libraries and gaining users for them should be a primary goal.

There are Forth words with generally agreed-on definitions but it seems it's
not designed to grow a large, common vocabulary in the way that modern package
managers enable.

~~~
pavlov
The counterpoint is that every software project of reasonable complexity
evolves its own language anyway.

When that is layered on top of overly generic libraries/frameworks, you may
end up using only parts of the underlying vocabulary. Now the project is stuck
with two vocabularies. Learning the generic one doesn't get you far and may be
actively misleading ("yeah, we never use features X and Y of the framework,
instead we've overridden Z with our own implementation that does all this plus
W").

~~~
skybrian
Yes, that's a problem with code sharing gone wrong. Another problem is
framework churn where popular libraries aren't stable. When good, stable
libraries aren't available then it may be better to reimplement than to use a
bad one.

But these problems are, in their way, a sign of success at the package
management level. If you don't have good package management then people
probably aren't having much success at sharing code.

We should still aim for building and sharing stable, well-understood, high-
quality code libraries. Unfortunately, sometimes the way to get there is to go
through a period of instability.

~~~
eckza
> We should still aim for building and sharing stable, well-understood, high-
> quality code libraries.

And I agree with that 100% - but that isn't the solution to every single
problem. That's all I'm saying.

------
3xblah
[deleted]

~~~
andykx
Have you tried viewing it on mobile? It looks awful.

------
AstralStorm
Ultimately, programming languages lie on a few spectra. Extremes are annoying,
lack of access to them is sometimes too.

The big problem with the extremes especially the lower, is the amount of
discipline they require from the user. If your team has anyone that ignores
this, you get garbage and bugs, which get hard to fix as either the language
constrains you due to structure or the problematic behaviors are depended upon
transparently and this very hard to factor out.

Low level languages make it easier to commit the latter mistake. In higher
level, this usually rears its ugly head as bad design where you have to
replace big chunks of code at the same time, sometimes leaving compatibility
glue. You cannot do that in some of the higher level "discipline" languages or
have to hack it in nasty ways (hey Java and C# with reflection, C and C++ even
with macros; try doing it in Haskell), while in something unstructured you're
up a creek without a paddle...

On the upside, the DIY nature makes it harder to produce bad or any
abstraction, as trying to write anything you do not understand ends poorly.
The problem then with getting the debugger in is that this can let you code
with incomplete understanding and depend on things that are not meant to be
depended upon. Everything becomes an API. That accidental delay in revision x
of hardware? Can't get rid of it. Used a slower bus in the past? Oops.

Defined interfaces are important too. Which is why VHDL and Verilog exist even
in hardware world - and even they are on the soft side of defined.

