edit SideBar

Main / State

From John Grant: I continue to see products doomed or at least crippled by an excessive number of layers. I call that "lasagna code" -- it can be more impenetrable than spaghetti code.

John Hartman wrote: A wise programmer I knew used to say "There is no problem that can't be solved by another layer of abstraction - except for the problem of too many layers of abstraction."

Software Complexity is Killing Us

If you try to hide the complexity of a system, you end up with a more complex system.

Businesses want to build software cheaper and faster. But engineers don't often support that goal the way they should. We get enthralled by the maelstrom of complexity and the mental puzzle of engineering elegant solutions: Another layer of abstraction! DRY it up! Separate the concerns! We lose sight - that managing complexity is the second most important responsibility of software developers.

Over the last few decades, our industry has been very successful at reducing the amount of custom code it takes to write most software. Much of this reduction has been accomplished by making programming languages more expressive. Other significant gains have been made by using open source, standing on the shoulders of giants. But we still must develop all the interfaces, workflow, and logic.

Low code development tools are a modern term put on the latest generation of drag and drop software development tools. The biggest difference between these tools and their brethren from years past is that they are now mostly web (and mobile) based and are often hosted platforms in the cloud.

So, what is the problem? Well, a few things. First is that experienced developers often hate these tools. Most Serious Developers™ like to write Real Software™ with Real Code™. Second is that folks like me look at these walled platforms and say “nope, not building my application in there.” That is a legitimate concern and the one that bothers me the most. If you picked a vendor 10 years ago who had a locked down platform, then you might be forced into a rewrite if they shut down or change their tooling too much. Or even worse, your system gets stuck on a platforms that freezes and no longer serves your needs.

We, as an industry, need to find ways to simplify the process of building software, without ignoring the legitimate complexities of businesses. We need to admit that not every application out there needs the same level of interface sophistication and operational scalability as Gmail. There is a whole world of apps out there that need well thought-out interfaces, complicated logic, solid architectures, smooth workflows, etc…. but don’t need microservices or AI or chatbots or NoSQL or Redux or Kafka or Containers or whatever the tool dujour is.

A lot of developers right now seem to be so obsessed with the technical wizardry of it all that they can’t step back and ask themselves if any of this is really needed. Our obsession with flexibility, composability, and cleverness is causing us a lot of pain and pushing companies away from the platforms and tools that we love. What I’m saying is that we need to head back in the direction of simplicity and start actually creating things in a simpler way, instead of just constantly talking about simplicity.

Simplicity Was Elegance

Phil Matthews ponders this:

Recently I had to work on some embedded software for a PIC24 that would reset another chip by pulsing an I/O pin low for 160usec.

The code I found had a function "reset_chip()", which created a message that was posted on a message bus to a task in a "reset object" that subscribed to the message. The message was dynamically allocated on the heap and linked into a message queue. The message contained a pointer to the message data which was also dynamically allocated on the heap. That "object" had 4-layers of hardware abstraction that ultimately pulled a GPIO pin low. Another timer object also subscribed to the same message and started a timeout with minimum resolution 10msec. The timer object was dynamically created in a linked list of timers. When the timer expired it generated a timer event object that posted a timeout message to a another task that subscribed to the timeout message. This caused the reset object, through 4 layers of hardware abstraction and logical pin mapping, to pull the pin high. The reset pin was low for anywhere between 10-20msec. Also it didn't always work, and sometimes went low and failed to go high (This is why I was working on it) .

I deleted 1500bytes of code and replaced it with 3 lines of C-code:

 Set_gpio_pin(6, low);
 Set_gpio_pin(6,  hi);

When I pointed out how ridiculous the original code was, and asked why it was done that way I was told point blank, "It's object oriented". When I asked what problem is being solved by doing it this was the reply was "Everything is object oriented. It's the way software is done".

Admittedly this is an extreme example. However, over the years I have noticed embedded software becoming more complex for no apparent benefit. It looks structured, and follows some academic pattern. But is way too complicated, slow, memory hungry and full of bugs. I don't mean complicated systems. I'm meaning simple systems with unnecessarily complicated software. Why has this come about? Is it software guys becoming more and more distant from hardware?

When I started writing embedded software it had to be crammed into limited hardware. Simplicity was elegance.

The Best Code is No Code At All

"Code is bad. It rots. It requires periodic maintenance."

Please Don't Learn to Code

"Don't celebrate the creation of code, celebrate the creation of solutions."

Page last modified on April 21, 2022, at 01:01 PM