No one builds 747s. People build parts of 747s, parts of parts, and parts of parts of parts, then put them together. It is perhaps the essence of engineering that, to do a task that is impossible, you decompose it into parts that are less impossible, then further decompose those parts into parts that are less difficult, and so on, until you end up with parts that are simple. Then you do all the simple things and put it all together, starting at the bottom.
The idea of "Blockly for Business Logic" (BBL) can be summarized as: decompose into sub-problems that can be expressed as functional logic on flat data, expressed in Google's "Blockly" visual programming tool, then combine them.
Blockly makes it easy and practical to express logic "functionally", and logic that is expressed this way can be more rigorously validated. Encapsulating the "flat" part of the processing separately from data, user, or machine I/O is a powerful simplification that eases comprehension and encourages rigorous unit testing. The impossible becomes almost too easy. I would say that doing the impossible is in fact impossible unless you first make it simple.
I'm not ready to attempt the construction of a 747 in BBL quite yet. A simpler example, though, may convey the idea, with a little imagination, that BBL can be scaled up to any project.
The Pinewood Derby is a racing event for Cub Scouts in the Boy Scouts of America. Cub Scouts, with the help of parents, build their own cars from wood, usually from kits containing a block of pine, plastic wheels and metal axles. The step-by-step instructions for building a Pinewood Derby racer found here are the basis for this BBL example.
At the top level, the racer is complete when certain steps are complete, as follows:
The question arises whether the steps need to be performed in the order specified. The answer is "no", because this is supposed to be "functional programming", in which there are no implicit dependencies. In the example, some steps could be performed in a different order than what is shown but not others. It should not be painted before the block is shaped, at least. To enforce this dependency, block shaping completion before painting is included as a condition of "(is) painted", as follows:
A bigger but related question is, what does this program "do"? Does it build a car? Does it help someone build a car? The answer is that it could do those or perhaps many other things. All it says, so far as it goes, is that these things must be done to build a car. How it's used exactly is outside the scope of BBL. What BBL produces is an XML analog of the visual program. How that XML is used is another matter.
But isn't this utterly trivial? Yes, and that is exactly the point. And no. The process should be decomposed into parts, each of which is trivial. If a piece of the composition isn't so simple as to be boring, then it hasn't been sufficiently decomposed. But the end result is not trivial. The end result is a slam-bang guaranteed successful car build, with much higher probability than using conventional software methods.
What this module "does", then, is just this: it controls the building of a car. If "painted" is removed, the car will not be painted. If something completely new needs to be done, it must be added or it won't get done. It's a sort of checklist, but an active one, though its activity is implemented elsewhere. It's seems to me that, in order to be "super good at making large complex objects", just this sort of active checklist must be maintained, in exactly one place, and in a form that is boringly simple and which ignores everything except what it does, which is to specify that these steps make a Pinewood Derby car.
This sort of thing, when implemented in conventional software, is usually called "configuration", and is often done these days using XML. So one way to look at BBL is as a configurator. It has five things that configuration schemes usually don't have, though:
- It uses Blockly visual programming.
- It adheres to the functional programming paradigm.
- It adopts the powerful simplification of operating only on flat inputs and outputs.
- It uses a small, simple, consistent, customized programming language.
- It configures the entire process, not just higher level or partial components.
Continuing with the example, the "inspect and prepare" step breaks down further as follows:
When we look at the "block inspected and prepared" step, it starts to get a little more interesting.
If someone worked on this, and told you they made a mistake, what would you think of them? Who could possibly make a mistake doing something this simple? Well, I did. My first attempt looked like this:
The blue triangle means that a validation has failed. It confused me for a moment, and at first I thought there must be something wrong with my validation JavaScript. Clicking on the blue diamond gives the error message, though:
This message means that only a single element is allowed here and I was trying to give it more than one. I forgot to warp it with the "All" block, which returns a single "true" element if all the boolean conditions it contains are true.
Next we look at "block is not warped". Finally we're deep enough into the logic that we're actually "doing" something. We're going to test the block to see if it's warped by seeing if it rocks when placed on a flat surface.
The "block side 1" test look like this:
You press each of the 4 corners in turn to see if it rocks, then turn it over and do the same on the other side.
If it rocks, the build returns false. How exactly you recover from that is, once again, outside the scope of BBL.
It seems like an awful lot is "outside the scope of BBL". Yes, that's true. Does it mean that using BBL is pointless? Not at all. By isolating and simplifying this logic, you end up with a powerful and enforceable view of the problem.
To "black belt" programmers, this may all look simple-minded, and it is. I'm basically simple-minded and I hate making things difficult for myself. In my 30 years as a software developer, I've always written small modules like this, if they let me. I have something of a reputation for it. One time my manager came to me with a new project and gave me strict instructions to write it as a single module, because he thought my style was "boring". I did, and it came out to about 1,000 lines. Then he went and made a change to it on his own initiative, which created a subtle error in the results that did not get caught in testing, which turned out not to be boring for him or the customer.
When you run your software, you want it to be boring, every time. You don't want it to end up in the evening news.
Why BBL? Some day, perhaps, someone will use a robot to build Pinewood Derby cars. When that day comes, no change will be required to anything in the BBL. It is the same for cars built by robots as it is for cars built by Cub Scouts.
Why BBL? It produces boring results.
Why BBL? It can be created, modified and understood by people who like football more than they like software development.