Monday, October 01, 2018

Visual Programming - Why it’s a Bad Idea

Note. This post had a great response on Reddit with over 300 comments. I’ve added an update section to the end of this post to address some of the main criticisms.

A visual programming language is one that allows the programmer to create programs by manipulating graphical elements rather than typing textual commands. A well known example is Scratch, a visual programming language from MIT that’s used to teach children. The advantages given are that they make programming more accessible to novices and non-programmers. There was a very popular movement in the 1990’s to bring these kinds of tools into the enterprise with so called CASE tools, where enterprise systems could be defined with UML and generated without the need for trained software developers. This involved the concept of ‘round tripping’, where a system could be modelled visually, the program code would be generated from the models, and any changes to the code could be pushed back to the model. These tools failed to deliver on their promises and most of these attempts have now been largely abandoned.

So visual programming has failed to catch on, except in some very limited domains. This is fundamentally attributable to the following misconceptions about programming:

  • Textual programming languages obfuscate what is essentially a simple process.
  • Abstraction and decoupling play a small and peripheral part in programming.
  • The tools that have been developed to support programming are unimportant.

The first misconception holds that software development has significant barriers to entry because textual programming languages obfuscate the true nature of programming. The popularity of Scratch among educationalists plays to this misconception. The idea is that programming is actually quite simple and if we could only present it in a clear graphical format it would dramatically lower the learning curve and mental effort required to create and read software. I expect this misconception comes from a failure to actually read a typical program written in a standard textual programming language and imagine it transformed into graphical elements of boxes and arrows. If you do this it soon becomes apparent that a single line of code often maps to several boxes and since it’s not untypical for even a simple program to contain hundreds of lines of code, this translates into hundreds or even thousands of graphical elements. The effort to mentally parse such a complex picture is often far harder than reading the equivalent text.

The solution for most visual programming languages is to make the ‘blocks’ represent more complex operations so that each visual element is equivalent to a large block of textual code. Visual workflow tools are a particular culprit here. The problem is that this code needs to be defined somewhere. It becomes  ‘property dialogue programming’. The visual elements themselves only represent the very highest level of program flow and the majority of the work is now done in standard textual code hidden in the boxes. Now we have the worst of both worlds, textual programming unsupported by modern tooling. The properly dialogues are usually sub-standard development environments and enforce a particular choice of language, usually a scripting language of some kind. Visual elements can’t be created except by experienced programmers, or understood except by reading their underlying code, so most of the supposed advantages of the visual representation are lost. There’s an impedance mismatch between the visual ‘code’ and the textual code, and the programmer has to navigate the interface between the two, often spending more effort on conforming to the needs of the graphical programming tool than solving the problem at hand.

Which bring us to the second misconception, that abstraction and decoupling are peripheral concerns. Visual programming makes the assumption that most programs are simple procedural sequences, somewhat like a flowchart. Indeed, this is how most novice programmers imagine that software works. However, once a program gets larger than a quite trivial example, the complexity soon overwhelms the novice programmer. They find that it’s very hard to reason about a large procedural code base and often struggle to produce stable and efficient software at scale. Most of the innovation in programming languages is an attempt to manage complexity, most commonly via abstraction, encapsulation and decoupling. All the type systems and apparatus of object-oriented and functional programming is really just an effort to get this complexity under control. Most professional programmers will be continually abstracting and decoupling code. Indeed, the difference between good and bad code is essentially how well this has been done. Visual programming tools rarely have efficient mechanisms to do this and essential trap the developer in an equivalent of 1970’s BASIC.

The final misconception is that visual programmers can do without all the tools that have been developed over the decades to support programming. Consider the long evolution of code editors and IDEs. Visual Studio, for example, supports efficient intellisense allowing the look-up of thousands of APIs available in the base class library alone. The lack of good source control is another major disadvantage of most visual programming tools. Even if they persist their layout to a textual format, the diffs make little or no sense. It’s very hard to do a ‘blame’ on a large lump of XML or JSON. Things that make no difference to the functional execution of the program, such as the position and size of the graphical elements, still lead to changes in the metadata, which make it harder still to parse a diff. Textual programming languages have learnt to separate units of code into separate source files, so a change in one part of the system is easy to merge with a change in another. Visual tools will usually persist as a diagram per file which means that merges become problematic, made harder still when the semantic meaning of the diff is difficult to parse.

In conclusion, the advantages given for visual programming tools, that they make the program easier to create and understand are almost always a mirage. They can only succeed in the simplest of cases and at best result in the suboptimal situation where the visual elements are simply obfuscating containers for textual code.

Update…

I was probably wrong to use a screen-shot of Scratch and use it as the primary example in my first paragraph. I’m not an educator and I don’t really have an opinion about Scratch’s effectiveness as a teaching tool. Many people say that they find it enormously useful in teaching programming, especially to children. Anything that introduces more people to the wonderful and exciting world of programming is only to be celebrated. I really didn’t intend this post as a criticism of Scratch specifically, it was simply the visual programming system that I thought the largest number of people would have heard of.

Another counter example cited on Reddit were static structure tools, such as UI designers, database schema designers, or class designers. I agree that they can be very useful. Anything that helps to visualise the structure of data or the large scale structure of a program is a bonus. These are never enough on their own though. The ultimate failure of 90’s tools such as Power Builder that attempted to build on graphical visualisations to create a fully code-free development environment attest to this.

36 comments:

Dave Newton said...

So, it's not a bad idea in the situations where it works, then. (And you're missing some other places where it *is* a demonstrably good idea, like process control.)

I'm not going to teach my robotics class to code in C--I want them to actually get something working. This includes things you're saying aren't represented in visual programming paradigms, e.g., interrupt handlers and co-routines, which exist, and are fairly easy for kids to grasp. It's the same with anything: things need to be introduced piece by piece, and the vagaries of typing, "special" characters they don't normally use, error outputs in the console... just no. It's too much cognitive overhead for something they're simple not able to deal with in short, one-hour a week sessions.

Is it a bad idea for me, a (all-too) seasoned programmer? Not always, no. I'll build my apps the old-fashioned way--but even I use blockly-like programming for quick-and-dirty stuff, or composing things I've already written.

Blanket statements like "IS BAD MKAY" are disingenuous.

Anonymous said...

"I do not think that word means what you think it means."
https://www.dictionary.com/browse/textural

Anonymous said...

Note that "textural", an adjective you use ubiquitously, refers to textures. I believe you mean "textual", relating to text.

Anonymous said...

The properly dialogues -> property

Joe said...

this is the call on the emperor's new clothes

Anonymous said...

Dude, have you even heard of Houdini? Unreal engine? For a "Bad idea", visual programming is doing quite well for itself.

Mike Hadlow said...

There are lots of good comments on this on Reddit:
https://www.reddit.com/r/programming/comments/9kgk75/visual_programming_why_its_a_bad_idea/

Unknown said...

You are confusing graphical dataflow languages (the ones with the boxes with hidden options and arrows connecting those boxes) with what Scratch does. Scratch is a text language where the program statements and types are predefined shapes to eliminate syntax errors. You cannot make a syntactically-incorrect language in Scratch as the boxes don't fit together. Beyond this syntax help, Scratch doesn't hide anything and doesn't format differently from a pure text language.

That said, I do agree with much of what you say in regards to other educational languages, such as are used for the Lego Mindstorms robot kits. That language is derived from LabView, and most beginners find it pretty difficult to move beyond a few blocks or to wire in things like variables. My guess is that a language that hits a complexity barrier with variable assignment is not going to scale well :-).

Gael Sa said...

Wow thank you for this article, I completely agree and at the same time completely disagree.
You are on point that programing can't be summarized to block and arrow.
At the same time, if all textual command could be made visual maybe we could have a visual language that could come close to a real interpreted language.
What if all keyword, variable and functions would have visual counterparts?
Maybe it is not about making programing more accessible but more about creating a visual programing language, one that could match the complexity of a standard textual language.

AnimationDot said...

Some forms of visual programming is good for learning the basics and once you learn what you are doing then it get a lot easier to text elements to create more advanced programs. However, it is a bad idea to only use block type visual code.

Jake said...

I think the premise of your article is wrong. Visual programming isn't for programmers.

Nova said...

I wonder if the author has heard if Pure Data. Yes, is mostly for music, but is visual programing done right.

Andy said...

While I agree that all these problems plague most visual programming languages, I disagree that these are inherent problems with visual languages. Perhaps they are inherent problems in visual languages that are representing imperative paradigms.

Consider a functional dataflow language with haskell-like types - text dataflow languages are really just constructing a DAG - not mutating state in an imperative style.Now consider that you can either define that DAG via textual (parse->AST->DAG) or visual (directly manipulate DAG). If you could easily switch between these representations, have a solid type system, 1st class functions and use modules instead of a single text file it wouldn't have any issues. The problem with visual languages is that they are usually not very good languages and that "structural"/low-level things are easier to deal with as text, but (for dataflow languages at least) high-level structures are more suited to visual representations.

Unreal's Blueprints are a pretty good example of how imperative programming language can work visually, your point about not being able to fully understand a program without looking at the corresponding c++ is totally right but in practice the intended audience isn't actual programmers so it's actually been really valuable - even at AAA studios.

Perhaps a better example is LabView or Reaktor - both of which feature highly complicated, encapsulated code completely written in the visual language. The problem is that writing low level code in these languages is super complicated (for the reasons you listed in the article), but the payoff of being able to do the high level "business logic" visually is really big. If a language could be represented expressively in both text and visual formats, and diffed using the textual representation, I think it would be very powerful (of course for specific domains).

DeaconNickelodeonLogan DNL said...

Yeah I don’t like codes

Tarik's Blog said...

Visual Studio offers tools such as ADO.Net or Entity framework designers which are excellent to quickly get the data structures and code to interact with a RDBMS. Another example is SSIS on MS SQL server. Workflow designers are also useful. I mean to say that hybrid is good.

Alfa_ Q said...

This has to be a joke article, right...?

Greg J said...

Using Scratch as a blanket for all visual programming seems a little disingenuous. I also doubt the creators of Scratch believe your misconceptions. It was created for a specific purpose and the underlying code is not simplistic.

Take a gander at something like RFML from Red Foundry or the entire Mendux ecosystem for better examples of visual programming.

One big reason why it is a good idea where possible is that it is clear. And in a world being swallowed by poorly written bug ridden software I think this reason is quite worthwhile.

Unknown said...

Simulink and Labview are both excellent visual "languages" for certain tasks and people.

CrazyEyes said...

"Visual programming isn't for programmers."
He specifically discusses tools that were supposed to make professional programming visual using UML, so yes, visual programming was indeed at one point "for programmers."

"So, it's not a bad idea in the situations where it works, then."
That's a statement that can be applied to literally anything. Zeppelins work when the gas bubble is totally secure and there are no ruptures or flames that go near it. Yet, for some reason, we don't use them any more. Just because an idea isn't applicable in every single situation does not mean it is "good."
"I'm not going to teach my robotics class to code in C--I want them to actually get something working."
Why not write a robotics library for C (or whichever language you choose) and allow your students to make robotics code that scales, while circumventing the issue of your students writing robotics firmware? Honestly if you told me a robot was designed using visual programming, I wouldn't buy it, let alone allow it to handle my things.

William Payne said...

I agree that dialog boxes as an input mechanism are terrible. Anything that splits the code up at too fine a level of granularity and that gets in the way of fluid navigation is going to be terrible for usability and productivity, but I don't see this as a necessary result of trying to explore different representations of program logic.

My personal preference would be to use YAML as a textual modelling language, combined with Python or C for functional components; with navigation and understanding aided by generating various visual representations of the system: Most usefully at the level of systems and components, but without limiting finer granularity representations (dependency graphs, control flow graphs, data flow graphs, parse trees, etc.. etc..) either.

UrsulaMinor said...

I used to do seismic data processing before I became a software Developer, and a most of the programs we used were very similar to the visual languages described by the author. We built processing flows (or program diagrams) out of blocks connected together with arrows, with most of the parameters of each block burried in the settings. All of this is to say it was a way of allowing non programmers to do programming like work, without training as coders on top of training as geophysicists. This is, to me, the correct application of visual languages. I dont think we ever should be using them as a primary tool to build software, but they are damn useful in allowing others to do very complicated tasks within software, especially when we are talking about data analysis.

Unknown said...

I agree with source control, the increased complexity of one line of code mapping to multiple blocks and the complexity of abstraction. But why do you think it's necessary to define high-level blocks through textual code?

A high-level block can represent a underlying visual function even defined in another file much like external higher-level functions in textual code. Like a Math.pow(2,4) isn't a single line of code, but in fact multiple lines just abstracted, you can have a Math.pow() block and it's underlying logic visually defined somewhere else

Achmad Solichin said...

I agree with you. Sometimes we need visual programming but don't forget about the basic concept of the programming language.

Clay Smith said...

Here's my response. In general I greatly disagree from an educational standpoint. https://blog.claycodes.org/2018/10/VisualProgrammingAResponse.html

Samurai_Crow said...

Have you ever seen a textual language with multilingual locale support?

Anonymous said...

I agree. It's a good intro to get something up and running quickly and understanding basics.

Elwood M. Buel said...

After spending two years in labview I concur.

In the end G-IDE systems are just as capable as traditional languages, the difference is a G-IDE allows people with minimal programming skills to create complex systems that are impossible to maintain.

Today in Traditional languages, it honestly takes someone of high intelligence to create systems that are impossible to maintain. Typically working alone, without a program manager.

No matter how much tinkering you do in the G-IDE it's not as functional as traditional code. I wrote a visa wrapper on one page of python code that does the same thing as five different VI that take up multiple windows.

Which is easier to adapt to new systems? Which is easier to maintain?

The python Visa wrapper.

Anonymous said...

Its easier, because no need to worry about syntax

Clay Smith said...

Here's my response. In general I greatly disagree from an educational standpoint. https://blog.claycodes.org/2018/10/VisualProgrammingAResponse.html

Josh Reuben said...

Last decade I spent a fair bit of time working with .NET Workflow Foundation - a visual programming abstraction. Many projects devolved into "abstract art" - this paradigm failed, and Microsoft has phased this API out after several iterative retries.

Anonymous said...

Visual programming is not valuable because textual programming obfuscates a fundamentally simple process, it is valuable because textual programming does not elucidate a fundamentally complex process. Visual programming languages are valuable in domains where rigor and correctness are more important than simplicity. Even partial implementation in a visual domain with internal code aids in testability and interpretable encapsulation. As you say, good code may already decouple and abstract away in the proper ways, but generally not in easily interpretable ways. I think these goals are actually directly addressed by many visual programming tools, which clearly show dependencies between modules, and generally have nesting capabilities. It seems your gripes are more with the particular tools you have used than the state of the art and a priori possibilities of the technique.

It is very difficult to show that code implements a specific, pre-specified formal structure without a diagram in the same (visual) language as that structure. If you create analysis tools to compute this diagram structure from textual code, it is not too difficult to begin progressively improving that tool into a tool for programming itself. At this point you have cut out the middleman and you are working in the interpretable domain directly. Even if you still write code in some places, the overall system is specified in a way that you can more easily evaluate for correctness.

It is interesting that you fault visual programming languages for not being amenable to git diffs. Have you considered that git is in fact the tool that is failing in this process? It was designed for textual code. It is not surprising that extensions or different source control is necessary for non-textual code.

Visual programming is not a be-all, end-all solution, but it has valuable applications, and the issues with it can be addressed. I have built visual programming tools and used them - while I believe they, like all systems, have many issues, none of those you raise in this article seem to be serious or meaningful.

Moritz Mœller said...

I suggest to learn Houdini. It may change your pov on what [also] constitutes 'visual programming' and also what to think about it, specifically in the context in which it is used in Houdini but also generally.

Anonymous said...

You lost me at "untypical"

Unknown said...

Pictures are great but from a pragmatic use in a real. world scenario I've seen these types of tools fail. SAP B1 integration framework and SnapLogic use the same graphical representation of code blocks that can be linked together to create ETL integrations between systems. While the initial use and implementation looks good, over time you start to see the lack of good code development practices and catastrophic failures because it was so easy to slap a few blocks together that now your business partners are cobbling together integrations faster than IT can manage the overall platform. They are great for niche cases to quickly lay out a structure, excellent for an additional way to explain complex code dependencies but overall a poor choice for heavy use in an enterprise environment.

Alexis Read said...

To add to Andy's comment above, if we consider the visual language a DSL on top of a suitability flexible low-level language (ie. New visual extensions can be easily developed), the impedance mismatch between the DSL and the low-level language is an important consideration.
The better visual DSLs will have a low impedance, possibly to the point where the DSL can self-host, and few language features will need to be hidden away in dialog boxes.

NodeRed is a good example. It's built on nodeJs and extensions can be easily developed (hence the plethora of nodes from opencv to twitter nodes, SQL database access, rpi i/o etc).

It supports UI development through the dashboard plugin (though is missing a table plugin here) and runs cross-platform (see https://www.github.com/alexisread/noreml) so even mobile apps can be developed.

To address the impedance match- visual primitives corresponding to language primitives help immensely eg. For Composita, basic malloc is handled via RAII (scoped object creation/destruction) and object communication via a fixed size queue. Both these can be modelled visually.

Anonymous said...

What a bad hot take. History is going to make fools of everyone who thinks like this. If I am selecting and manipulating code text directly with touchscreen, is that a Visual Programming Language? Okay, so what if there is a graphical element to represent the text, but just while I'm dragging it somewhere else? At what point is it a Visual Programming Language and not a better text editor?

There are so many counterexamples disproving this author's proclamations that I don't want to waste my time arguing against this ridiculous rant.