9 ms·
A look at Unison: a revolutionary programming language
- dmytrish 4y agoMy experience with Unison so far has been limited to learning the basics and doing a few exercises on Exercism.io (big kudos to whoever added the Unison track there, it's a really great way to get your hand dirty with a new language!). Coming from Haskell/other functional programming languages background, I have found many things familiar. Unison can be an improvement and an opportunity to do better this time. What I still find lacking: - developer experience and tooling: there's no language server (is it even possible for Unison?) or an easy development environment. I found myself confined to the usual vim+tmux+"repl" combo. A VSCode plugin that I tried was pretty basic, even though it showed the structure of code base and libraries nicely. Even Haskell is more pleasant with haskell-language-server these days. - discoverability of library functions: skimming through modules, reading docs, trying to figure out what to use. Type-aware search (like Hoogle) is a great idea, but it does not replace the ergonomics of having context-specific completions. Having dot-namespaces relevant to a specific object (in OOP/Go/Rust style) makes this so much easier for me.
- iamevn 4y agoGood news, there is now a language server! https://www.unison-lang.org/learn/usage-topics/editor-setup/ https://www.unison-lang.org/learn/usage-topics/editor-setup/
- kwhitefoot 4y agoWhy do we need a new language to do this?
- pmarreck 4y agoOr just use your existing language of choice, but incorporate Nix (which is based on the same idea), or go all-in and use NixOS (or Guix, very honorable mention) to get the same ideas all the way to the bare metal of the hardware (which IMHO is where the reach of this idea belongs, it is that good) For example, there are tools that convert traditional lockfiles to nix flakes. Nix is more intimidating than it actually is. It’s basically JSON with pure functions and some syntactical-sugar shorthands that end up being very nice. “Flakes” are basically lockfiles for Nix. Before Flakes, Nix still used hashed dependencies though. So everything you install with it is more or less guaranteed to also automatically pull in everything it needs to run, without conflicting with the needs of anything else.
- rileyphone 4y agoRemoving layers of abstraction is necessary for building greater things on top. Not that Nix isn't better than what exists currently, just ideally the OS/language disconnect can be resolved, in line with Dan Ingalls. TBH I'm not really sold on Unison as a language, but the idea is certainly intriguing. Would be a lot more interesting if it was as at home in the browser as it is on unix - as it stands I don't see a real use case for it. Perhaps a killer app will come along, but I think for a language to succeed with this idea it will have to be a lot more pragmatic (aka further from Haskell). Time will tell.
- dustingetz 4y agoi upvoted, love the reference to os/language disconnect. But is it historically true that we must remove layers to build greater things?
- naikrovek 4y agocan someone tell me what this is? this instinct to "one-up" posts? "forget that, try this!" "that's nothing, look at my favorite thing!" this is rampant all the time in all posts no matter what they're about on this site and I do not understand it. Root comments reminiscing about The Old Days also steal thunder from the topic and I don't understand why people do it. start a post about Your Favorite Thing if you want to go on about it; please stop hijacking other threads because you wanna talk about Your Favorite Thing. let people talk about This Thing...
- pmarreck 4y ago> can someone tell me what this is? this instinct to "one-up" posts? That’s not at all what I said. I just said that the fundamental idea here is already available for everyone at the component level for your entire system. Unison just takes this idea down into the language. A new language that you’d have to convert 100% of your work into in order to benefit from, and then you’d STILL suffer from the same things outside that ecosystem in your software, that Nix solved.
- 4y ago
- michaelmior 4y ago> Unison does away with builds. Completely! > It has a canonical representation for all code, Isn't generating that canonical representation the build step? > The important thing is that now, I can actually compile and run this program Now I'm confused whether there is or isn't a build step.
- naikrovek 4y agoJavaScript doesn't have a build step either. sounds like it is interpreted and you reference methods by hash instead of by name. sorta?
- __MatrixMan__ 4y agoI'm not an expert at JS internals, but I'm under the impression that if you call a function ten times, its code has to be interpreted ten times, so you get ten, temporary, abstract syntax trees. Such is life in interpreter-land--the code is authoritative, the instructions are ephemeral. My impression of Unison is that if you want to call a function ten times, you just need to evaluate that code into an AST once. Once you have the hash of that AST, you can delete the code and still call the function 9 more times without having to bother with building the tree each time. I don't know what to call it, but I don't think it's interpreted because you don't need the code to run it (except the first time, which is how you know find the hash of the function).
- mrtweetyhack 4y ago[dead]
- goto11 4y ago> I'm not an expert at JS internals, but I'm under the impression that if you call a function ten times, its code has to be interpreted ten times, so you get ten, temporary, abstract syntax trees. This is not the case even in an interpreted language. You only need to build an AST once, at parse time. In JavaScript the AST is then compiled into byte code or machine code depending on the implementation.
- cratermoon 4y ago> tests that run every single build even when nothing checked by them has changed Oh yes, because we can always be sure that a change in one place will never cause a test in another place to fail.
- deleted 4y ago[deleted]
- moeris 4y agoNot when it's referentially transparent. In that case, there's no need to run the tests if a function or its children haven't changed. Of course, in that's the case, the tests are probably fast enough that running then won't matter much.
- __MatrixMan__ 4y agoIf you're working with pure functions, you can always be sure of this.
- xet7 4y ago> As I write this in early 2023, finally, I think it has reached a level of maturity where it’s actually usable for real work, so I decided to write about my impressions using the language for something non-trivial. For what non-trivial you used Unison for? Are you allowed to write about it? Is that those examples in this Unison introduction article, or something else?
- scanr 4y agoIt will be interesting to see how it handles transitive dependencies through a supply chain you don’t control. Same issue as “this 3rd party npm package depends on an insecure version of X” but at a function level.
- jdougan 4y agoIntegrate this with IPFS (or other DHT) and you have a distributed code database with the possibility of massively parallel builds. (Assuming I understand the claims properly)
- zubairq 4y agoI’m working on a low core project that is already using content addressable source code that is stored in IPFS at https://github.com/yazz/yazz https://github.com/yazz/yazz so it can be done
- deleted 4y ago[deleted]
- __MatrixMan__ 4y agoTheir slack is on the free tier, so I couldn't find a direct quote within the last 90 days, but this comes up from time to time. Last I heard it's not on the roadmap but there's interest. I didn't think of it as paralell builds so much as a big patchwork quilt where some patches are data and others are code and you can kind of wander around and see which data is related to which other data through which functions.
- dietr1ch 4y agoLooking at the comments it seems that this talk might be a better introduction than just skimming at the landing page. https://www.youtube.com/watch?v=gCWtkvDQ2ZI https://www.youtube.com/watch?v=gCWtkvDQ2ZI I watched that in 2020 or so and got amazed at how much a seemingly simple idea could work it's way into the core of a language. What I recall is this, The main new idea is turning codebases into a content-addressed store, this needs some new tooling, but makes a couple of interesting things possible, * Having different versions of the "same" function. They are actually different functions anyway, so you can do things like partial library upgrades when there's breaking changes. Large migrations like python 2 to 3 wouldn't take O(10yr). * Formatting is not a thing anymore. This goes further than just having a formatter as there's really no format nor names you can't personalize locally without affecting anybody. * Similarly, renaming is free, so you can come up with better names in the future and chanting it just needs a tweak to the canonical name for the function. * Functions are serialiazable, which makes it possible to send them to remote nodes for execution without any concerns about their deus, since a function is now more of a Merkle tree, so if there's any difference the client would know and be able to ask for missing dependencies * The tool to manage your function repo might seem like a burden to some, but once you realize that having this as a first class tool that understands the language you can propose safe mass refactoring of code you don't own.
- bobajeff 4y agoThis sounds almost like Dion. It would be cool to be able to feed the AST to a compiler backend like gcc/llvm and map to C's semantics. * https://dion.systems/gallery.html https://dion.systems/gallery.html
- xwolfi 4y agoI stopped reading when they cried in joy at the ability to auto infer types instead of writing them. This has always led, in my limited experience, to unreadable code after 2 weeks. Why do people want to write short leetcode, Ill never get it.
- miloignis 4y agoPart of the cool bit about Unison is that the code is stored in a content-addressed database and is then rendered out to files to edit at your command (including with your own set of custom names for things, I think). I imagine that Unison would allow you to work on code that has entirely specified types while perhaps a coworker of yours let them all be inferred, without irritation to either of you.
- dang 4y agoRelated: The Unison language – a new approach to Distributed programming - https://news.ycombinator.com/item?id=33638045 https://news.ycombinator.com/item?id=33638045 - Nov 2022 (113 comments) Unison Programming Language - https://news.ycombinator.com/item?id=27652677 https://news.ycombinator.com/item?id=27652677 - June 2021 (131 comments) Unison: A Content-Addressable Programming Language - https://news.ycombinator.com/item?id=22156370 https://news.ycombinator.com/item?id=22156370 - Jan 2020 (12 comments) The Unison language - https://news.ycombinator.com/item?id=22009912 https://news.ycombinator.com/item?id=22009912 - Jan 2020 (141 comments) Unison – A statically-typed purely functional language - https://news.ycombinator.com/item?id=20807997 https://news.ycombinator.com/item?id=20807997 - Aug 2019 (25 comments) Unison: a next-generation programming platform - https://news.ycombinator.com/item?id=9512955 https://news.ycombinator.com/item?id=9512955 - May 2015 (128 comments)
- robocat 4y agoI worked using an object oriented database, where all code was stored as the AST as versioned objects in the database. Problems that I remember that might be relevant: 1. To “install” code into another instance, you usually exported your code as a massive text file from your dev server as source code, then import the source code as text into your production server. You could do individual functions, but that had a high risk of ending up with a pet with different code than your dev server. Version control was a mess. 2. We just ended up putting source code (without comments) directly onto production servers. That happened to turn out well for the client, and turn out badly for the development company (who owned the code). 3. Syntax or semantic changes to the language were a bitch when the database version needed an upgrade. Any existing code was migrated, from the old objects to the new objects, which sometimes caused problems. 4. Limited IDE. You had to use the IDE that came with the database, and various code transforms, global refactors, or normal development actions were unavailable. The primary other option was to export a complete syntax tree as text, make changes, then re-import (uggggh). 5. Debugging was hell. Obviously Unison is a very different beast, but some of the above problems were a result of having the AST be the source of truth: problems which have the potential to apply to Unison too.
- dmytrish 4y ago1. A Unison codebase is a persistent shared data structure, which should be easy to integrate deeply with something like git or borrow ideas from it. Conceptually, it's just like a git repository. 2. It's possible to add an additional compilation step to generate (potentially obfuscated) machine code for a Unison AST. The same point applies to Javascript/Python or JVM bytecode. 3. Data migrations are an open question, yes. Still, Unison is a pure functional programming language and might do this much better than an imperative OOP language. Especially if you model your data as a shared persistent data structure too (like Clojure). 4. This is true, all the textual tools go out of the window without some kind of a translation layer. There are possible workaround like exposing a codebase as a FUSE filesystem. On the other hand, the codebase-as-AST makes it trivial to do code transforms, global refactors, etc, in a Lisp-style macro way, with its pros and cons. 5. I agree that debugging and execution observability is a must. The idea here seems to be "let's have a Haskell-like language that does not need much debugging in the first place". I am a bit skeptical of this approach in general, but it does make a lot of debugging go away. Thanks for sharing your experience, many of the points are valid for Unison.
- lisper 4y agoThis looks attractive at first but it has one show-stopping problem AFAICT: if it turns out that a function has a bug, you can't fix it by changing the function definition. You have to create a new function and then change every single call site from the old definition to the new one. Maybe there is a solution to this problem, but a cursory review of the language description didn't turn one up. It seems like a Really Hard Problem because there is nothing that can structurally distinguish between a new function that is created for its own sake, and a new function that is intended to be a bug-fixed (or otherwise enhanced) version of an old one. Maybe a unison aficionado can enlighten me?
- zawodnaya 4y agoThe UCM tool propagates the changes for you automatically. It also creates a patch that you can distribute with your release to update any dependents automatically. If the change can’t be made automatically because it breaks stuff, then UCM guides you through propagating manually. You’d have to do this manual propagation in any language. Unison is a little nicer about it than most languages, since it just tells you what needs an update (and will suggest an order in which to make the updates) instead of giving you type errors or test failures.
- dietr1ch 4y agoWell, you can say the same about git right? If you need to change an old commit, then you'd need to re-create all the commits that depend on it. Which is true, but something we leave to tools. In git we can just rebase or absorb. In terms on how to distinguish functions, you could just have some suffix, like foo@base and foo@local. I played a bit with Unison before, but I don't think I tried this. I'm sure it's a non-issue though because it's not hard to imagine how tools would help here.
- lisper 4y ago> Well, you can say the same about git right? The difference is that in git the repo structure is metadata. The data (the contents of particular commits) is completely independent of the repo structure and so you can change the latter without changing the former. Furthermore, when you try to build a program, you only ever deal with a single commit. You never build a program from multiple commits at once. Program linking has nothing to do with the repo structure. But in unison, the "repo structure" is no longer metadata, it's part of the program. It is now part and parcel of your linker. So when you change the "repo structure" you are changing the behavior of the program. Git works precisely because it separates data (program) from metadata (repo structure). When you glom them together the way unisom does, you get some gnarly problems to which I don't see any immediately evident solutions.
- aetherspawn 4y agoFinally, a programming language that can be used in Tarrey Town.
- deleted 4y ago[deleted]
- beastman82 4y agoFWIW I'm acquainted with a few folks on this team and it's the biggest concentration of talent I've ever seen.
- ultra_nick 4y agoI started designing my own functional dataflow language to simplify distributed programming. It looks like I can stop. Does Unison execute its DAG of functions concurrently by default?