[Discussion of truly graphical
languages, as opposed to "visual" tools for building GUIs etc., moved to GraphicalProgrammingLanguage
Are we about to make another major programming paradigm shift? Have visual programming tools matured enough that we can honestly consider them to be the forerunners of a new way
to develop applications and systems?
I am about to start a major development effort (in Java) and we are leaning towards using a visual (RAD) tool. (Ignore all of the problems inherent with using a new technology such as Java.) The current generation of Java visual programming tools inherit a lot of ideas and techniques from Smalltalk environments (such as VisualAge
) and popular Win95 RAD environments (such as VisualBasic
Now, of course, there is still a lot of code that still needs to be written by hand (business specific logic, system level algorithms, etc). But, I am curious as to how well a graphically based notation will work out for high level code sharing, browsing and maintenance. (Using JavaBeans
to encapsulate the business logic and system resources, the application programmers would be the primary users of the visual programming environment. They would be wiring
the beans together to build the application).
Here is a possibility:
Looking into the future, I can see navigating the source code of large systems by looking at the schematic
: components as boxes, methods as connections, etc. This is different than traditional CASE based programming. You are
looking at the code, not a high level design representation (used to generate code).
, through his concept of LiterateProgramming
, looked ahead to a time when program listings would be read as works of literature. Visual programming is a slight departure from this. Instead, we may look ahead to a time when program listings consists of schematics: a canvas filled with boxes, circles and lines.
Maybe this schematic will contain patterns
of relationships and logic that can be visualized as spirals, clusters, and fractals. This is just a different kind of LiterateProgramming
had a program, NextInterfaceBuilder
, that did roughly what you're talking about as far as wiring
user interface components together (IB was, in many ways, a bean box for ObjectiveCee
). And, since I got my professional start doing NeXT stuff, I have to say I thought it a very natural way to do things.
The reason it worked so well was something NeXt
documentation called "the target action paradigm." All user interface widgets had an instance variable called "target" and when you wired a button to an object (either a visual object or one in the "control panel"), you got to choose from all methods with the signature
- (void) methodName: (id)
(that is, all methods that took a single argument of type "object").
You selected a method and then, at runtime, when the widget did something, it would call the method chosen, passing itself in as an argument (so, for example, if the user selected an element in a scrollview, the recipient of the message could find out which element in the scrollview was selected).
In later years, NeXT changed it around a bit, using the observer pattern instead of direct messaging, but the basic notion stayed the same.
I think the effort involved in using the tool is less than the effort involved in laying out the user interface via code (although code gives you more control over the exact look and feel -- NeXT, like the beans approach, serialized out instances of objects instead of generating code).
I also think the approach is very limited. It requires you to know a lot
about the runtime configuration of your code. While this is reasonable for user interfaces ("I know eactly what the window should look like"), it is much less true for back-end code (though not entirely untrue).
It depended quite heavily upon the programmer knowing the semantics of all message calls (and on the sender being a simple object, easily understood). Basically, the idea is "when you're in <state description> call <methodname>."
If an object has complex state, or if the method called depends on application state (not just object state), the wiring approach is hosed.
One can imagine application state being introduced by applying conditional logic to the connections (somehow implemented visually -- oh no, this is starting to sound like flowcharts!)...
Yes, the technology isn't here yet and it certainly won't make programmers out of users (the lure of most RAD providers), but I have to wonder whether there is an easier way to get an overall grasp on complex applications without just diving into the source listing (I only trust design specs but so far). This worked fine for structured software (LiterateProgramming
), but OO makes code reading more fragmented (and reuse further complicates things).
Actually, I find that the source listing itself is not a very good way to find out about an application. The problem is that the design-time structure and the run-time structure are entirely distinct things; CASE tools can show you design-time structure, but that only goes so far.
I find it useful to talk about goals and desires when explaining a system. Neither goals nor desires make it into the code (except as comments), but they're the thing that allows people (well, allow me) to understand what's going on.
-- William Grosso
, then VisualProgramming
will only help with the user visible part of your software. Not a bad thing (GUI programming is tedious and thus error prone), but an insignificant part of the effort.
One way VisualProgramming
might help is to help you develop and freeze the GUI early. If you can do that, you've got an early deliverable for the testing and documentation staff who have to know what the program looks like.
You can graphically model even those parts of the software that have no GUI. Ever looked at the ShlaerMellorMethod
? Part of the ShlaerMellorMethod
involves drawing FiniteStateMachine
s to describe the dynamic behaviour of object-classes. (Bear in mind though that the ShlaerMellorMethod
is targeted towards RealTime
applications - such an approach may not be suitable in another problem domain.) --
My own experience is that, once you have learnt how to use the available layout managers, it is much
quicker to type in a description of the user interface than it is to fiddle about with the visual tools.
For the non-visual parts of the program, it is useful to have a good view of the structure. Perhaps tools based on an ArchitectureDescriptionLanguage
, such as Darwin [http://www-dse.doc.ic.ac.uk/Software/Darwin/
], would be useful.
Wire-em-together GUI tools tend to encourage bad designs which expose too much application knowledge to the GUI. So do non-GUI patterns like MVC. See [http://www.javaworld.com/javaworld/jw-07-1999/jw-07-toolbox.html
] for an alternative pattern.
Another way to lay out your application is with a mini-language such as IBM's "Bean Markup Language" [http://www.javaworld.com/javaworld/jw-08-1999/jw-08-beans.html
My experience has been that the very name "VisualProgramming
" tends to lead in a direction contrary to what I find helpful and productive.
There is a design to every user interface (some are quite ugly!), good designs seem to reuse certain idioms and follow certain rules, and these idioms and rules can be described using a pattern language. This pattern "language", in my experience, is often best described graphically. I have written, for my own use (in Smalltalk), tools that reflect this approach and I find that my use of these tools dramatically improves both my productivity and also the quality of my resulting code.
I would like to say most emphatically, however, that this is not
-style "visual programming" in the manner described here. Rather than attempting to construct static pictures of dynamic flow (the fundamental problem I have with any effort to "draw" a decent user interface), I find it more successful to draw diagrams of the code
that creates these interfaces, and draw the constraints that govern that code.
In most cases, in my experience, good user interface is an epiphenomenon of good code. All of the code, for any pleasing software I have encountered, demonstrates deep and obvious structure, pattern, and form. I view "VisualProgramming
" as the task of surfacing that structure, pattern, and form so that it is explicit, apparent, and most importantly, capable of being manipulated by both developers and other code (including itself).
So...yes, I draw schematics and diagrams. But they are schematics and diagrams of the source code
I am working on. Thus, when I discover a rule, such as a prefixing and suffixing rule for an identifier, I can readily reflect that rule as a graphical operation, provide "terminals" for the prefix, suffix, and identifier, and then have easy and immediate access when my client decides to change the prefix convention. This identifier pattern is then easy to instantiate whenever I use a similarly-structured identifier -- it becomes a value for terminal of another diagram, like a parse tree for a method. And guess what...lots clients like to use a common prefix for method names, class names, application names, and so on. The approach I suggest here lets me use the OnceAndOnlyOnce
pattern to great advantage; the prefix is used OnceAndOnlyOnce
, as are the rules that integrate a prefix into other structures.
It is all very much like the approach the WindowBuilder
used to take with "pseudo-classes" and that IBM Smalltalk uses for building new classes (it's really quite interesting to go look at what IBM Smalltalk does
when you, for example, reparent a class).
The early "plug-board" style of programming can be considered "visual" to some degree. See EarlyProgramming
It can also be viewed as DataFlow? at a low level - data flowed between registers across those wires we so painfully inserted. There seems to be a close correlation between visual techniques and flows or streams - or maybe it's just that a lot of the real world works like this. --PaulMorrison
has extended the VisualProgramming
metaphor used in InterfaceBuilder
, which is a full DomainSpecificLanguage
for exploring and prototyping the various Quartz graphics technologies.
I'd be willing to bet that text code's days are numbered
. Over time tools are gradually becoming more visual and/or more GUI-driven and/or wizard/form-driven. Perhaps there will always be a textual underlying representation, such as XML, but most of the actual programming will be via GUI's (or whatever replaces GUI's in the future). I've seen interesting concepts that seem "almost there".
What is missing in part is meta-tools, tools that make building GUI tools easier such that experimenters and pioneers don't need an army of programmers to produce products that are good enough to test ideas and spark a revolution.
I would note that I'm not satisfied enough with existing visual tools to abandon text-centric approaches at this stage. They still suffer the EightyTwentyRule
Perhaps for some things text code's days are numbered, but it's notable that despite the invention of drawing, humans have not stopped speaking or writing.