The Namingless Programming Language
github.com
github.com
What's going on here is that there are actually two operations, where one is spelled `_` and another is spelled every other character. The program starts with an empty array of trees (what is called the "current branch" here), and any character other than `_` appends to that array, while `_` takes the last element and does something accordingly. And that's a common theme for light-hearted esolangs: that single operation encodes a lot of semantics so that there are in fact multiple super-operations described with that operation. It is much harder to design a minimal esolang without no obvious super-operation structures.
One thing less obvious from the description is the Turing completeness. I think it is not, because the actual computation is only possible via `_`, but the number of `_` operations is set from the initial program. If `_` can be executed undefinitely, it is relatively easy to construct a program that replicates itself (cf. quine) in the current branch and `_` keeps running the replicated program over and over. Alternatively `_` can have a super-operation that can execute `_` multiple times, for example by interpreting a particular branch as a program [1]. But as it stands, it doesn't seem to have any sort of looping. A simple fix would be to assume an infinite number of `_` following the input program.
[1] This sort of iteration is not very uncommon in esolangs. See, for example: https://esolangs.org/wiki/Muriel
Another fix I believe sufficient (and perhaps a bit more interesting) would be an operation to exchange `left` and `right`, so that the program is replaced with the data, and vice versa.
Or academic computability analysis. Raúl Rojas's paper on the Z3 comes to mind. A neat trick.
"The datastructure" is cons
Trying hard to avoid names (by, say, eta reduction in Haskell) is a fun excercise that rarely leads to more understandable programs.
Almost all time spent improving names is worth it. The only exception might be one-off scripts.
Agreed, but if you're writing in J, Forth or Factor then it's hardly likely to make it into production anyway.
Still tempted to use the flag link though. So maybe that's actually a compliment to the author in a weird way.
From my own experience, working on "silly" projects like this, with severe artificial constraints for example, can be quite interesting and challenging and lead to lessons learned that can be applied to real projects later.
So for the author, it might have been quite constructive indeed.
You can showcase the same programming techniques in a toy compiler as you would in a production-level system.
But you may not get there because you're drowning in practical matters instead of getting to the point of innovating.
And hacker news is where I come to read about random projects like this.
Decoupling and abstraction via naming is fundamental to both computation and data storage.
While I don't think Unison to become the next big thing(TM), that's irrelevant to what Unison claims in my understanding. You can always name any term as in most other languages, and in fact you can also have a nominal type as well (cf. `unique type`). So you can distinguish multiple terms with otherwise structurally equivalent representations, and use names to refer to them.
The obvious following question is: what is different then? In conventional languages where you define a function `f(x, y) = x + y`, `f` is engraved into some sort of namespace, like a symbol table of the static or shared library file. That obviously implies a possibility of collision, and a common remedy is to have multiple or nested namespaces to separate them, but that doesn't fully fix this issue because such separation is not automatic. In Unison everything is first automatically named according to a hash of its implementation, and then can be aliased to other names. So the collision is impossible by default. Unison still has a type system, so I believe decoupling is still possible by multiple terms with the same type but different implementations (thus different hashes).
The implementation is supposed to be hidden and changeable independently of the interface and independently of clients.
If I am coupled to the implementation, it's not an abstraction.
More commonly, and in my opinion, more reasonably, any abstraction involves a trade-off. Some abstractions can be quite leaky but darn easy to use. Others may be less leaky but difficult to use (or misuse, depending on your view). There is no non-leaky abstraction here. Once you've chosen a trade-off and thus abstraction, you are still not entirely free from coupling for the aforementioned reason, but can enjoy some level of freedom thanks to the trade-off made. Unison is no different from other conventional languages in this sense.
And pronounced underbar, as in where you need to drink yourself when programming in this language
It goes to unnecessary lengths to avoid naming the output files themselves.
Also there's a significant copout that the language allows you to operate on explicitly named files.
This makes it possible to have named "variables" by writing whatever you need to keep into named files.
The stack of trees is interesting.
Also using _ to execute top thing on the stack is a cool concept that avoids need for quoting anything because nothing executes by default. Although you still need to quote _ itself as U_ if you don't want it to execute and the lang doesn't have subroutines yet so to make them sensible some quoting will probably still be necessary.
There's also a weirdness where strings are always compared as if they were numbers. At least according to the docs.
It's like having to use an explicit call operator for everything (call + (call * 2 2) (call * 3 3)). You do that for applicators other than call like map or apply. Call is special, so you don't give it a name; it is named by the absence of a name.
You want the actual operators like ^ and H to be implicitly active. When you want ^ and H to just be the literal characters themselves, that's where some quoting syntax should be applied.
I was amused until I read this.
So much pain owes its existence to special characters in filenames.
Don't do it.
The author seems to have thought it through!
So it’s basically lisp, with either lists or atoms, at the char level
Keep naming types, but abandon the idea of variable names.
I think this gets repeated a bit too often. I don't find naming difficult personally, and I think I'm not alone.
You can actually practice this by thinking of concepts, entities, their relations and the way they intertwine.
(aside) “You may fire when ready.”
https://en.wikipedia.org/wiki/Esoteric_programming_language#...