13 ms·
The Unison language
- cprecioso 7y agoContent-addressed, immutable code? Reminds me of https://thedailywtf.com/articles/the-inner-json-effect https://thedailywtf.com/articles/the-inner-json-effect
- ivanbakel 7y agoReading the tour[1], I got the impression of being struck by something not that surprising, but still fundamentally groundbreaking. Beyond just the idea of a global program store (which I hope has space for some virtualenv equivalent), the cleverness of effect handlers as a first-class language feature is very exciting. Once the type system is more mature, this could easily be the next kind of Haskell - a language which redefines modern ideas of good programming. 1: https://www.unisonweb.org/docs/tour https://www.unisonweb.org/docs/tour
- the_duke 7y agoSince it took me a while to find it, the relevant documentation is under "Abilities and Ability Handlers" [1] [1] https://www.unisonweb.org/docs/language-reference#abilities-and-ability-handlers https://www.unisonweb.org/docs/language-reference#abilities-...
- thesuperbigfrog 7y agoUnison seems to combine ideas from Forth, Haskell, and Clojure's Datomic and stir them together into an interesting mix: Forth ideas: a global dictionary with pre-existing and user-definable words Haskell ideas: functional programming and type signatures of functions / words Clojure Datomic ideas: immutable store of object definitions that append and use references to point to the latest definitions. I am curious how I/O and error handling are done in Unison.
- ivanbakel 7y agoIf you look at the other reply to my comment, someone has linked the Unison docs on their effect handlers implementation - which is what is used for IO, and with any luck, error handling as well. Haskell has several packages for effect handlers, and they're taking off in programming and category theory circles as alternatives to monads for IO. The short summary is that you can write code with side-effects that you don't define the implementation for, and then let call sites handle those effects or defer them.
- alipang 7y agoAlgebraic effect handlers no doubt seem to be the future of getting side-effects under control in programming languages, much like in the way of what immutability has done for data. My (admittedly little) experience with Unison though is that it's far from ready for the spotlight however. Much of the docs 404, and joining their discord mostly resulted in the advice to wait for future releases. I wish Microsoft would invest in something like the koka language https://github.com/koka-lang/koka https://github.com/koka-lang/koka. Perhaps the idea of content-addressable / immutable code could find a place too, but I think it's less critical.
- imglorp 7y agoI've pondered using IPFS as a backend for content-addressable, immutable code blocks. That idea seems to fit in with the concept of structured or syntaxless programming, to assemble blocks into systems. Here's a list of the latter. https://www.reddit.com/r/nosyntax/ https://www.reddit.com/r/nosyntax/
- tasogare 7y ago> I wish Microsoft would invest in something like the koka language Given the ML-like syntax of Unison, it would be nice to see F# taking some of the key ideas.
- pjmlp 7y agoF*, https://www.fstar-lang.org/ https://www.fstar-lang.org/
- pjmlp 7y agoThey already have F* for such type systems. https://www.fstar-lang.org/ https://www.fstar-lang.org/
- rzwitserloot 7y agoKudos to them for not using the buzzword, but if you believe in the notion that 'blockchain is just a fancy buzzword that gives developers the ability to get managers to agree to larger budgets to clean up tech debt', this is.. blockchain programming. One problem I did find: Somewhat deeper into the tour, the tour makes the claim: > a Unison codebase can be versioned and synchronized with Git or any similar tool and will never generate a conflict in those tools. This is pratically speaking of course not true: If you have some unison codebase, whilst under the hood it's all hashes, that doesn't change the simple fact that if 2 people both check out the exact same code, and then both people make a change to how the software operates, where that change is conflicting (say, I make the green 'OK' button now red, and you make it blue), you.. have a conflict. That is a fundamental property of this interaction; no language bells and whistles can ever change this fact. So, what does happen in unison? Is it 'last committer' wins? That'd be a bit problematic. A conflict in your version control system, _IF_ it is representative of the fact that there was an actual conflict (as above with the button and the conflicting colours), is a good thing, not a bad thing.
- steve_taylor 7y ago> It is append-only: once a file in the .unison directory is created, it is never modified or deleted, and files are always named uniquely and deterministically based on their content. That's how conflicts are avoided.
- aidenn0 7y agoSo I append X to my file and you append Y to your file, do we not have a conflict?
- capableweb 7y agoYes and no. Yes as in, if you'd like them to be merged into a new one, then you'll have to resolve a conflict. But no as in, you both appended different data, so you both have new files from the original one, as you're dealing with immutable data.
- blamestross 7y agoAppend only is nice, but I would think a "Garbage Collect" would be useful. Remove all the code not attached to the import tree anymore. Otherwise you will just keep collecting junk forever Honestly git has the problem too, but I expect orphaned/dead code will happen a lot more with this approach.
- SamBam 7y agoGit has this problem only as far as the developer's storage of the history of all files is concerned. That "junk" doesn't remain in the final program. You can have a decades-old git repository containing hundreds of MBs of files, but output a 2kB program. Someone correct me, but it sounds like if you had the same thing with a unison project, the actual executable size can only grow?
- lilyball 7y agoMy assumption is the content store can only grow, but any executable produced from it would only contain live code.
- mekkkkkk 7y agoI suppose you could do it for the top level application code, but all past definitions of libraries must remain. That's the thing that allows safe updates of shared dependencies.
- jedimastert 7y agoMaybe I've been out of the game or something. But I don't think saying everything is "content-addressed" can land as such of a big mic-drop moment when I've never heard the term or the concept in my life and the front page does absolutely nothing to explain it beyond that. ------ EDIT: My tone here is a little more antagonistic that I meant (proofread kids, don't just check for spelling and publish) but my first impression was a kind of "buzzword-y" vibe. I've looked a bit more and the authors seem genuinely passionate about shaking things up and trying something completely different, which I can respect. I'll leave it up as is because I still think my issue are legitimate, but the tone is a little off and I apologize. ------ Let's take my discovery path so far as an example: > Functional language: cool cool. I know what that is. Immutable: also cool. Content-addressable: no clue. Saying it'll simplify code bases and eliminate dependency and "no builds" is supposed to sound amazing, but it really doesn't land when I have no clue what the premise is. > Alright, that's it for the front page. No code examples, nothing linking the currently known to this new paradigm-shifting stuff. K. Let's try the docs. > The Welcome is the state of the project without saying anything about the language itself. Roadmap isn't gonna help Quickstart! Let's look there. This amount of effort for discovery isn't very helpful for me. I found a selection of talks elsewhere on the site. One of them is labeled "This is a longer (40 min) introduction to the core ideas of Unison and probably the best talk to start with." That might be a nice link for the front page. I unfortunately don't have anymore time to look at this this morning, but the first 5 or so minutes of the talk say waaaaaaaaay more than the first however long I spent. Honestly, I think all of that information (code examples, linking core ideas to what we already know, basis of comparison) could be on the front page. The tl:dr I can glean from it is: It's kinda like Haskell, but every definition is turned into AST and put in a hash table. Any references are secretly references to the table, so changing a definition is making a new hash and changing the reference, and renaming is changing the reference to name table. Also, everything is append instead of rewrite, which makes all kinds of stuff cleaner, like versioning and refactoring. Pretty neat idea, I just don't really like how long it took me to come to that knowledge. I don't know how well it would scale or be usable in a real world scenario, but I also have never used Haskell or any functional language in a "real world" scenario so I'm not the best one to ask.
- refried_ 7y ago
- forgotmypwd123 7y agoThe name is already pretty taken.... https://en.wikipedia.org/wiki/Unison_(disambiguation) https://en.wikipedia.org/wiki/Unison_(disambiguation)
- hobofan 7y agoThat list looks like its very available to me? The only overlap with software are two unmaintained projects.
- emmanueloga_ 7y ago"Unison: a new distributed programming language" by Paul Chiusano [1] 1: https://www.youtube.com/watch?v=gCWtkvDQ2ZI https://www.youtube.com/watch?v=gCWtkvDQ2ZI
- the_duke 7y agoThis talk highlights the benefits and interesting features of Unison much better than the docs. Highly recommended.
- capableweb 7y agoThe video is from Sep 15, 2019 and still more useful than their website? Anyone have a transcript to link?
- pcr910303 7y agoA TLDR for the tour[0] based on my understanding (please fix me if I’m wrong): Unison is a functional language that treats a codebase as an content addressable database[1] where every ‘content’ is an definition. In Unison, the ‘codebase’ is a somewhat abstract concept (unlike other languages where a codebase is a set of files) where you can inject definitions, somewhat similar to a Lisp image. One can think of a program as a graph where every node is a definition and a definition’s content can refer to other definitions. Unison content-addresses each node and aliases the address to a human-readable name. This means you can replace a name with another definition, and since Unison knows the node a human-readable name is aliased to, you can exactly find every name’s use and replace them to another node. In practice I think this means very easy refactoring unlike today’s programming languages where it’s hard to find every use of an identifier. I’m not sure how this can benefit in practical ways, but the concept itself is pretty interesting to see. I would like to see a better way to share a Unison codebase though, as it currently is only shareable in a format that resembles a .git folder (as git also is another CAS). [0]: https://www.unisonweb.org/docs/tour https://www.unisonweb.org/docs/tour [1]: https://en.wikipedia.org/wiki/Content-addressable_storage https://en.wikipedia.org/wiki/Content-addressable_storage [2]: https://github.com/unisonweb/quickstart https://github.com/unisonweb/quickstart PS: The website is very well made, but I would like to comment that there should be two buttons on the top front page, the tour and installation, as I think most people want to have a glimpse of the PL before installing. I, at least was puzzled because I thought the button was a link to an introduction of the language.
- Avi-D-coder 7y agoI really like the idea, I like the language, but the world will not be rewritten in Unison. A web assembly FFI story is needed for Unison to succeed.
- tasogare 7y agoIs this satire? Web assembly has no real adoption on the browser yet, is waiting for a standard I/O interface on the desktop to be useful and is itself the nth iteration of an old concept.
- Avi-D-coder 7y agoWeb assembly is the first time a binary assembly has been adopted as an open web standard. What do you propose as an alternative safe sandbox for other languages? Large quantities of code can already be compiled to WASM. Since Unison works best with pure functions, most system interfaces would presumably be emulated. This emulation is already possible with Browsix.
- strbean 7y agoUnity targets WASM. I've run into several browser games using it in the wild.
- agbell 7y agoI have learned a lot from the creators Paul and Runar in that past. Their book on FP is legendary in some circles. Unison seems like a super ambitious undertaking, but I wouldn't bet against this team.
- augustk 7y agoI found this rather incomprehensible.
- sktrdie 7y agoI like the idea of syntax-tree rather than filesystem directories (if that's the main difference). Seems like this could be implemented in other languages though, and don't really understand why we need yet another new language. For instance, can I not build my JavaScript code in similar ways: I would need a compiler that stores things in trees rather than dirs.
- sparkie 7y agoThe big issue is the presence of cyclic dependencies between parts of code. If a piece of code is identified by its content, and its identifier is the Merkle root of its parts, then you can't possibly have cycles because you can't compute the hash of a parent before computing the hash of its children (which in turn depend on the parent). You have to use DAGs or plain old trees and eliminate any cycles. So to get it to work with other languages, you would need a way to convert their abstract syntax into a DAG compatible structure. It may be possible to do so, but I doubt there is a general approach which will work across multiple existing languages. It would require per-language hacking, if it is even possible without rewriting some parts of code. Seems like languages like OCaml and F# might be slightly more suitable for this approach because they require compilation units to be ordered by their dependencies, and thus promote a convention of avoiding cyclic dependencies between types (although it is possible to make such dependency in the same compilation unit with `type A and B`). They also allow recursive functions, but these should be simple enough to represent with a non-cyclic syntax tree. If you design a language from scratch, you can simplify things by requiring that no cycles exist in the language - at least at the syntax tree level. You might be able to design representations for recursion at a higher level which collapse to non-cyclic structures in the AST.
- Vlad_Zamfor 7y ago>>code is content-addressed and immutable. No, as I keep insistently repeating: Code is content-immutable and addressed. Also, Urbit is a lie, Surface detail is true and you are a lie and your code is retarted.
- Vlad_Zamfor 7y agoBlaaaaaaah. (No I'm not being sick.) Blaaaaaaaaaah. I am not a robot. Repeat: I am not a robot, I am a human being. But I love your (timeless) decision theory.
- giancarlostoro 7y agoOne thing that takes away from programming languages is not having code samples on the index. I think this lets someone know immediately if it's interesting to them or not. Show a sample of code with the console output or a screenshot of an UI from the code. I think Racket had it right ages back. They would show everything from a web server, to other things. This is what major programming languages (with some exceptions) basically do and it gives a developer more information than any amount of marketing speak. That said, I had to dig in the documentation to find code, and it didn't seem as obvious cause the syntax is definitely different from what I'm used to and there's weak syntax highlighting.
- blain_the_train 7y agoSmall code samples tell me next to nothing. How could they. I want a clear explanation of the foundational aspects.
- dunefox 7y agoI want both.
- giancarlostoro 7y agoThat's the ideal amount of information. A reasonable example of a good page that is informative and provides lots of examples (enough at least!) is the one for D: https://dlang.org/ https://dlang.org/
- dunefox 7y agoI also like the "Ecosystem" part of Julia: https://julialang.org/ https://julialang.org/ Sadly, for some reason code samples are lacking.
- giancarlostoro 7y agoJulia is a language I love that I don't see myself using sadly. It does some amazing things that leave me shocked, like it can show you the assembly you generate while using a REPL. That's impressive to me. However, I'm not the target developer for Julia. Edit: Course after clicking your link, I am wondering how wrong I am since it is still technically general purpose capable. Wow Julia has grown so much!
- stef-13013 7y agoThe language of the month... (Can't wait february)
- kbr 7y agoLooking at their GitHub [1], it's been actively developed and open source since 2013. [1] https://github.com/unisonweb/unison https://github.com/unisonweb/unison
- nadam 7y agoI find the content-addressed, name-independent, immutable (kind of blockchainy) approach to source code very interesting. On the other hand this seems to be rather orthogonal to other (semantic) aspects of the language. I wonder what would happen if we would change one thing at a time to test the idea: create something like unison based on an existing popular programming language. (python, javascript, java, etc...) All the syntax handling, building and version control would be done the unison way, but the interpreter would be the same as today in that popular language. The benefit would be that a lot of existing code could be transferred into the initial 'blockchain', with all the current dependency hell being solved from day one. I did not think this through deeply though... Maybe some aspects of existing languages prevent them to be handled the 'unison way'?
- brodo 7y agoI tried something like that in 2016 with Javascript. I parsed the source code and put every AST node on IPFS and linked it to the other node using the hashes. The problem was that this is a _lot_ of overhead...
- zamalek 7y agoSpent a year doing R&D into storing a "abstract syntax DAG" consisting of extremely rich syntax nodes (effectively entire programs/modules). That overhead you mentioned is why we decided that failure was a good result.
- capableweb 7y agoInteresting, you have published the results/source somewhere public? Would love to take a look at it. If you're using a language that doesn't need a AST/where the AST is the same as the source code, I'm sure we could pull out more benefits of this approach. Seems one would need a lisp or lisp-like language that is homoiconic.
- zubairq 7y agoI have done exactly that with a language called Pilot. It is not pure JS but based on JavaScript and all code is content addressable and indexed by the sha256 of the code
- kowolkian 7y agoHell yea, we can finally move forward with editors now. No more saving files with syntax errors. I imagine you could move a lot of paredit functionality into an editor like this, or have excellent voice editing.
- m712 7y agoNo mention of Smalltalk in the comments? The "codebase" that is managed by ucm sounds very similar to Smalltalk images. I am personally delighted about this.
- losvedir 7y agoVery cool. Glad to see someone tackling the idea I first saw brought up by Joe Armstrong[0]. When I read his post it made so much sense, I was hoping I'd get to see someone try it. [0] https://joearms.github.io/published/2015-03-12-The_web_of_names.html https://joearms.github.io/published/2015-03-12-The_web_of_na...
- andrekandre 7y agofrom the link: > Once we have the SHA1 name of a file we can safely request this file from any server and don't need to bother with security. > For example, if I request a file with SHA1 cf23df2207d99a74fbe169e3eaa035e623b65d94 from a server then I can check that the data I got back was correct by computing its SHA1 checksum. —- that’s crazy! i’ve had the same thought myself, and wondered why no one had done something like that... i hope this becomes more and more common (though not using sha-1 ^^)
- capableweb 7y agoThere is bunch of systems implementing things like this, commonly referred to as "content-addressable storage" as the address of the content is based on the content itself. See https://en.wikipedia.org/wiki/Content-addressable_storage https://en.wikipedia.org/wiki/Content-addressable_storage
- andrekandre 7y agothat’s really cool, thanks for the link
- DerSaidin 7y agoThis is cool. I've wanted to see a Merkle tree based AST for faster incremental compilation (and incremental static analysis). I wonder if the source manager interface makes this easier to use than editing source files? AST can still be the source of truth. To edit need to generate source text from AST, edit as text, parse to AST, save. In other words, I think most of the benefits of this can live behind the scenes for other languages.
- bnjmn 7y agoI don't think you can have a proper Merkle tree if cycles are possible, and cycles definitely are possible in this AST representation: https://www.unisonweb.org/docs/faq#how-does-hashing-work-for-mutually-recursive-definitions https://www.unisonweb.org/docs/faq#how-does-hashing-work-for...
- UglyGenius 7y agoWondering if Unison was designed as (or ever planned to become) a general-purpose language or it something more domain-specific, e.g. distributed computations.
- UIZealot 7y agoThis is seriously impressive. I've always felt that some kind of database system is needed for code in which you store each function individually. Unison not only has that, it goes one step further to identify a function by its hash. I can't wait to see what the world of programming can become along this direction.
- thethimble 7y agoDoes anyone know how concurrency is handled on Unison? I couldn't find any references in the docs.
- tracnar 7y agoThere's an example in this talk: https://youtu.be/gCWtkvDQ2ZI?t=1903 https://youtu.be/gCWtkvDQ2ZI?t=1903 Basically you can quote code (like in Lisp) and pass it to an executor (thread, remote server, ...). The main difference is that thanks to the immutability, you can also have a protocol which shares efficiently all the dependencies required to execute the code (like a git pull). It also uses an effect system, so the implementation does not need to decide which executor to use, it only uses an interface called an "ability", and the caller can choose the implementation.
- ed 7y agoFor a good introduction, watch this talk at 1.5x speed from 2:50 to 5:40 https://youtu.be/gCWtkvDQ2ZI?t=170 https://youtu.be/gCWtkvDQ2ZI?t=170
- war1025 7y agoMaybe I'm missing something, but this seems like it would get unwieldy very quickly for anything more serious than toy examples. Even the toy examples I'm having trouble following along with. The benefit of code-as-text is that you can navigate the text without knowing what you are looking for. This seems to take the opposite approach of making it very easy to look things up assuming you know ahead of time what you are looking for. That is something that a good usage of grep or some more sophisticated IDE integration will already take care of for you. The only thing I could see this being potentially useful for is "notebook" style computation, where you are really only using the language to do things like structured math calculations. What am I missing here?
- strbean 7y ago> What am I missing here? I think IDE tooling for Unison could pretty easily give you the exact same experience. Generate code from the AST, group it reasonably, and give you a view that is indistinguishable from a traditional source tree. It might be non-trivial to structure things nicely, but I think theres a good chance your generated structure would be better organized than a traditional codebase.
- reggieband 7y agoI recently came across Unison through YouTube recommending me a series of videos from the "Strange Loop" channel [1]. The fundamental idea of uniquely addressing functions based on a hash of their AST is mind-blowing to me. Immediately my mind started to consider many of the possible paths such an idea could lead down, many of which are clearly tickling the minds of many of the commenters in this thread. My first thought was the same insight from von Neumann architectures: code is data. So I thought of package repositories with URLs corresponding to hashes of function definitions. http://unison.repo/b89eaac7e61417341b710b727768294d0e6a277b http://unison.repo/b89eaac7e61417341b710b727768294d0e6a277b could represent a specific function. A process/server could spin up completely dumb other than bootstrapped with the language and an ability to download necessary functions. You could seed it with a hash url pointer to the root algorithm to employ and a hash url to the data to run against and it could download all of it's dependencies then run. I imagine once such a repo was up and running you could do something like a co-routine like call and that entire process just happens in the background either on a separate thread or even scheduled to an entirely different machine in a cluster. You could then memoize that process such that the result of running repo-hash-url against data-hash-url is cached. e.g. I have http://unison.myorg.com/func/b89eaac http://unison.myorg.com/func/b89eaac run against http://unison.myorg.com/data/c89889 http://unison.myorg.com/data/c89889 and store the result at http://unison.myorg.com/cache/b89eaac/c89889 http://unison.myorg.com/cache/b89eaac/c89889 1.https://www.youtube.com/watch?v=gCWtkvDQ2ZI https://www.youtube.com/watch?v=gCWtkvDQ2ZI
- olodus 7y agoWas thinking of writing this years Advent of Code in Unison but changed my mind because of its very young age and switched to Zig instead. But I'll very much consider it for next year. I really think some of its ideas are, if anything else super cool and worth learning and thinking about.
- jganetsk 7y agoAt first, this sounds like a great idea. On second thought, I have two major categories of concerns: 1) If I fix a bug in a function, (thus creating a new version of an existing function) how do I propagate that fix to all that code that transitively depends on the buggy version? Doesn't that mean I need to create new versions of all the downstream dependencies? Doesn't that defeat separate compilation? Does this scale? 2) Does this closely couple interface and implementation? Is it a hash of an implementation, or a hash of an interface? Is it possible to depend only on an interface, and not on an implementation?
- sparkie 7y ago> 1) If I fix a bug in a function, (thus creating a new version of an existing function) how do I propagate that fix to all that code that transitively depends on the buggy version? Doesn't that mean I need to create new versions of all the downstream dependencies? Doesn't that defeat separate compilation? Does this scale? This can vary depending on how many dependants the code you change has. If you have some fundamental type which an entire codebase depends on, then modifying it will essentially require recomputing hashes for the most of the codebase. On the other hand, if it's something close to the entry point, you would only need to recompute a few hashes and the root hash which represents your entry point. Any parts which are unchanged effectively have their hashes cached. > 2) Does this closely couple interface and implementation? Is it a hash of an implementation, or a hash of an interface? Is it possible to depend only on an interface, and not on an implementation? I don't think unison has interfaces or any similar construct yet. There's an FAQ item mentioning why type classes are not included[1] yet. Personally I think the right approach would be to use a structural type system similar to OCaml's. You would have functors which describe the code you're calling, and call sites would use the hashes of the functor definition. You can then define concrete representations of types independently of the functor, and instantiate them against the functor afterwards. Thus, if you change some implementation detail in a type, then the only hashes that will need updating are those of your concrete type and the instantiation of the functor against your type. The functor, and any code which depends on it, will remain unchanged. [1]:https://www.unisonweb.org/docs/faq https://www.unisonweb.org/docs/faq
- jganetsk 7y ago"As a result, a Unison codebase can be versioned and synchronized with Git or any similar tool and will never generate a conflict in those tools" Conflicts are a feature, not a bug. If two developers are making divergent changes in the same piece of code, I suppose Unison would just let the divergence happen, essentially forking the code. I don't think forking code is the right default.
- mikl 7y ago> A friendly programming language from the future. I loathe marketing BS like this. No, you’re not from the future, you pretentious twats. If you have a good idea, let it stand on its own merit, don’t dress it up with manipulative language.
- dang 7y agoRelated from 2015: https://news.ycombinator.com/item?id=9708405 https://news.ycombinator.com/item?id=9708405 A larger thread, also from then: https://news.ycombinator.com/item?id=9512955 https://news.ycombinator.com/item?id=9512955
- frank2 7y agoIs the Unison codebase manager written in Unison? What other user-facing open-source softwares have been written in Unison? Which of those softwares has been used for months or years by at least one person?