đŸ Archived View for dcreager.net âș swanson âș no-names.gmi captured on 2024-05-12 at 15:10:48. Gemini links have been rewritten to link to archived content
âŹ ïž Previous capture (2023-09-28)
-=-=-=-=-=-=-
2023-09-24
One of the points I made in my Strange Loop talk is that a defining characteristic of a stack language is that it doesn't use names to refer to the values that the program operates on.
Concatenative programming and stack-based languages
The first iteration of Sâ was not stack-based, and was instead heavily based on names. For instance, in the name-based Sâ, we had a test case that we could load an empty module. It looked like this:
module empty.load_empty_s0 { $load: containing () receiving ($loaded, empty.s0) { $module = closure containing (empty.s0) -> main; -> $loaded ($module); } main: containing (empty.s0) receiving ($finish) { $return = closure containing ($finish) -> main@exit; -> empty.s0 drop ($return); } main@exit: containing ($finish) receiving () { -> $finish succeed (); } }
Many of the details are irrelevant for this note. But note that values have names (and typically receive their values through a `name = something` statement of some kind). And _blocks_ have names too! There are three in this example: â$loadâ, âmainâ, and âmain@exitâ. (There is a syntax to give named blocks multiple named branches, which isn't shown here. These three blocks all have a single branch, whose name is the empty string.)
Last year I decided to change Sâ to be concatenative.
Should Swanson be concatenative?
In the current stack-based iteration of Sâ, the above test now looks like:
module empty.load_empty_s0 { # loader nil <1 # [] loader :>load (empty) <2 cons <1 # [empty] loader :drop # [empty] enclosed %empty.load_empty_s0 # test && # harness [empty] uncons >1 dropnil # harness empty :drop :succeed }
I'm not describing the syntax here, but note that there are no names, either for values or for blocks! The lack of names for values was very intentional â the primary thought was to replace the âenvironmentâ (a mapping from names to values) with a stack (a list of unnamed values). But in putting this together, it turned out there were no names for blocks either. At first I assumed this was just a oversight. Or maybe not an oversight â something that I would punt on at first. At some point down the line, I would figure how to bring named blocks back into the Sâ syntax. I assumed that this would be necessary to make it easier to write maintainable Sâ code.
But I no longer think that's true! Higher-level languages will have all sorts of named entities that they'll need to track. And the current hunch is that should all be simulated inside of an interpreter for each of those languages. There will end up being various âsymbol tableâ or âenvironmentâ types, as needed by each of those higher-level languages. But Sâ is not higher-level, (now) does not have any names, and we shouldn't spackle them on in attempt to solve some other language's problems.