Seems really good!
There's quite a lot of mathematical structure kicking around in there: Release
as the arrows of a category (Namespace
as objects); similarly Branch
(Namespace'
as objects); embedding of Release
into Branch
; functor from Release
down to the monoid that does Namespace -> Namespace
composition; similarly from Branch
with Namespace' -> Namespace'
; Causal
as a way of using a Semigroup a
to induce a join semilattice on Causal a
with some kind of free poset construction... not sure what it all adds up to but it feels rich and interesting.
I really like the way the Branch
/Namespace'
stuff is an enriched version of Release
/Namespace
, but with lots of symmetry between the two.
The sort of thing I'm struggling with is seeing how it all adds up in terms of UX. I'm sure you're way ahead of me here, and you've got a bunch of use cases in your heads that have motivated the model. Questions that I've got along those lines...
- What's a typical workflow, say for a few developers working on different topics?
- Does someone maintain a master release?
- Where in the old ways people would have made a commit, do they now make a Branch? How do things proceed as we build up several of those for a topic?
- Where can they see their version history? Presumably not in the underlying git repo, if there's a branch for every incremental change?
- Is the typical github PR now the addition of a branch? Or an in-place update to the master release?
- When is a branch
B
converted to a release? What are the implications of the loss of all the Causal history at that point? Will other people find it harder to merge onto that release, if they've been working concurrently with what was inB
, maybe sharing changes with it?
Here are a couple of questions which I'm sure demonstrate that I haven't understood things!
- I can't actually put my finger on why we need a commutative merge operation.
- Ditto I can't explain why we need
Causal
. I guess it helps spot when one edit is a merge ancestor of another. But why do we need that? - Why is
Causal
being applied on a per-name basis? i.e. why is itMap Name Causal (Conflicted Edit)
rather thanCausal (Map Name (Conflicted Edit))
?
- You've got
Edit
as a forgetful thing - it knows the new term but not the old one. I've got a feeling we're going to want to be able to reverse edits (and hence branch upgrades), so we should store the old value too.- Another motivation for this is observing that
Release
specifies an arrow, partly by specifying the new value of theNamespace
after the upgrade, and thinking of it just as a category, this is not a natural choice - i.e. it could just as well have been the old value.
- Another motivation for this is observing that
- If Alice renames a term from X to Y, and Bob renames it from X to Z, what's their experience when merging?
- How does conflict resolution interact with propagation? So, if term
f
has some conflicting edits, does that mean that all its transitive dependents have conflicts too? How does someone resolve that? - How are you going to render a
Conflicted Edit
to the user doing conflict resolution? Surely they want to know which source branches/releases each version of the edit is coming from, but I can't see how you'll know that. - Is this bit still current? "The namespace of a branch refers to the latest version of everything, propagated as far as possible. Anything else has the prefix old." Is doing propagations going to add a bunch of new names to the namespace automatically?
- Is it possible to rename a branch or a release?
- I have an urge to make it turtles all the way down: to make the names of branches and releases part of the namespaces we're trying to manage. Have you explored that line of thinking?
- Trying to work out the boundary between the unison codebase editor and the underlying VCS:
- is there a 'git blame' of any kind, in the new world? is there a history (of a term, a name, or the codebase as a whole)?
- is there a way to rewind the clock and get access to a previous revision in Unison-land, i.e. without using the VCS?
- How much of the codebase model will be internalised into Unison? Will I be able to talk about a Namespace or a Branch in Unison code, say if I'm using a
Codebase
ability? I have a smalltalk-ish desire for the answer to be yes: if Unison can describe its own UI domain model, and is its own domain language, then we might end up with a more consistent and composable world, in which Unison tooling can be written in Unison, and in which people can talk about Unison in the same universe as they talk in Unison.
- In your code for
Semigroup Causal
here, I can't work out if it's meant to be right-biased or left-biased - the first two lines make it seem like the former, and the next two the latter. Might have misunderstood though.
- You didn't define
Conflicted
in the 'model' section of the write-up.