"Interact":
https://github.com/d-cook/Interact
(continuing from previous) ... So the minimal UI would just expose the raw structure of everything, and provide a way to execute / evaluate code. (That's not the end goal, but I'll get back to that later)
Entities (strings, numbers, lists, functions, etc.) sit freely on a canvas, where they can be moved around, inspected, expanded/collapsed, etc.
Dragging values onto a function causes the function to be evaluated with those "arguments", and the result appears as a new entity on the canvas. Since there is a function for every basic operation, this is sufficient for making every kind of manipulation
possible (but not necessarily ideal - I'll get back to that!)
(Certain basic things like getting or setting a value could be as simple as drag-and-drop; but I'll get a working tool first, and then use the tool itself to see what works best for what -- let's call that "phase 2")
Either way (e.g. whether the UI "helps" or not), any sequence of operations that can be done -- whether through user interaction or by evaluating "code" -- directly corresponds to sequence of (nested or otherwise) function calls. Therefore, by recording and replaying actions taken, all code can be created and viewed as direct interactions, rather than as the textual or structural representation one normally thinks of as "code". *(From here I might use "code" and "actions" interchangeably)
So essentially you can do a bunch of manipulations, and then say "See what I did? Call that a function, and THIS value here is the result". And then edit the *actions and/or the object that represents the new function to replace certain values with arguments, etc.
Now whereas "normal" code references values by identifiers (e.g. looking up variables by name), the user is able to just "grab" values that are just sitting there. So under the hood, code is stored as a list of actions, which contain either simple values or the index of some other action (referring to the result of that action) ... In other words, it's a DAG.
When viewing / editing a function, actual values are substituted from the arguments, and you are shown the "aftermath" of the actions (i.e. values on a canvas), as if you had performed all the actions yourself. Changing any actions or values causes the whole thing to recompute (think FRP)
This means that any operation you do becomes part of the current "function" you are editing. I'll provide a way to "cut" dependencies though, so you can use the canvas as an interactive REPL, and then either throw out the results, or "forget" how it was computed and just use the generated value directly. I could also have a "cleanup" that will throw out all intermediate operations that did not contribute to the ultimate result of the function.
All editing is done in a function, so even the "top level" (global scope) is a "function" with its own record of actions taken. This also means that all the work of "programming" you do is recorded as some step somewhere, giving you multiple layers of undo/redo. Anything you do can be abstracted into a function and edited for generic reuse. E.g. "Here's how I do x to the code"
... Anyway, I'm getting lost in low-level specifics. I'll tie this up in another reply