1. 39

Unison keeps code in an append-only local database where code is addressed by a hash code of its AST. Two functions that are identical up to a change in bound variable names hash to the same value and are considered “the same function.”

It also has a way of integrating git branches and pull requests inside the same code base, where you can have multiple branches of the same repository cloned into different namespaces, then call each of them within the same REPL session. There are some interesting implications!

  1.  

  2. 4

    This reminds me of some ideas that Joe Armstrong had:

    https://erlang.org/pipermail/erlang-questions/2011-May/058768.html

    1. 1

      Indeed, I see definite similarity.

      there are no “open source projects” - only “the open source Key-Value database of all functions”

      If you look at the github URL + function hash as a composite key, then we almost have that. (Though such a composite key still allows redundancy where the same function appears in multiple github projects.)

    2. 2

      These ideas seem applicable to Forth-like languages too — traditionally, Forth code compiles into an append-only heap. I’ll have to think about this.

      1. 1

        The idea of identifying code by structure globally is fascinating but how does this accommodate abstraction? The hallmark of abstraction is an interface that can be implemented in different ways (and trade-offs). This does not seem possible (or encouraged) here.

        1. 3

          I think Unison has four ways to support polymorphism. (Though this is my novice-level interpretation so I might not get all the nuances.)

          First and most visible, Unison is an FP language with functions as first class values. So you can always pass in a function (as long as the function’s type is acceptable) that contains a specific variation of behavior.

          Second, functions can be polymorphic in their types.

          Third, Unison has an effects system (called “abilities”) where the effect definition is an abstract interface and specific implements can vary. Abilities occupy a special position in the syntax and semantics though, so not everything can be abstracted this way.

          Fourth, there is work going on now about how to incorporate typeclasses.

          So it might be that there is a surplus of abstraction techniques!

          1. 1

            As I recall, it’s approach to abstraction is similar to Haskell’s; type-wise, if function a has the same types as function b, then the functions are treated the same to the rest of the code using them. Haskell seems to do ok with abstraction, but maybe I’m misinterpreting you.