I've read the central paper on Algot: "
Bridging the Syntax-Semantics Gap of Programming". Salient points [my opinions bracketed]:
It's PBDemonstration, where user conveys intent by actions, and not PBExample where intent is inferred from before/after or input/output pairs. They attack the gap
during program construction, admit it's weak for later comprehension.
State is
graph with nodes containing numbers (to be extended in future). Graph for pedagogical reasons โ covers structures they want to teach + visualization is
universally understood.
[Target audience not explicitly stated; seems to be for beginning CS students? I'm personally more interested in PBD for end-user programming; but then I wouldn't teach them linked lists or binary search trees...]
It's showing concrete data when directly-manipulating top-level state. ๐ฐ
But when demonstrating a procedure ("helper"), in Input stage you denote parameters (+ pattern matching) by adding "abstract" nodes. IIUC new nodes created during your hepler are also abstract? Unlike concrete state nodes, you won't see abstracts' value at Action stage ๐, only their label letter. (Also, not all nodes will exist in all executions โฅ)
[This is serious unsolved gap! Inherent question of how PBD can be parametrized โ you don't see
actual semantics, but some โsymbolic approximation.]
They aspire to improve this in future by letting you pick example inputs and see actual values [they cite
https://arxiv.org/abs/1902.00549 which is good read and
wonderfully-motivated title]
They believe nested conditionals and loops to be confusing for beginners.
=> No loops, only recursion.
=> Boolean checks can only be made in Query stage before procedure starts (pro: order doesn't matter), and then Action stage code is
flat, with
optional predication โ each step may be conditioned on each query being true/false/don't care. [Heresy #1 ๐ค Personally I'm skeptical flatness scales well to complex codebases?]
Con: if you need checks and/or pattern matching depending on prior checks, you'll want to extract a 2nd procedure. Each procedure has Input+Query stages, so not really as flat as it sounds! (technically they reduce the need by allowing empty-set pattern matches [?] but they admit guard-before-access is mentally clearer.)
[Most interesting heresy ๐๐ฎ #2, emphasis mine:]
4.1 State Should Be Relatable, Visible and Editable
... Conventional imperative languages such as C, Java, and C#, also separate state into local variables on the stack and objects living on the heap. This separation can be confusing and lead to misunderstandings.
... Even systems designed for beginners like Scratch tend to scatter state by maintaining variables, position for individual objects, or drawings on screen. We believe that a scattered state leads to additional cognitive overhead and instead intend to maintain a single central state. Algot avoids variables as separate entities from other state.
โข Instead of local variables, one is supposed to insert a new (disconnected) node to the global graph, mutate/grow connections, and remove it from the graph when done. (you do bind a local name to it, but that's immutable โ the state lives in node's content and connections, and cosmetic โ you don't really reference by name, you click it)
โข They didn't 100% banish scattered stack state: Procedure parameters get bound (by ref.) to concrete nodes given as arguments โ so there are hidden activation records somewhere.
โข The recursive examples given do materialize in global state parts of what'd usually be implicit in stack ๐. E.g. fibonacci works with explicit linked list of prior results. Is this purely stylistic? No, it's encouraged by IIUC
not having return values! [interesting heresy #3! ๐ฎ] Procedures can "return" results by mutating the global state graph (possibly via output parameter pointing there). Even builtins like "add" take assembly-like src1, src2, dest.
[All in all, my first instinct was to protest, but the goals are interesting and the choices nicely provocative ๐ค]