There are some ideas that are reinvented constantly.
Well, maybe they aren’t quite reinvented. They are just continuously re-discovered.
Early in my career, I had to develop an instrument control system for scientists in a biomedical company. I knew I could write the system in C but that was a gargantuan task. I looked around for alternatives and found one.
There was a company that sold two products that could help. One was a ‘visual programming’ (no-code) system for linking together controllers for various pieces of hardware. The other was a system that had the same controllers but you could piece them together with C code. I opted for the latter because it looked more flexible. It was. I was able to develop the system quickly and move on to the next thing.
You might wonder whether I made the right choice. Did I need that flexibility? It turns out that I did. As I was developing the system I realized that I would’ve been boxed-in by the no-code system. But, that isn’t the end of the story. Later, I ended up reimplementing the system in C++ with hand-coded device drivers and custom Windows graphics. Why? Well, I was boxed-in again. I needed more flexibility as the users needed more features.
Back then, there was nothing new about this story. There still isn’t. This dynamic has been around as long as we’ve had software. We can build upon existing software (in this case a vendor platform) but when we do we have to live within its constraints. Those constraints were designed-in (intentionally or unintentionally) months or years ago by people with different incentives and concerns — they aren’t directly changeable.
The simple fact is that low-code and no-code are based on a dream. They can be useful, but you have to see through the dream to make good choices.
Here’s the dream:
“Use this tool / library / platform and you will be able to develop your system quickly and save money. The end.”
The reality is that all of the software we use has constraints. Often we don’t see them until long after we’ve decided to use it.
So, what do we do?
Here’s a strategy:
Look carefully at low-code and no-code tools and ask these questions:
Does the tool support every use case you can imagine?
Is the vendor responsive? (because the unimagined sometimes happens).
What happens if the vendor is acquired, goes out of business, or raises its prices?
None of these questions are reasons by themselves to avoid low-code or no-code, they just lead you to the next task — thinking about your software’s succession plan.
I have the strong opinion that all software should have one.
You need to figure out what the next system will look like if you outgrow constraints and how you can get there.
Some key questions:
What are the conditions that will determine when you will replace your (low-code / no-code) system?
What is the time frame?
Can you use separation of concerns to lessen the impact — i.e, modularize key parts of the system that you might want to incorporate or leave out of the successor system?
Does the low-code / no-code system support testing? Will there be an easy way to see make sure that parts of the successor system are behaviorally equivalent?
Again, none of this is new. Many applications still start as spreadsheets and move to code when they reach limits.
There are always limits.
It’s just a question of whether we ever reach them and when.
No code is someone else's code, just like the cloud is someone else's computer.
There is no magic; there is no free lunch -- well, except for the universe.