Here is a brief description of my latest work in progress, which I am submitting to PPIG.
Direct Programming
To make programming more accessible to regular people it may help to make it less abstract and more concrete. Towards that end I am taking another run at the old ideas of macro recording and Programming by Example. Many such efforts abstracted user actions into conventional code. Instead I co-design the PL and UI to be analogous, so that programs and users have much the same capabilities, and programs look much like recorded transcripts of user actions. Conscientiously following this design principle leads in the opposite direction of current PL trends, towards a deeply imperative semantics and a de-emphasis of functional abstraction.
Any attempt to make programming more concrete faces two challenges: loops and conditionals, for they necessarily deal with hypothetical situations. My approach is to extend the direct manipulation metaphor onto template states that prototype iteration, and example states that witness alternative cases.
This submission is a demo of early-stage work lacking evaluation, and indeed it is submitted in the hope of receiving guidance on an appropriate evaluation methodology.
As always, comments and criticisms welcome.
Nice! I was very curious about how you handle iteration/loops and conditionals. I’m trying to do something similar in a VR-based environment but am struggling with these same issues. Not sure if your techniques will translate but they are certainly inspiring!
Hey Jonathan, this is amazing.
I’ve been thinking lately about all the troubles the beginners face with trying to abstract ‘methods’ before hand. I’m thinking that programming by example is for sure an easier way for them to make programs.
I’d love to play with what you have, is it available somewhere?
Also can you share a little about the stack you’re using to develop it? I’m curious about the stack, because it will mean how easy a person can start trying it out, for example if it’s a web site.
Thanks, it’s always great to see what you’re working on!
Thanks Daniel. I’m using Typescript and React, but just because I find that handy for this kind of UI programming. This is ages away from being ready for real users, or even for other researchers to play with.
Thanks for your response Jonathan.
Can you comment a bit about what would be the long term goal of the project? Also do you have a roadmap for the project?
My long-term goal is to noticeably improve programming, either through promulgating new ideas or an actual product. But my short-term goal is to just get enough things figured out so that I have a stable base on which to build, instead of rebooting every 18 months like I’ve been doing.
A tight distillation of your longstanding ideas. While programmers remain deeply entrenched in the plain text niche, other design software (CAD, 3D modeling, animation, and music) has been growing more parametric over the decade with [more](https://www.youtube.com/watch?v=f6ZLnitXMmU) and [less])https://www.youtube.com/watch?v=Yg_z0jyzY5s) hideous embodiments.
Your formulas have a certain concatenative feel `9 * 5 / 32 +`. Concatenative languages share the nice quality that any sequence of steps can be [factored](http://factorcode.org/) out. They’re also notorious for [stack shuffling words](http://docs.factorcode.org/content/article-shuffle-words.html). Where textual linearity forces order on concatenation, time linearity forces order on direct manipulation. Ultimately stack shuffling corresponds to shifting attention in the direct manipulation context.
When linearity is relaxed, we naturally end up with [flow diagrams](https://johncarlosbaez.wordpress.com/2018/05/19/circuits-bond-graphs-and-signal-flow-diagrams/). Node-based editing follows. These graphs have the virtue of making data-flow more explicit (some systems allow for side-effects) and can show intermediate results. Archimatix shows a preview at the bottom of a node. Your example shows a preview to the right of each step after a blue arrow.
That sounds right to me, William. My strong intuition is to hug the linear end of the spectrum, with only nesting of linear expressions as right-hand arguments to binary operations. Use records for keyword parameters.
I played with similar ideas in the context of a “shell”, that is, where all commands are given as text. You could loop over an array by using “each 5 4 3”, where 5, 4, are references to the worked example, and 3 is the array to loop over.
Example here: http://inimino.org/~inimino/blog/activeshell_aiclass
I also “rebooted” after about 18 months and subsequently worked on other things, but I believe programming by example has tremendous promise and can be made quite powerful.
Interesting, but I don’t understand how ‘each 5 4 3’ works. 4 is a last verb.
In the context of the “each” verb, 4 represents an example value, and 5 represents an output that was calculated using that value. What it means is “take the calculation that created 5 from 4, and then map it over the values of 3”. The calculation of 5 from 4 is in this case the single caesarcypher verb, but it could be any arbitrary number of steps, and there’s no requirement that the example value came from the array we are iterating over (although the types should match).
It can be done in two steps with a “lambdify” verb that extracts part of the dependency graph into a function and then a map application, and this is what the each verb is doing internally, like so:
lambdify 5 4
map 3
However, I was trying to get away from exposing abstractions like the extracted lambda, so I rolled these two steps into the single “each” verb… it means the *only* way to do iteration is actually to start with an example value, calculate the output that you want, and then refer to the example input and result in an “each”.
Sorry, some formatting was stripped, but the two lines of code should be:
lambdify 5 4
map <that result> 3