I’ve been thinking about this for a bit, and it extends on my previous idea of decomplecting human names with machine reference ids.
TL;DR: An IDE which works directly with Clojure semantics, and saves top level constructs into a database, any change to them creates a new version, meaning they are all immutable. You would need to specify which version you want on a per-use basis, or maybe per-namespace basis. When you actually wanted to run the code, it would create a Clojure source file projection so that you can bundle it and package it. You wouldn’t need git, since the IDE itself has all code versioned and immutable at the level of vars, macros, functions, and namespaces.
One could create the following environment:
- An IDE which would allow you to create namespaces, gobal functions and vars, not with text, but as part of the UX.
- You could move global vars between namespaces, maybe by drag an drop.
- Under the hood, the IDE would give the var a uuid, and the namespace would also be a uuid. It would add to the doc-string of each the name you gave it, using some convention. Could also be meta, but doc would work.
- At this point, it means that every namespace and global var you create have a unique reference-id of namespace-uuid/var-uuid.
- The IDE would not let you type text. The namespace and functions vars or value vars are UX construct, always balanced. You can add arguments, add doc, add pre/post, but the UX maintains consistent syntax.
- The implementation of the functions or the value to go in a var would be free-form text, with paredit or pareinfer.
- But, THE MOST IMPORTANT PART, each time you save, the namespaces, functions, value vars, and macros get stored in a database.
- You can freely change the doc-string, doc-name and meta, and it gets updated everywhere, but try to change the implementation, arguments, or pre/post conditions and when you save, it creates a new version of that construct.
- When you use one of these, you’d need to specify which version you want.
- I’m not sure namespaces are useful in that sense, but maybe it could ease the burden of having to define per-function dependency versions.
- Once you’re done, to run the code, it would create a source file projection, including only the constructs that are used.
- There could be a global database, so libraries wouldn’t really make sense anymore. No need for packages. Just top level constructs and their specific dependencies.
My only hesitation is that it greatly reduces the tools one can use, and its possible that dependency management would become a huge burden. For example, what if a function gets changed to fix a bug, woudn’t you want to automatically get the bug fix?
Maybe we could mix this with spec. You could attach a spec to a function and it could run generative testing on it after the change is saved. If it still passes the spec, reference to it would get auto-promoted to the new version. If it fails the spec, it would be flagged, and reference to it would continue to point to the old version.
Anyways, just some of my ideas for now.