One 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 excepti…
TBH if you're creating a new language after 2014 you should be thinking about how to get good syntax highlighting and other tooling from the language definition itself, because you're competing with a ton of mature languages that had to do this manually through a ton of effort of their communities.
The Unison language
111–120 of 144 posts
Re: The Unison language
#112Earlier quoted context omitted.
There's nothing philosophical about it! There will exist a conflict as far as Git (or any other) version control system is concerned. That's all he saying!
The files holding the ASTs are append-only. So you get: PR #1: appended stuff PR #2: appended stuff So there is no merge conflict in the git sense.
If that conflict always shows up in one single line saying what hash of the main function is the one to use - then it doesn’t seem like a huge improvement in terms of conflict handling. Conflicts bubble to the root hash. I assume they thought about this and have some sort of tooling for “traversing” conflicts from the root, choosing my function, your function, or allowing a merged function to be created.
Re: The Unison language
#113My 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 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 run against http://unison.myorg.com/data/c89889 and store the result at http://unison.myorg.com/cache/b89eaac/c89889
Re: The Unison language
#114I 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.
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.
Re: The Unison language
#115Earlier quoted context omitted.
That list looks like its very available to me? The only overlap with software are two unmaintained projects.
It's incomplete. There's at least the Unison file synchronizer as well: https://www.cis.upenn.edu/~bcpierce/unison/
Re: The Unison language
#116Re: The Unison language
#117Earlier quoted context omitted.
Hey; Unison author here— Definitely appreciate this honest and helpful, specific docs feedback, so thanks for taking the time to put it together. We do want the value of Unison to be straightforward given even a quick skim of the site, so: sorry about the current state, we'll try to improve it. :)
No worries. I guess it sounded a bit antagonistic, I apologize for that. I am actually interested in the idea, I was just a little frustrated that it was hard to figure out what was different about the language.
It's mainly just an issue of manpower on our end (we do accept doc contributions, but probably we should be doing it); having fresh reader eyes on it like this is still valuable though.
Re: The Unison language
#1181) 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?
Re: The Unison language
#119Conflicts 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.
Re: The Unison language
#120At 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 sca…
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.