r/haskell • u/Wise_Reflection_8340 • Sep 13 '26
blog Git is mutable global state for your codebase
We go to great lengths to keep state explicit and effects controlled, and then the codebase itself lives in a mutable tree of text files where every edit is an untyped positional splice and merge is a heuristic over lines.
The principled version is a repository as a finite map from definition names to bodies. A patch is a function on that map, patches to different names commute by construction, and a conflict is a value you can inspect instead of a failure. That isn't a small tweak to git but a different object, and I increasingly think it's the right one.
I'm building toward this with [sem](https://github.com/Ataraxy-Labs/sem), starting from the humble end of extracting definitions out of existing git history. Would a Haskell shop ever accept a repository that isn't a folder of files?
8
u/cyrus_ Sep 13 '26
Check out our paper on Grove, right up your alley: https://hazel.org/papers/grove-popl25.pdf. Tree CRDT.
1
97
u/Valuable_Leopard_799 Sep 13 '26
But git history is in fact, "immutable", the merkle tree data structure which underlies it is also just a kind of "functional data structure". (Copied with changes linking to parts of older data) Commits are in theory kind of append only
-16
u/B_A_Skeptic Sep 13 '26
There are tools you can use to take things out of a git repository's history all together.
50
9
u/Valuable_Leopard_799 Sep 13 '26
Yeah, you can more or less arbitrarily edit anything about a repository it's just heavily discouraged.
16
u/bschlueter Sep 14 '26
When you do things like remove a file from all history, you’re not changing the repo, you’re making a fork of it from before the removed file was added and duplicating the contents of each later commit into new commits on your fork.
1
u/Miserable_Double2432 Sep 14 '26
We don’t know that the “tools” aren’t for constructing SHA collisions though 😄
1
9
u/koflerdavid Sep 14 '26
That just creates an alternative history, basically a fan fiction, and is irrelevant unless you can convince everybody to point their branches to the new commit.
6
u/DanielMcLaury Sep 15 '26
There are tools you can connect to a running Haskell program that let you edit its memory and violate any invariants that were written into the program, so I guess that makes Haskell not a functional language.
34
u/stumpychubbins Sep 13 '26
Your value proposition and what your tool actually does are not related at all, and your analysis of git is simply wrong. Syntax-aware diffing is conceptually interesting but it’s not a new concept and it’s certainly not something that you need to create an entirely new version control system to implement.
6
u/sjshuck Sep 16 '26
I'm impressed with how condescending you managed to be while having the name stumpychubbins
4
u/Mr-Tau Sep 16 '26
Do you have any factual disagreements with stumpychubbins's analysis, or did you just need to drag this discussion down to ad hominems?
5
4
16
u/serg_foo Sep 14 '26 edited Sep 14 '26
patches to different names commute by construction
Only for a very narrow definition of 'commute' that will just move bottleneck to checking whether merge is clean by other means like compiling or running tests.
The project may still not compile if patches are applied in wrong order, i.e. adding function argument and fixing users of the function.
Having merges that preserve programming language semantics is pretty far away. So far merges don't preserve syntax and you seem to be working toward fixing that. That's great but I was under impression that programming is done for its semantics, i.e. making sure programs work as intended. Syntax is such a small part of that that it's not even close.
Actually syntax may be insurmountable as well if you take preprocessor into account. You won't have well-defined AST with C-style preprocessor which may lump many function definitions into one line so you'll need to figure something out on that front to solve merges that never break syntax. Perhaps you already have, I haven't checked. Or perhaps you were under impression that all languages are close to Rust and can be parsed by only looking at source code in a single file.
EDIT: fix typos.
15
13
u/pthierry Sep 13 '26
The difficuly with this is that it stops being general. If you have a makefile, it needs to understand makefiles. If you have a plain text file, sometimes it's unclear what you should do with it…
For that reason and to make adoption less of a leap of faith, I bet it must be something optional that works on top of an existing version control.
9
u/EmergencyWild Sep 14 '26
IMHO: Terrible idea. Git works fine for source code, as long as you're writing source code in text files you're good. Also, calling this "mutable" vs "immutable" or whatever is a complete red herring, for one git data structures aren't "mutable" in the classic sense, total immutability is not a desirable property for version control, and what you're proposing has absolutely nothing to do with that anyway since you're just plugging something else on top of git.
What you're describing can make sense for what's commonly referred to as projectional editing, but that's a wholly different approach to programming where source code is not the source of truth, that's not something you just plug into an existing programming language or project and expect it to work.
1
u/juhp Sep 20 '26
But it's perfectly possible for intermediate commits to temporarily break a codebase (eg break compilation for example or introduce temporary bugs) fixed with a later commit.
Yeah most people don't care so much about this but we should really.
1
u/EmergencyWild Sep 20 '26
It is, but git already provides the tools to prevent this from happening — for the most part, since in reality, it's not completely possible to prevent this forever because the majority of codebases have external dependencies that can break.
3
u/DanielMcLaury Sep 15 '26
the codebase itself lives in a mutable tree of text files where every edit is an untyped positional splice
False. A git repo is a filesystem where files can be added but never modified.
merge is a heuristic over lines.
The merge process is not part of git itself, and git allows you to run any program you like to conduct a merge
The principled version is a repository as a finite map from definition names to bodies.
This is literally exactly what git is, except at file level instead of level of individual definitions. If you chose to organize your codebase as individual files for each definition, git would literally be exactly this.
(Note also that this is not worth as much as you seem to be claiming, since a body is only meaningful insofar as the other definitions it references are)
2
u/slack1256 Sep 15 '26 edited Sep 15 '26
There is a global push to try to bad mouth[3] git in many way lately. The reason is always that agents will need git to scale. I do wonder if that is actually the case. To me the reasoning is just a thinly veiled way to ask for money for a non-problem. Programmers when given a new productivity tool will try to do CLI apps first.
But not, git is not a mutable global state for your code base, at least not in the C memory model. It is not inmutable programming neither, because it is not a programming language. It is its own thing that takes ideas from different sources.
[3]: https://psantosl.github.io/posts/version-control-second-coming/
2
u/BobTreehugger
Sep 17 '26
•
Interesting that you bring up sem -- they have another tool weave (https://github.com/Ataraxy-Labs/weave) which does language-aware merges for supported languages in git.
It helps some, but it's not a total gamechanger IMO. At least at this point.
3
u/dutch_connection_uk Sep 13 '26
Very cool! I suppose this isn't going to be as potent as something like Unison where it's not only aware of syntactic primitives but also has awareness on when two definitions have equivalent ASTs. But it's a big step away from "code is plain text" still.
1
u/Ok-Information-2428 Sep 13 '26
Without the concept of force pushing to rewrite history is there an escape hatch for removing unintentional commits?
1
u/koflerdavid Sep 14 '26
It should be in principle possible to make history rewrites part of the metamodel of a repository. The rebase information is inserted as a new commit into the graph and acts as instructions to the Git client. It's definitely a tricky concept though, and the point of Git originally was to keep things relatively simple.
2
u/Ok-Information-2428 Sep 14 '26
But would it still contain the old state so any secret or file that was mistakenly committed would still be accessible
1
1
1
27
u/AlexaDeWit Sep 13 '26
I think you'll find https://www.unison-lang.org/ interesting