Yes, this! It's the inquiry into the way the data flows, what the application should do, and how to handle edge cases that is difficult for a lot of business applications. To say nothing of getting various stakeholders to agree. Code isn't fluid, it's calcified business process. That calcification requires regimented thought that developers can bring to the table (others can too, but I've seen it far more often with developers).
That's not to say that there aren't more and more domains that will be codeless. As another commenter says, if you can stay in a box, a codeless solution like Wix or wordpress.com can solve your problems quite well. But as soon as you step out...
Another issue that is never brought up is lifecycle and change management. This is a complex topic that developers spend a lot of time thinking about. Some codeless solutions version control behind the scenes, but testing and regressions are not really part of what the end user thinks about. Again, this is a question of maintainability and scale. Small companies may not need the overhead. Until they grow and suddenly they do.
Please pardon my ignorance, as I've never worked in software development. Could you please explain what you mean by 'overhead', and also how a lack of testing/regressions in low-code programs would be a roadblock as the company or application scales?
As an aside, I love your analogy of code as "calcified business process". I've heard several low-code 'success stories' of business users without CS experience learning how to build apps, and they often comment that one of the most difficult things was learning to think in terms of the rigidity of code. Sometimes I ponder whether the true value of low-code platforms is simply that they teach non-coders how to think about business-level problems in terms of logical systems, rather than fluidly, which is how they experience them.
What about adding a feature that changes a fundamental assumptions of the program? Eg since the very beginning, the product has only ever supported integration with Salesforce.com, so all of the system was programmed with that assumption in mind. Unfortunately, there's now a need to support other CRMs. As support for OtherCRM is added, how sure can you be that salesforce.com support still works 100% perfectly? And then let's also add support for 30 more CRMs because that's what the customers are using. If support isn't added for those 31 CRMs, then a (high-code) competitor could come along with a better product for cheaper.
Thus, making sure every change going into the program still works with every single one of those CRMs becomes a roadblock. Not insurmountable, but at some point, the roadblock becomes an albatross around the neck of the product, making it impossible to make any changes to the product.
Having tests (hopefully automated) will make sure that the product works with all the CRMs it claims to. But the overhead of writing tests takes a non-zero amount of time/resources, which (eventually) adds up.
Software is deliberate, yes. You need to know what you want to do at a pretty detailed level, but that's not the challenge. The challenge is that this new technology (what software can do) is a gamechanger for most traditional businesses. It creates a lot of new opportunities by enabling ventures you couldn't even imagine before, and every time you build more, you get more opportunities. Software requires you to reevaluate what you were doing previously. That's hard.
Software is also fluid. As you get more software, you see more opportunities. As you get more, you want more. Anything that tries to treat the domain as "static and understandable" is doomed to fail. Development is not the steady march towards the perfect system. Development is the discovery of what you can do with software, and how that changes the business processes that already exist.
Well said.
I should revisit with more modern examples.
- dealing with the environment. My program always works perfectly until it moves away from my laptop.
- debugging. If you don't know how to code, good luck to find the error in your system.
- interfacing. Your codeless stuff is going to work fine for everything that it already know. But new stuff are coming. Somebody will need to code for that.
Now I do think that eventually AI will be able to manage all that. And that it will give human a fuzzy codeless experience. But it will take A LOT of time before we get there.
I have a chipset that I'd like modeled, and can I have some trivial drivers by next Tuesday?
Modern computers are not trivial. They are probably the most complicated devices on the planet, full of features, edge conditions and screw cases that are not obvious even to very skilled developers. I've done some very fast platform bring-ups and gotten them to ship, projects organized to be very light-weight and agile (in the non-political sense) and it's still many person-years of effort and a bunch of time on the phone with vendor support, discussing chip-level bugs (can that model please include the bugs? That would help a lot!) No talk at all about pleasant abstractions, we need to ship this pile of silicon.
Visual interfaces are for toy programs that spend resources on making pretty illusions of how the world should work. Underneath the pretty glitz are piles of slain dragons and machinery that people take for granted and apparently think can be wished away. That's fine for end-users and application level folks, assuming they can get their jobs done without resorting to breaking the abstractions (and any sufficiently large or long-lived project will). But someone has to worry about memory management, concurrency and synchronization, all the drivers for fucked-up hardware that (say) locks up when you fire data at it too fast, what happens when the file system fills up or that configuration file is mangled by an upgrade. All that nasty stuff that the "drag a blue wire from point A to point B -- see, easy!" doesn't handle, and never will.
On one project we had a clock that would, very occasionally, go backwards in time. It took a calendar year of going back-and-forth with support and ultimately a phone call with the chip architect to figure out the problem (the workaround for the bug was unpleasantly expensive). It's easy to model a clock and come up with a set of expectations. It is much, much harder to make a clock work in the real world. You would not believe how hardfought some of this stuff is, for features that are "trivial".
Visual programming is great when it works -- I've certainly done my share of it -- but we should not mistake ease-of-use in some domains for revolutionizing programming in general, or (worse) expecting the paradigm to work when things get complicated and large.
I was with you until this line. Is it really the case? x86 has been with us for... a while, and x64 is backwards compatible. We built an abstraction on top of that, a compiler that can take high level languages and turn it into machine instructions.
I think what people are looking for next is a compiler that can take something even higher level and "compile" it into high level language. The issue is that if you get too abstract, a standard compiler stops being able to make good guesses about your intent. However, if you built a "high level compiler" around specialized domain-specific use cases, then you might be able to make reasonable higher-level guesses about intent (though as with normal compilers, you'd need support for advanced developers to work around those assumptions).
So some new "things computers can do" from the last 20 years:
- Fit in our pockets
- Communicate wirelessly between any two major population centers on the planet, with high bandwidth
- Store exabytes of data
- Do excellent pattern-matching of all sorts of data
- Be close to your customers, wherever they are on the planet, without you needing to have a ton of capital upfront
- Cost as little as $7 while still being compatible with our complex software stacks
- Be powerful enough to run an Electron application
- Monitor your blood glucose levels and deliver the right amount of insulin in real time
Probably a next great milestone is being able to run multiple electron apps in parallel...
I usually snark on Node.js but not really in this case, I understand well when the platform imposes a moat and it's easier to just re-do than integrate. Ain't nobody got time for that... it's still something of a tragedy but it's not something we have an easy fix for.
Because the real world is like that, there is no possible programming language that is going to prevent the need for "if". Users may think they don't care about that, but the requirements are full of "if".
Loops you don't need to code today - if you don't need too precise a control over execution. If you need real control, you probably need to write the loop instead of just using a comprehension.
Data storage schemas: As databases scale, efficiency of storage start to add up to real money. The user may not care, but the finance people care a great deal.
No, not necessarily, depending on the business requirements. There's already logic programming, for example a language like Prolog. You the programmer input a very high-level description of the rules that your information must follow. The computer figures out all the imperative bits.
Until then, what we can do is build abstraction on top of abstraction over what computers can do. But that is code. There's a lot of room to make application development easier, to make it require less knowledge. In a lot of cases there's no good reason it isn't easier already. But it can't really become easy until the target stops moving; what computers can do changes too fast for people who want to build a good unified set of abstractions over it.