Difference between revisions of "Annotated lambda diagrams visual rules"
m |
(added section == Alternative variants ==) |
||
Line 156: | Line 156: | ||
This requires some canvas solutions for local only redrawing for rendering efficiency. <br> | This requires some canvas solutions for local only redrawing for rendering efficiency. <br> | ||
This enables some options for smooth animations despite the basis on boy drawing characters. <br> | This enables some options for smooth animations despite the basis on boy drawing characters. <br> | ||
+ | |||
+ | == Alternative variants == | ||
+ | |||
+ | Allowing applications coming in from below, adding these additional wire elements ┬,┘╯<br> | ||
+ | The original unannotated [[lambda diagram]]s featured that option. <br> | ||
+ | |||
+ | Allowing for ┼² where an application line bridges over a value line. <br> | ||
+ | Adopting this would likely lead to an unreadable mess. <br> | ||
= External links = | = External links = | ||
* https://en.wikipedia.org/wiki/Box-drawing_characters | * https://en.wikipedia.org/wiki/Box-drawing_characters |
Latest revision as of 23:18, 3 December 2024
Contents
[hide]Natural choice for datastructure organization
An "ALD-closure" consists of a sequence of "ALD-lines".
An "ALD-line" consists of a sequence of "ALD-slots" (roughly characters).
Visual rules (to review)
For now this is for the only downward turning variant of ALDs. This …
… gives a much more unabiguous mapping between
the codes AST and the semi-visual structure of the AST.
… makes for an easier programmatic implementation.
General format in the following:
- [symbol, ok above, ok below, ok left, ok right]
Value wire rules:
- [─ , ANY, ANY, {char,─, ┼, ├}, {char, ─, ┴, ┐} ]
- [┴, {│², ┐}, ANY, {char, ─, ┼, ├}, {char?, ─, ┴, ┐}]
Application wire rules:
- [{┐,╮}, ANY, {│²,┴}, {char,─, ┼, ├}, ANY]
- [│², {│², ┐, │¹, " "}, {│², ┴, " "}, ANY, ANY] (│² is one visual appearance of an application wire)
Function arguments are corresponding to abstraction wires.
Abstraction wire rules (LS means line start):
- [│¹, {│¹, ├, ┼, " "}, {│¹, ├, ┼, " "}, {LS, │¹}, {│¹, ├, " ",│²?}] (│¹ is one visual appearance of an abstraction wire)
- [├, {│¹, ├, ┼, " "}, {│¹, ├, ┼, " "}, {LS,│}, {┼, ─, char, ┐?}]
- [┼, {│¹, ├, ┼, " "}, {│¹, ├, ┼, " "}, {LS,│}, {┼, ─, char, ┐?}]
The initial part of a line starting from the line-start LS
is the only place where application wires are allowed.
It must be all application wires with no gaps.
Internally │¹ and │² may be represented differently.
Rules for the leading abstraction section
Abstraction wires {│¹,├, ┼} must be compact (packed from left).
A line with ├ is "active" and enables value operations. Only one ├ per line allowed.
A line without ├ is "passive".
Passive lines preceding lines with more abstraction wires may contain argument names:
– Space-separated (and or line-break separated) list identifying abstraction wires
– An underscore _ marks anonymous arguments
– Trailing unnamed wires (omitted _) are treated anonymous too
Notes on low level ALD transformation operations
Note that these are meant as low level base operations.
UI interface operations should build on them to make for a nice UX.
See "typing normally" section further below for details on that.
Building up and evaluating a lambda calculus based language with some visual transformation rules
may be a really weird and wildly inefficient approach for a programming language. Yes.
A more normal (and in the long run perhaps better) approach would be
a normal lambda calculus evaluator as basis and then a projection function.
Here the focus though is to get from the static mockups here to interactive graphics ASAP with minimal effort.
Conversion/projection from lambda-expression based closures to ALD-closure-diagrams is dauntingly non-trivial.
Especially when wanting to avoid batch processing full redraws.
Here application of visual incremental transfromation rules (that is needed anyway)
should naturally lead to a (very inefficient) way of evaluating the code.
Semi-visual substitution corresponding to beta reduction.
Removing a line
A passive line can always be safely (no semantic changes) removed except
if both adjacent lines (above & below) have more abstraction wires {│¹,├, ┼} than itself.
As this would merge distinct abstraction lines.
Removal of an active line means …
★ one needs to (recursively) back-trace across preceding lines to the dependencies
★ one needs to forward-trace across followup lines to dependents
It may be code simplifying and usability improving to support / allow-for
forbidden states (tracked and explicit !!). That is, allow for:
– unused value results ┐(╵dead end to below) and
– unfulfilled applications ┴ (╷dead start from above, )
Latter one is feeding in a BOTTOM value outside the expected type (if types are managed). 404: crickets.
The symbol for bottom "⊥" is kinda too close to "┴" so we may want to use an alternative.
Idea is to have partial live coding program execution (like in spreadsheets).
Adding a line
TODO
Adding/removing a slot
This may require adding slots in other directly or transitively adjacent lines too. Shifting the ┐will shift the below so far it's not disconnected. Shifting the ┐to the right with no free space " " before a │² will shift the │² (and the follow-up too).
Picking a value from abstractions (or swapping the to a different pick)
Potential for mouse UI:
- Passive line: Click on the application wire to extract the value from.
- Active line: Click on the application wire to switch to. If types are managed induced type mismatches may break wires.
- Click on the argument name further above then on the line where to extract it.
- Click on (or arrow key navigate towards) a line and start typing the desired name (see section "typing normally" below)
Also related here is the potential option of
swapping argument order and corresponding application wires order by drag-n-drop of names or wires.
Picking an application from values
Similar to picking a value from abstractions.
But the position of the line may not allow for access to the desired value that one wants to apply.
Thus the line with the value wire extraction may need to be (auto) re-positioned.
Potentially even needing an introduction of a let … in … structure?
Allowing for application wires crossing over value wires ┼² would be an option but
would lead to a horrible unreadable mess and reduce the uniqueness degree of the visual representation.
Principle: Typing normally
Desired for a good interface (UX) is that there's no need to laboriously draw all the wires,
But instead that one can "type normally". ("Normally" meaning: As is established in textual code editors).
Typing a function name shall automatically add the corresponding value wire (and abstraction wire if not yet present). Typing an argument name shall automatically add the corresponding value wire on an (as close as possible) preceding value wire line (and abstraction wire if not yet present).
Principle: All keystrokes cause visible reactions
Hitting keys and noting happens is extremely frustrating and the quickest way to lose alpha testers.
Even for illegal edit attempts there needs to be an instant conspicuous response for why this is not possible.
(and perhaps suggestions for what to do instead).
Edit time immutability
Note that in fully expanded view ALDs shall make their "edit time immutability" explicit.
That is "changing" hard-coded input does not change the diagram
(does not change the active path ═) but instead makes a new diagram.
Shades of gray may gradually change as fancy visual indication that one switched to a different static codebase universe.
An undo history falls out naturally from this.
For a galaxy brain moment: Hard coded input shall extend to the programs (ALDs) structure itself!
And the sequence of edit calculus operations on the AST. Challenging with the approach here.
Side-note: Individual keystrokes may be ephemeral but
hitting enter or jumping elsewhere with arrow keys shall make for an extension of history.
Misc ideas
Double lined or fat box drawing characters {─, ━, ═}
could be used to indicate the active control flow path.
There are transition characters. Adding a bit of coding complexity.
related to section "edit time immutability above"
The shape of the top element of every application wire {┐,╮} could be used
to indicate immediate or delayed evaluation respectively.
Visual scaling extension
Annotations may be replaced by previews of their ALDs.
By scaling down by a whole multiple x2 x3 x4 one can match the monospace font grid.
This requires some canvas solutions for local only redrawing for rendering efficiency.
This enables some options for smooth animations despite the basis on boy drawing characters.
Alternative variants
Allowing applications coming in from below, adding these additional wire elements ┬,┘╯
The original unannotated lambda diagrams featured that option.
Allowing for ┼² where an application line bridges over a value line.
Adopting this would likely lead to an unreadable mess.