Live data from Hacker News

Unison Cloud

unison.cloud

151–158 of 158 posts

Re: Unison Cloud

#151
post #63

This is about the Unison language but I think it's relevant. I was checking out the FAQ for Unison and noticed this: https://www.unison-lang.org/docs/usage-topics/general-faqs/#... > Unison does not currently support a Foreign Function Interface, for invoking code written in other languages. > Your programs can interact with the outside world via the `IO` ability, and this includes interaction via network sockets - s…

Hi, one of the Unison creators here. We've held off working on FFI until the JIT compiler[1] is completed since FFI is closely connected to the runtime. There's some interesting subtleties with FFI in a distributed programming language, so I'll ramble about that here in case it's interesting to you. :) So, in Unison, all values are serializable, including functions and their dependencies. This is a key superpower tha…

> Hope that was interesting!

It's definitely interesting. I'm happy to hear that you'll definitely be supporting what we can currently do with less rigid languages and their FFI, but that we'll have to adapt to the bounds of the system and its rules to some extent.

Do you have any idea how you'd support `LoadLibrary`/`dlopen` in order to load/reload function pointers live? At some point I imagine a lot of this has to have a "trust me" kind of escape hatch.

Re: Unison Cloud

#152
post #150
post #46

Earlier quoted context omitted.

The language is free to use.

Yes but what’s a language without a deployment strategy?

Not familiar with its deployment strategy. I assumed it could built into a binary but maybe not.

Re: Unison Cloud

#153
post #31

It looks like to use this product, I have to learn an entirely new programming language (which appears to be a weird mashup of Python and Haskell), a whole set of entirely new API's, I can only host my stuff on their for-pay cloud infrastructure, and I can't use source control? That's a lot of very high hurdles to clear. Even if this magically solved all my scaling and distributed system problems forever, I'm not sur…

++ The odd thing is unison started purely as a language. Now there's a platform. I'd love to hear some opinions from outside Unison about how they like using this language, tooling and hosting.

Hello! I'm a user of Unison. Been toying with it off and on since I heard about it maybe spring of last year from a Reddit post on the functionalprogramming sub.

As a somewhat stay-at-home dad I was looking to do something fun with programming, and ideally something where I could make an early impact. About the same time, I read about Tree Sitter Grammars and was looking at Lapce, a Rust IDE in its early stages, and uses TSGs for syntax highlighting.

So I ended up learning everything about the Unison syntax, going so far as to learn me a Haskell for great good to produce the TSG for Unison.

About that time, Unison started opening up early testers of Cloud. I passed because I hadn't really written much code in Unison. I'd just been writing the TSG (in C++ and JS).

But then I picked a project: write an implementation of Philips Hue's bridge API in Unison. In the process, I learned about server-sent events and wrote a library for that and released it on Unison Share, which I think of as a mix of Github and NPM (or Maven, or pypi, etc.). I also wrote a MimeType typings library.

I can't speak to the cloud stuff yet, and when I do use it, I won't have much to compare it to because my ops exposure in my profession (as a stay at home dad, haha) is limited.

That's my background, and here are my thoughts:

First, the Local UI for browsing your code and documentation is hands down the best I've ever seen. Everything you write is browsable there, and has hyperlinks to everything else. It's so money. And there's a `Doc` type as well, so you can write something like

  {{
    The first parameter of {term Internal} represents a count, and the second parameter represents a distance in 1-space.
  }}
  type Foo = Internal Nat Int

Then you can `add` and `Foo` will be stored in the current namespace, but so will `Foo.doc`, which is the content inside `{{ ... }}`. You can then delete this code from your scratch file and never think about it again.

If you browse the Local UI (you type `ui` in your `ucm` instance and it auto-loads in a browser), you can easily view the type, the doc above it, and you can click `Nat` or `Int` to be taken to the definitions of these in the base library, located at `lib.base` (`lib` is like your dependencies, like `node_modules` in JS, e.g.).

Say you later want to add a third type parameter. `edit Foo` and the current definition will be pretty printed to your scratch file. Then you can edit it, and run `update`. Anything relying on this type that can be migrated to the new definition will, and anything that can't automatically be migrated will get dumped to your scratch file for you to update manually. Once you have no more errors in your scratch file, `update` will finish it.

This feels a lot like the process of `git rebase --continue` until everything is consistent. Except here it's the code itself that `ucm` understands, not text data that `git` doesn't understand beyond "this is text with conflicts."

From one `ucm` instance, I can switch between projects. No managing folders on my computer in `/Users/foo/workspace/foo-project`, etc.

Anyway, the long and short is that once I got used to working this way, I immediately wished this existed for TypeScript as well, bc that's what I do so much of my work in. The doc generation is incredible, the source browsing is so good, and the process of updating my code is really slick. A few versions ago, it was less so, but it's been improved since then and now I really like it.

Pushing code is as easy as `push`. You can create releases of your libraries or applications by going to Unison Share, finding your project, and navigating through the simple "cut a release" wizard.

There are even types for License, CopyrightHolder, etc. so metadata about your application can be done in code. For example, the license for my mimeType library is

  LICENSE : License
  LICENSE = License [copyrightHolders.kpg] [Year 2024] mit

The type for `License` is defined as `License [CopyrightHolder] [Year] LicenseType. There are pre-configured license types in the base library, and `mit` is one of them.

I find this to be a nice addition as well, although for many this is something to be ignored. But I like the idea of encapsulating so much of a project in code rather than in things like a `package.json` file that is brittle.

The one other thing I'd like to mention is abilities. It was hard to wrap my head around them at first. I'm really familiar with monadic programming. My coworkers might say I'm too in love with it :) Wrapping my head around abilities was hard at first. They're kind of like...monads, DI, and interfaces all sort of mixed together. But there's essentially two components: the ability, and the ability handler. The ability is like you defining an interface. Any handler needs to know how to handle any of the "requirements" of the ability. For example, you might write an application that communicates with an api for example.com as

  ability Example where
    getAll : '{Example} [Foo]
    get : FooId -> {Example} Foo

You're somewhat defining an interface that handlers need to conform to (i.e., they must have code that handles each of the "ability requirements"). Your handler then essentially converts your abilities to more fundamental ones, or removes them completely. You're generally working your way, in an application, down to only IO and Exception abilities (there's probably some cloud abilities I am not familiar with), which UCM handles natively.

Your handler is like the implementation of an interface.

From there, you can write code using anything in that ability, and so long as some ancestor function call wraps all that in a handler, everything just works. It kind of acts like injecting your handler as a dependency of everything that is a descendant function of the handler.

I don't know if I'm effectively communicating how this works, but it makes sense for me. Those are the analogues I'm familiar with that I used to understand the ability system.

Now that I feel comfortable with it, it's pretty cool!

Edit: My final thoughts is that the language is really nice to use (though there are some things from TypeScript I miss, they're very few, and it's certainly superior to something like Java IME). It's nice the VCS and documentation/code browser is built in. Being able to push to a repo, again built into the ucm program, is convenient. Everything is wrapped up nicely. And the company behind the language is extremely online and repsonsive. I've gotten so much help from them. I wish I could speak to the cloud offerings, but I haven't worked with it yet.

Re: Unison Cloud

#154
post #85

Earlier quoted context omitted.

It definitely is ambitious! A multi-year effort. This post https://www.unison.cloud/our-approach/ talks more about why such radical changes were necessary to achieve what we wanted. (In particular check out the "3 requirements of the dream" section, which walks through what the programming language needs to support to be able to do things like "deploy with a function call.") My general take on "when and where to inno…

Not trying to pour cold water, but the "3 requirements" post seems to address straw man problems. There are existing solutions to each problem. 1. "Deployment should be like calling a function" isn't that the mantra of serverless? e.g. GCP Cloud Run or AWS Lambda? This is also becoming much more streamlined with server-side WASM e.g. wasmCloud. 2. "Calling services should be easy" this is what protobuf is for; cross-…

It is so funny to defend serverless with it's all crappy configuration, slow dev cycle and vendor lock-in.

Re: Unison Cloud

#155

OK, maybe this is a silly question, but if a function that is written once always refer to the same hash as when it was written, how do you update functions? For example, if I have function A that calls function B, in today's languages updating function B would just work (A will call updated function). My understanding is that updated function B (we can call it B'), would not be used.

Unison developer here! Let's say you have some term: B = "Hello " and it hashes to #a3yx. Lets say you also have funcion: A = B ++ "world" which hashes to #c7c1 when we store the A function, we actually store it as: #c6c7 = #a3yx ++ "world" Then later if you update the definition of B: B = "Hello, " and that function hashes to, #5e2b, when you tell unison to update B from #a3yx => #5e2b, it will look for all of the p…

This is a really interesting system, and I'm excited to give this a try!

Without knowing whether the following cases would actually be useful/relevant, I'm curious if these things apply to Unison:

- Is there a way to "pin" a symbol to a specific hash/version so it won't automatically update when the referred function gets a change? I.e. I could write: A = B@ ++ "world" and when I store and retrieve it, it becomes (example syntax): A = B@a3yx ++ "world"

- Is there a way to refer to a function/symbol by name rather than by hash? I.e. a call site which uses B by looking up which hash is currently associated with the name "B", such that if I do two simultaneous renames, B->D and C->B, the code would now refer to the function previously known as C?

- Are there ways in which the way function updates "bubble up" through the codebase (I assume updating a function means updating every function that calls it, recursively) could become a problem? It would seem that changing one little function could have a knock-on effect that requires re-hashing most of the codebase.

Re: Unison Cloud

#156
post #150
post #46

Earlier quoted context omitted.

The language is free to use.

Yes but what’s a language without a deployment strategy?

Since this announcement is about Unison Cloud, it might not be clear for people who aren't familiar with the Unison language that you can run Unison programs without Unison Cloud. So much like just about any other language you can put a Unison program in a Docker container, deploy it via AWS Lambda, etc. Unison Cloud is kind of an "easy mode" for scalable and distributed deployment with support for typed durable storage, the option to expose public HTTP/websocket endpoints, etc.

Here is an example of containerizing a Unison program: https://github.com/ceedubs/containerized-unison-program

And here is a library that makes it easy to create an AWS Lambda out of a Unison function: https://share.unison-lang.org/@gfinol/lambda-runtime

Re: Unison Cloud

#157
post #74

Earlier quoted context omitted.

What happens if you have two terms that are incidentally equivalent: A = "Hello " B = "Hello " C = A ++ "world" D = B ++ "world" and then you update the definition of A but not B?

At the point when you've written a term which is incidentally equivalent to another, the Unison codebase manager tool tells you that you're adding a term that is identical and lists its name. You can still technically perform the addition if you really want at that point, but most folks don't want two aliases for the same function floating around. If you do end up adding it, updating A would also update B. Think of t…

(Sorry for replying late to this but) that seems kind of inconvenient! And what if I'm using two libraries which happen to export functions with identical ASTs, and one updates? I guess usually meaningful nominal types will ensure that that doesn't happen but it seems like a nightmare to deal with in the event that it does.

Re: Unison Cloud

#158

I strongly dislike marketing material that tries to normalize gross incompetency around complexity problems that don't actually exist.

If you gave examples of what you meant, others might be able to understand and discuss what you mean.

I have been involved in so many projects where AWS, Google Cloud, OpenStack, or Kubernetes (on metal) was used. I'd have to think a bit hard on how to articulate this well, but I see the page linked on this HN thread and it just screams "utter horse shit" to me.

Someone who finds AWS so hard to use is either not reading documentation or not comprehending it and probably shouldn't be coding in the first place.

Post reply on HN