Retro is an interesting Forth platform because it has numerous features not present in more traditional Forth systems, such as the ability to create closures and first class literals while still maintaining compactness that would be expected of a Forth system.
It was originally meant for desktop scripting but has been ported to tiny devices like microcontrollers.
It is worth a look if you are even mildly curious about Forth
I would love a Forth with a type system. I don't know if that is heretical, but I'd love a higher-order type system for when you are several meta-words deep. Disclaimer: I've only used Factor on Project Euler problems.
Might not be quite what you're thinking of, but for typed Forth, there's StrongForth, which is statically typed. I wrote a Forth-based scripting system for Dreamcast homebrew, and used StrongForth's type system in it. I would run and edit the scripts live on the console, and the static typing was a big help to prevent errors that could crash the system (since the game ran under a single process, and did not use the MMU).
Personally I prefer Dr. Becher's follow-on project, StrongForth.f, which is just a library to load into a standard system like gforth (which is probably in your OS's package repo).
> I would love a Forth with a type system. I don't know if that is heretical [...].
Jack Woehr (of the ANS Forth committee) and Mitch Bradley (of Open Firmware fame) think it’s old hat[1], so guess not. (They also think it probably won’t work though.)
In general, people have tried a lot of times; there’s a number of postfix Lisps with type systems—Kitten mentioned elsethread, ActorForth[2], etc.; a low-level Forth, as in identidally sized cells on stack and no automatic memory management, I don’t think has been done to completeness (IIRC either Forth, Inc. or MPE have a standing offer for any that’s able to process their legacy code even just for stack checking), but then C wouldn’t be complete by that standard either (and Rust far too limiting).
Honestly I’m not sure how well it would work. In C, you get a great deal of utility out of compound types, and classic cell-oriented Forth kind of sucks at even mildly complex datastructures—they are certainly possible, but being unable to manipulate them as values on the stack makes things quite unnatural. (And that’s where I draw the line between Forths proper and “postfix Lisps” like PostScript, Joy, and Factor, as such manipulation doesn’t seem feasible without some sort of automatic memory management.)
I've only used Forth briefly, but one of the things I loved about it is that it almost has the opposite of a type system - everything is just 'memory' - but you just build words around that and barely even notice.
I've seen people recommend C as a way to "get closer to the hardware", but I think we all know that that's not really been a thing for longer than most of us have been alive. Forth, though? Maybe!
MStoical[1] is a fork of a fork of Stoic[2], which has toggle-able runtime type checking. It supports the following parameter types for each parameter (see the docs)
short long
----- ----
* bah ( don't care )
f float
s string
r reference
p pointer
io stream ( file / socket )
a array
h hash
c clause
I'm not a C programmer, and it took a fair bit of help from folks here on HN to get it compiling (it was forked from a 20 year old C source), for which I'm grateful.
I'm slowly working on one. The repo is a mess and the examples don't actually run (they're sketches of where I'm trying to go; the unit tests in the Zig source are a better idea of where I'm actually at so far), but I'm attempting to slap a "minimum viable "does this shape align with this other shape" type of type system" onto a loosely-FORTH-inspired stack machine with some modern amenities with Gale. https://sr.ht/~klardotsh/gale/ (or for the GitHub fans, https://github.com/klardotsh/gale)
When I'm working on something like that I tend to literally have a directory called sketches/ in the root of the repo, a few of which will currently run, a few more of which -did- run at some point, and then the rest are more thinking out loud than anything else.
Calling it that straight out the gate reminds me not to worry too much about it and just get the thing down into a file for future reference, if I derive a 'real' version of anything in there that I intend to both run now and to stay running I'll put that somewhere else (and leave the sketch in place for historical curiosity purposes).
There are a few stack-based languages that you might enjoy. Pop-11 is a typed open stack language roughly at the level of Common Lisp. RPL (originally "reverse Polish Lisp") is an interpretive stack based language on some HP calculators.
We need a new name for this kind of thing[1] because it's not really literate programming - you can't re-order your code blocks in the literate source files and have them come out in the right place in the code source files which is, I think, a key part of it being literate programming. Don't get me wrong - I use this a lot with the various *occos - but it needs a name of its own.
[1] Assuming we don't already have one that I've missed.
My take on this is that TANGLE-style reordering is much less necessary now that we have ubiquitous forward referencing and variables that can be declared in the middle of a function. If you read Knuth’s Pearls example[1], a lot of the code blocks would be separate constants or functions; but he’s using WEB to inline them to compensate for the one-pass compiler and associated limitations. In a modern language for the most part you already have the freedom to order your code blocks however you want, and you don’t need a separate tool to make this possible. At that point the main advantage that the technique offers is particularly extensive and well-formatted comments.
McIlroy also touches on this in his review, though from the other direction:
> Perhaps the greatest strength of WEB is that it allows almost any sensible order of presentation. Even if you did not intend to include any documentation, and even if you had an ordinary cross-referencer at your disposal, it would make sense to program in WEB simply to circumvent the unnatural order forced by the syntax of Pascal.
I was vaguely under the impression that Forth only dereferenced words from the dictionary into functions when you call them, but I admit I haven’t actually used it. In that case, being able to reorder your code so you can give the overview of what you’re trying to do before diving into the finer details of its internals does seem like a great help!
Sadly, I think the new name for this kind of thing has been "literate programming" for the past 20 years at least, while the literate programming that Knuth described has been renamed something like "the literate programming that Knuth described".
I think Docco was when that approach acquired some kind of popularity? So 2010 or so[1].
Of course Haskell has had its “literate format” since forever (ETA: the Haskell 1.2 report[2], dated March 1992, has a description in an appendix), and it became mildly popular for Haskell blogging when blogs caught on, but its name was always accompanied by a side note that in Haskell you don’t really need to reorder things (kind of true).
I recall, on first encountering Literate Haskell at some point after 2010, mentally comparing it to something I thought I recalled from earlier in the perl ecosystem (on top of being vaguely aware of Knuth's stuff, although I hadn't actually read up on it at that point - at this point I have a copy on my desk).
POD? I’ve only encountered people using it to embed manpages into their single-file scripts, even if it turns out that the documentation[1] doesn’t consider this the canonical use case and demonstrates something much more like LH. But then I’ve never done much Perl.
It's in the interesting overlap space with Notebooks. I don't know if that is a name you'd want to reuse for "non-reorderable literate programming", especially as more Notebooks move the other direction and support cell reordering.
> The literate coding system they're using (Unu) is a bit primitive, but it's GREAT that they're using one at all.
There’s an old tradition of annotating Forth code with documentation: code would go into even-numbered 64x16-character “blocks”, accompanying documentation into odd-numbered “shadow blocks”, and on e.g. a VGA you could even view them at the same time.
I find it hard to get into Forth, in part because every time I ask a Forth developer what they use Forth for, they simply say "writing my own Forth". It seems to be Forths all the way down. When I tried to write a piece of software in it, a basic TODO list app, and had issues with dynamically sized arrays, every Forth programmer I asked said "this task is not suited for Forth". Okay, then what is? Very strange
I mean fair enough but a lot of Forth fans try and sell it as a general purpose programming language and even compare it to things like LISP, but it's obviously really not, it's very domain specific.
FORTH isn't necessarily domain specific when you start a project, but it always is by the time you finish.
In that sense it is actually much more like LISP than most other languages, it is scaffolding that allows you to build a DSL (in FORTH probably in the most literal sense of the word(s)).
I've never used any other language that has this property, and I've used C, C++, C#, Haskell, Java, Javascript, Rust, Python, Mathematica. All of them have easy to use dynamically sized arrays
C arrays are syntax sugar over pointer arithmetic and defining up a handful of FORTH words to do the same thing (plus a bump allocator) is sufficiently trivial that putting it in core would be weird, because -in general- FORTH programs are low level enough you wouldn't have -many- dynamic arrays so having separate words for each one often makes a lot of sense.
This isn't to say that FORTH is going to be particularly -suited- to writing something like a todo app, and I'm having the sort of day where I can see the rough shape of the required code in my head just fine but cannot for the life of me convince my fingers to produce you a useful example, but it's very much doable.
Well then it's weird that no Forth programmer I've asked can produce such an example when I ask them, and instead tell me to use another programming language
They probably tell you to use another programming language because if that's the kind of questions you are asking for your todo list application using another programming language is likely going to work better for you. It's a bit like asking to provide the schematics for a particular type of wrench when your job is to put a nail in the wall.
For instance, in computer science "literal constant" has a very specific meaning.
Python calls things "literals" that are obviously not literals; for instance [1, 2, 3] is actually a constructor which allocates a new li^H^Harray each time it is evaluated.
A true literal does no such thing; its syntax retrieves an object which has been placed into the program image; it typically exists before the program even starts.
Programs depend on the semantics of [1, 2, 3] making a new object each time; a Python compiler cannot just deduce that because all arguments are constants, it can be turned into a literal.
You don't want to learn computer science terminology (or computer science at all) from Python.
In general, in a discussion about or adjacent to programming language design, people will tend to expect 'list' to be used to mean a data structure that behaves like a singly linked list ala lisp's cons cell based list data structures.
The programming styles list-first and array-first languages encourage are sufficiently completely different that using them interchangeably tends to be a really bad idea, and honestly python's arrays being named that way irritates me even if I don't consider 'this irritates me' to be a criticism per se.
I am so happy to see Charles is still releasing new versions. Has a lot of interesting designs on functional programming using the stack. You can see the inspirations from joy and the portable virtual machine is well designed and easy to understand. This is a great project to study and experiment with.