Visual Coding: Drawing Parallels

There are many visual representations of programs, there are even various possible interpretations of the same visual representation. In this article I compare Blockly with Node-RED code. Blockly is a form of programming that reminds me of LEGO® MINDSTORMS® and the early versions which used a similar visual paradigm to allow children to program their robots.

I never found that visual representation to be either intuitive nor easy to understand but then again, I cannot play the piano either! Everyone is different and everyone has a different analogy when it comes to programming algorithms. Therefore we as programmers should be careful in the selection of our representations.

TL;DR: We as programmers should choose representations of algorithmic solutions that is understandable by our audience and not necessarily by us. We are, after all, not coders but programmers and as such, we also program our audience with our words. Sometimes knowing the audience might be difficult, it should not be an excuse for not making an effort.

img

Described are my thoughts on the visualisation of a specification in different representations. The following Javascript[1] one representation, in a textual representation. I will present this same logic in various representations to transfer an idea to the reader: our audience is more important than us when selecting a representation of the underlying ideas we wish to transfer.

Javascript

This article will discuss the following Javascript code:

msg.versions = msg.versions || {};

var module = msg.modules.pop();

if ( !module ) {
    return [ 
        undefined,
        msg
    ]
} else {
    return [
        {
            ...msg,
            url: "https://registry.npmjs.org/" + module.id,
            module: module,
            requestTimeout: 2500,
            isempty: msg.versions[module.id] == undefined,
        },
        undefined
    ]
}

That code represents in Javascript an interpretation of the following english specification:

First set the versions property on the msg object to an empty object but if and only if, the versions property does not yet exist, on the msg object. Next, a module is retrieved from the end of the modules list. If there is no more modules, an array with the first position being empty and the second position set to the msg object is returned. This then becomes the respective first and second outputs of the node.

If there is a module defined, then set various properties on the msg object: url to the registry at NPMjs.com, store a reference to the module object, define a maximum request time of 2500 milliseconds. Meaning that if the request to NPMjs.com takes longer than 2.5 seconds, the request is cancelled and an undefined value is returned. And finally a flag is set to indicate whether there has already been a value retrieved for the module. The versions property on the msg object stores all retrieved objects for all modules and is initial taken from the flow context. That implies that we might already have retrieved the details of the module, if so, do not make another request - but that logic is not implemented in this node.

The specification above is also a program: it is in english and is designed to program a human that understands english. The program is a means to convey a common understanding of what the Javascript code does and is conveyed from the writer to the reader. A writer hopes to transport their ideas to as many readers as possible. But this, especially in form of an english specifications, sometimes does not succeed. English is not a language as succinct for example, as a computer language. This leads sometimes to confusion.

The writer of the specification only intends to transfer the basic ideas, a reader does not have to translate that in to Javascript code, they may select another representation, perhaps as nodes in Node-RED.

Node-RED

How can this code be represented in Node-RED? The simplest representation of the Javascript code, is also the one that transfers the least understanding:

img

Function 23 is a function node that contains the above code, once the editor is opened, the code is shown:

img

Using the Node-RED basic nodes, the code can also be represented using the following five nodes:

img

Suddenly the code becomes more expressive and understandable, to the potential detriment of clarity in the overall flow. These nodes are viewed outside of their contexts, the Function 23 node resides within this complete flow:

img

The node I have taken for this example is marked in red. I find that within that context, a single function with “complex” Javascript code is a clearer solution than having five nodes - especially since I copy & pasted the node four times. Admittedly I have not cleaned up that part of the flow, mea culpa!

This is of course my taste and the readeras mileage might well vary. For me the expressiveness of a single Javascript node is ok since the functionality is not core to what the overall flow does: the flow creates graphs for an analysis of the Node-RED third-party node packages. There is the retrieval logic secondary in my opinion. Greater focus is placed on the creation of the graphs, hopefully thereby the understanding of what the entire flow does can be attained rapidly.

Blockly

Blockly is:

The Blockly library adds an editor to your app that represents coding concepts as interlocking blocks. It outputs syntactically correct code in the programming language of your choice. Custom blocks may be created to connect to your own application.

In Node-RED, the integrated Blockly node looks very much like the function node, just a different colour and icon:

img

However opening the Blockly editor for the node and a visual representation of the code is shown, in form of blocks:

img

This representation is converted to the following Javascript code:

img

From the generated Javascript code, I can be fairly certain that the Blockly representation is indeed the same code. That is reassuring since it took sometime to put together the blocks to create the code.

As someone who has been a programmer for a long time, I find the Blockly representation confusing because of the nesting of statements, the setting of the isempty property is the best example of what am I referring to:

img

If had not created the Blockly code, I would have to look at it least three times before I really understood what was happening!

For me, the single line: isempty: msg.versions[module.id] == undefined is far more understandable. Not because it might arguably be conciser[2], it is not conciser since concise is taken in context of the audience. For me and myself that code is conciser. The Blockly representation might be more confusing for me but for the intended audience, it might well be the conciser form.

UML

There is another representation but one that is “read-only”: its modification does not affect the underlying code:

img

Both Blockly and Node-RED nodes can be modified and those modifications become part of the final algorithm. That is not the case with UML, all modifications to the diagram would be transferred manually to the underlying code representation of the algorithm.

This representation might be understood by yet another audience, those that do not understand either blocks nor nodes nor code. For me, UML represents the most work (because of the manual transfer) but if it gains the broadest understanding of the ideas being transferred, then thats for me to accept.

Audience

The audience is more important than our understanding. We as people want to communicate our ideas and messages to the broadest possible audience. We as programmer can understand many forms that a program can take however we should make an effort to transport those ideas in a form that our audience best understands, not that we understand.

For me, explaining algorithmic ideas to others is not about demonstrating how smart I am nor is it about confusing the listener, its about transferring and sharing knowledge because only if someone else understands can knowledge sharing truly begin.

Last updated: 2023-11-14T09:43:22.320Z

  1. All code for this article can be found at FlowHub.org. ↩︎

  2. Concise is for me the point whereby understanding is transferred in the shortest representation possible. If the line of code does not pass on the correct knowledge to the intended receiver, then the representation is not concise instead its rubbish. The consequence is that the representation needs to become more verbose. ↩︎


Comments powered by giscus

The author is available for Node-RED development and consultancy.