Attending a conference today and yesterday about B...
# thinking-together
j
Attending a conference today and yesterday about Blockly, the visual code editing environment. Big push toward bi-drectionality between code and blocks. For integration with existing code-bases, AI generation, collaboration with people not using visual editors, etc. At least two different approaches being investigated or used, and I would be inclined to use a completely different one. They don't realize it, but some of their problems are solved by some of the tools people here are working on. Like how do you make it so that you can generate blocks when the text is in an invalid state? Much easier to just avoid invalid states, like Blockly does! How can you avoid invalid states if the person isn't finished typing, and there are mandatory subnodes in the AST? Much easier to fill holes by default, like Blockly does. Essentially, they can't get to bidirectionality, because the text editing experience is structurally unaware. It's not possible with VSCode, but it is possible with Tylr, or anything that imposes a structure. Even ProseMirror would work better. But there is no need to stop at two concrete syntaxes, if you can sacrifice interface specific details (e.g. whitespace in text, grid position in Blockly), or keep them where they live (linter settings, a database of block locations outside the AST), you can operate directly on the AST in whatever tool you want. Has anyone played with a "headless" AST that could be used that way? It feels like all structural editors need one, particularly if they hope to facilitate collaborative editing. Has anyone tried putting two different coding interfaces over the same shared AST?
Also, there was a suggestion that you could go from code to blocks by normalizing the code (standardizing whitespace, etc.) and then using some sort of evolutionary approach to build up a change to the block representation that has the same output as the text. Does that strike anyone else as WILDLY silly? The other approach I saw was adding the additional content relevant for the block language (e.g. X&y coordinates) as comments, and writing a JavaScript AST to Blockly XML transpiler. More reasonable, but limited to those two specific syntaxes, which seems short-sighted, and there are things that you can change in the text that will not survive round trips, which seems like a usability problem. Their use case was only to let AI write code, though, so that doesn't matter to them.
g
It’s a matter of semantic content and of discarding information. It is easy to go from a language that has more semantic content to a language that has less semantic content. But, it is difficult to go from a language that has less semantic content to a language that has more semantic content. Semantic content comes in forms other than sequences of characters (or sequences of vector graphics), e.g. structure and layout mean something to human readers. Going from Haskell to assembler makes sense, but, going from assembler to Haskell does not make sense. Likewise, if the VPL is any good, then going from VPL to code is easy, but going from code to VPL is difficult. N.B. if code->VPL were easy, it would imply that that the VPL adds no new information and is, therefore, redundant. A decent VPL should contain semantic meaning that is difficult to express in code. Hence, IMO, it makes no sense to even try to “round trip” code->VPL. For an example in a very different field - math - we are taught that we can multiply matrices, but, that we cannot divide matrices. Robert Distinti has developed a way to divide matrices and blames previous failure to do so on the fact that too much information is discarded by current methods. Aside: Note that, to me, a VPL is a hybrid of graphics and text (see SVG, for example). There is/was a field called “Design Recovery” that researched possible approaches to recovering semantic information (I witnessed such techniques being used for fixing Y2K problems, which would have been lessened if they had kept the source code and would not have equated “dates” with girls’ names in some of the code).
j
There are reasons to develop visually that don't have to do with adding semantic information. And the reason to be able to round trip might be to facilitate collaboration between people who prefer different interfaces, visual or text.
j
At least JetBrains MPS has been used to create DSLs with both visual and textual projections as well as (at least) writing to text files. Also my "projectional language workbench" generates a "headless" "AST editor engine" which can then be used, as you said, anyway you like. It exposes both the linearized version (for textual projections) and the tree structure (for visual projections). Currently I've only been working on the textual projection (which is a lot harder issue), but adding a 'blocky' projection should be just about writing the UI code. To read and write actual text files to and from the AST, a parser and an unparser should be implemented. Certainly possible but there's extra challenge in keeping the whitespaces when parsing and only writing minimal changes when unparsing. When parsing, the whitespace info should be stored in the AST that is then modified by the projectional editor. Now, it would be quite a bit easier if you wouldn't care that reading a text file, doing a minimal change in the projectional editor and writing back to a text file might change formatting for the whole file.
One approach to the text file round tripping could be to have the contents always follow strict formatting rules. Then the parser wouldn't need to care about formatting and the unparser would always just write according to those rules.
a
I've gotten as far as concluding that each projection, text or VPL or whatever, needs to have format-specific metadata associated with each abstract AST (that is, each individual document). eg the text projection will remember whitespace, the VPL projection might remember position constraints, color, etc. You need to handle defaults for the first time you project into a particular format, e.g. initial whitespacing. Probably there are also other hideous edge cases, the absolute worst intersection of naming things and cache invalidation; I'm sure the off-by-one errors are just waiting for their chance too. (I'm also thinking of this in the context of, say, bidirectional sync of documents in different formats).
g
“There are reasons to develop visually that don’t have to do with adding semantic information.” I would be grateful to learn more about this.
j
If your visual language is a one-for-one recreation of the text semantics, it may still, by virtue of being visual, allow you to use full words instead of symbols, illustrate the syntax structures, and make various kinds of syntactical errors impossible.
@Andrew F that's more or less where I have landed, too. But it feels easier to just say all that data is liable to be forgotten when you save and reload, because you aren't editing the interface, you are editing the AST, and those details have no meaning inside the AST, so just deal. But maybe that's too unfriendly.
a
As an answer to both @Jason Morris and @guitarvydas, friendliness is usually the core goal of a vpl. :) At least as far as I can tell. Otherwise we would just make people deal with syntax errors.
b
Tiled Grace (https://michael.homer.nz/Projects/TiledGrace) paper comes to mind.