The Unison platform
Unison is a new programming language, currently under active development. It's a modern, statically-typed purely functional language, similar to Haskell, but with a unique ability to describe entire distributed systems with a single program. Here's a simple example:
-- comments start with `--` -- alice : Node, bob : Node x = factorial 6 Remote.transfer alice y = foo x -- happens on `alice` node Remote.transfer bob bar x y -- happens on `bob` node
Remote.transfer function introduces a "remote effect", where computation may proceed on multiple Unison nodes:
Remote.transfer alicetransfers control of the computation to the
foo xcall happens on the
- At each transfer, any required definitions (such as
x) will be dynamically deployed to the
alicenode and cached for future use.
Remote.transfer bobtransfers control of the rest of the computation to the
bar x ycomputation happens on the
bobnode. Again, any needed definitions (
y) will be dynamically deployed to the
This dynamic transfer / deployment of arbitrary computations is possible because definitions in Unison are identified by a cryptographic hash of their content, including the hashes of all dependencies (the hash is also "nameless" as it isn't affected by naming of variables). To transfer a computation, we send it to the recipient, and the recipient checks to see if the computation references any unknown hashes. Any unknown hashes are synced to the recipient before the transfer completes and the computation proceeds.
If you'd like to learn more about the project, the talk How to write a search engine in 15 lines of code has more of an introduction to the language.
Since Unison isn't terribly useful in its current form, the rest of this README will focus on stuff that will be of interest for potential contributors, namely, how to build the code, and a brief tour of the (fairly small but action-packed) codebase. If you're just interested in the project and want to follow along with the progress, unisonweb.org is the place to go, or you can also say hello or lurk in the chat room.
Still here? All right then! Let's get to it.
A brief code tour
First, a bit of orientation. Here's the directory structure:
yaks/has subprojects for various utilties not specific to Unison (the result of "yak-shaving"). Once mature, each of these might be moved to independent projects and published on Hackage.
parser-typechecker/has the Unison syntax tree, parser, and typechecker. Depends on
runtime-jvm/has the JVM based runtime
Building using Stack
If these instructions don't work for you or are incomplete, please file an issue.
$ git clone https://github.com/unisonweb/unison.git $ cd unison $ stack --version # we'll want to know this version if you run into trouble $ stack build && stack exec tests
development.markdown for a list of build commands you'll likely use during development.
A brief tour of the Haskell code
Unison.Typehave the syntax trees for terms and types. In both
Type, the same pattern is used. Each defines a 'base functor' type,
F a, which is nonrecursive, and the actual thing we use is an abstract binding tree over this base functor, an
ABT(for 'abstract binding tree') is defined in
Unison.ABT. If you aren't familiar with abstract binding trees, here is a nice blog post explaining one formulation of the idea, which inspired the
Unison.ABTmodule. A lot of operations on terms and types just delegate to generic
Unison.Parsershas the main entry point for the parser.
Unison.Typechecker.Contextis the implementation of the typechecker, and
Unison.Typecheckerhas the "public interface to the typechecker" and some convenience functions. There isn't a lot of code here (about 700 LOC presently), since the typechecking algorithm is pretty simple. Unlike a unification-based typechecker, where the typechecking state is an unordered bag of unification constraints and higher-rank polymorphism is usually bolted on awkwardly later, Dunfield and Krishnaswami's algorithm keeps the typechecking state as a nicely tidy ordered context, represented as a regular list manipulated in a stack-like fashion, and the algorithm handles higher-rank polymorphism very cleanly. They've also extended this work to include features like GADTs, though this new algorithm hasn't been incorporated into Unison yet.