Why programming is difficult (2014)
joearms.github.io
joearms.github.io
Technology jumping based on anecdotal evidence of the efficacy of doing so. Jumping around so often precludes a lot of practitioners from gaining a deep experience and understanding with the tools they're working with. This may be the only industry I know where pertinent knowledge and experience matters little.
The notion of "Full Stack Developers" gives the impression that one can be proficient top to bottom. What I find interesting about the label is full seems to usually be bounded on the lower end at a place much higher than a place where I would use the term full. This is one of the many areas in our industry where hubris is in play. Specialization is usually preferable for quality and scaling.
Real world business continually drives the fast and cheap legs of the stool to be chosen by management. However, I think this grates against most practitioners who not only care about quality but would admit, the aspect of quality is one of the major reasons they are even in the field to begin with. There is a large natural tension at play here. I think it's this tension that Joe was articulating.
It's seems to me the most satisfied folks in this field are the ones fortunate enough to be compensated for working within a bounded context where over time they can gain more and more experience and knowledge. This naturally leads to a growing confidence and a sense of control over the context with which they work.
From the late 1990s until five or six years ago, it was fairly easy to keep up with the latest interesting stuff in terms of full stack. Adjustments were modest year to year. At this point I've entirely given up trying to keep up with the very rapid fad switching that has been going on. Real full stack is now only possible if you freeze pretty strictly across the stack and don't try to keep up as the next fad rolls in for a given part of the stack. If you try to keep up with all the fads now, it'll burn you out (and most likely make you hate what you do as you realize how pointless the constant switching is).
I've found - as you'd expect - that abandoning the stack rat race hasn't had any negative impact. Most of the latest fads are entirely unnecessary and bring nothing to the table that prior numerous solutions didn't already deliver toward building, launching and maintaining product.
But padding resumes is one of those seemingly fundamental problems of any industry (or bureaucracy). Many poor decisions by (middle) management come down to padding resumes - when the consequences of bad decisions eventually happen said managers are gone. Hell, you could even argue that a lot of higher education is about padding your resume rather than learning skills. Unfortunately, it seems that we have to live with the added baggage of "padding resumes".
Programming is not just understanding how the device, language, libraries work (ie. getting more complete information) but also limiting the ways the adversary can screw you and limiting the fallout.
Programming is difficult because developers don't appreciate how important the part of managing this incomplete information is. "I wrote this and it works! Yeay!" And then it goes in prod and fails instantly because you did not take this or that into account.
Some bright developers have the ability to manage this. But the problem is that they can't work really well with other developers (at a typical corp) who don't appreciate the problem the same way. This puts them in this untenable positions where they can either do something by themselves, very efficiently, or rely on extremely inefficient process if they want to work with other developers.
Suppose you're becoming pretty comfortable with your skills in a foreign language and you've become pretty decent at speaking it. Occasionally you'll make a mistake---you'll pronounce a word incorrectly, misplace a verb, etc---and chances are the person you're speaking with will be able to figure out what you meant to say.
Unfortunately, computers don't work that way. If you're writing a function and your syntax is incorrect, the browser won't understand what you're trying to do.
Or worse, you and the computer have different understandings about what you're trying to do and it goes along quietly incorrectly for a while until that little mistake causes a problem somewhere else entirely because that one misunderstanding caused a cascade of misunderstandings that kept building up until it finally blew out everywhere all over your program and the quest to find where the problem started begins, well before the task of fixing the problem can start.
The key is to not work at a typical corp! :)
Dealing with uncertainty and incompleteness is a core part of the job.
The problem is that far too many programmers are gloryhounds and cowboys who think all that is beneath them; cramping their style when they’re trying to be the coding heroes.
This is compounded by many programmers being lazy incurious bums who have zero interest in doing anything that isn’t writing code. They don’t want to learn the user’s problem domain, so they don’t. Instead they demand users describe exactly how the software should work down to the very last detail; but if users could do that for themselves then they wouldn’t need programmers to write it for them!
Starting from ignorance, instead of writing software that encapsulates the users’ expert requirements, they write clever code that solves their own problems: entertaining themselves, and getting paid.
Writing code is not hard. Any monkey can do that. The challenge is knowing what code to write; and that’s made needlessly hard by programmers who can’t be arsed to understand their users, what they do and why they do it, learning their needs and problems in order to synthesize more effective solutions.
Instead of raising themselves up to users’ level of knowledge, they drag the problem down to their level of ignorance and whale on it with their crappy tools to give the illusion of “productivity”. Instead of being problem solvers, they’re problem multipliers.
Slap on several more layers of equally useless management, marketeers, beancounters, etc, and factor in that while deadweight accummulates expertise walks, and it’s no surprise most software projects are rolling Katamari disasters that makes everyone miserable until finally put out their misery; only for the whole process to start over again, with zero lessons learned.
--
TL;DR: Programming is hard because programmers make it hard. Because they don’t want to do the job right. Because they’re children.
Not all programmers try to be heroes and cowboys throughout their whole careers. I am myself a programmer (25+ years doing it), and have known programmers my entire life. The distribution of certain personality traits is not better or worse in any given population.
Besides our 'lazy' and 'childish' ways, we also have to contend with business constraints and everything needs to be shipped for yesterday.
So although I do agree programmers should be more aware of the domain knowledge and be more 'client' oriented, it's also true that business stakeholders need to take the time and understand the impacts of their 'ship fast always' mentality. Too many times there is no counterweight to business decisions that lead to overwhelming technical debt, which is a great deservice to customers in long term business sense.
It's never black or white.
I said “far too many”. Although judging by the amount of crap software around, it’s certainly a lot.
“it's also true that business stakeholders need to take the time and understand the impacts of their 'ship fast always' mentality”
You’ll note where my original post points out programmers are not the only culprits at work. Learning is a two-way process. But developers are ostensibly the experts in turning requirements into solutions and what is needed to do that; so if users have utterly unrealistic expectations of what is/isn’t achievable then whose fault is that?
Often what users want is feedback: they want to know when they’ll be getting their solution, and be confident it does what they need. Both of these are engagement problems. That points to logistical shortcomings in the development cycle, particularly the siloing of parties and processes, which I know is a blight in which everyone is at fault.
But a lot of programmers would far rather wrangle code than wrangle users, even though user-wrangling is by far the more important of the two. So what does that say about these “solutions providers” and their ability to deliver?
Me, I’ve only been coding 20 years; professionally the last 10. My first programming job, I was one of two devs attached to the IT team out on the shop floor, working directly with users developing them quick-turnaround solutions to their immediate problems. In the 3 years I was there, I never once saw a developer from their 20+ Enterprise Applications department walk out of their glass cage onto the shop floor and spend some time talking to users about how they were getting on with their software and any problems they might be having.
Sure our code was small and simple, and theirs large and complex. But that’s all the more reason for them to engage closely and constantly with users, in order to avoid large and costly errors downstream that embarrass and frustrate everyone.
As I say, the problem is not in the code but in the people and their processes. Yet, no prizes for guessing where most programmers will try to solve it.
"Sure our code was small and simple, and theirs large and complex"
Having a complex piece of code, maybe with a lot of 'historical cruft' and legacy 3rd party modules? Business politics? Maybe a new manager wants his programming team to work on 'Shiny X' because that will make him/her look better with upper management?
Trust me, 95% of programmers (and most people for that matter) would rather feel like they are doing a valuable service and adding value to a product or service, than simply and lazily going through the motions of 'coding'.
Until you've walked a mile in some 'Enterprise application developer', or any one else I think it will be difficult for you to evaluate the global picture.
Although I understand you frustration and completely agree with the symptoms you mention, the cause is far more complex and difficult to grasp unfortunately.
[0]:At my current job I'm completely insulated from users and I would really prefer not to be, but that's "the way it is".
This has been the MBA's wish/dream/hope for about a half-century now: “if only programming were easy and programmers didn’t take so long,” they think, “I could be making millions off of this business.” Since they want this to be true, they reason, it must be true. They then insist, in spite of mountains of evidence to the contrary, that programming is easy, and the entire industry of programmers - every single one, including the ones who were educated recently, including the ones from foreign countries - are conspiring against them to make it seem like it’s harder than it really is.
The truth is, development is a high skill profession. It should take decades to master if we were really realistic about it.
It is almost like people have different domains of expertise because getting those skills takes time an effort, and specialists will always run circles around generalists in any non-trivial domain.
"Software Engineering" encompasses everything else on top of programming. You need knowledge of these things: build systems (Make/Gradle), filesystems, networking (IP/TCP/HTTP), Data formats (JSON/XML), Databases(SQL/KV), software architecture, layout/styling, documentation (both reading and writing). This list is just scratching the surface but we can agree that all of these things are critical to build applications.
These topics clearly aren't exclusive to "Programming" and knowing them doesn't mean you are a "Programmer". You could also be a sysadmin that is managing a large cluster for multiple applications. But if you are a Software Engineer and not just a mere "Programmer" you know that your job is much much more difficult than merely the "Programmer" part.
If you're programming, you're a programmer. Or a coder. Or a software developer. Or a software engineer. There is no consensus on the distinction between any of these things. Just lots of people with opinions because it's easy to have an opinion on.
Maybe it isn't yet, but I hope that there will come a day in my lifetime that it is.
With such a list, one would hope software engineering becomes a protected title
Engineering is a field where we understand the fundamentals. Changes from year to year or even decade to decade aren't going to uproot half of the things you know about it. In software that can very much be the case.
In my view, "engineer" is getting harder to define. At my workplace, anybody who does anything techy and has a degree is an "engineer" if in the product development department, or a "scientist" if in R&D. Only a small handful of the engineers do what a traditionalist would recognize as "hard" quantitative engineering. Most of the work is fitting building blocks together, troubleshooting, bureaucracy, etc.
Must be the tits.
Doesn’t mean people won’t question your abilities but it helps with signalling
I haven't seen a certification system that wasn't either a money-grab (product-specific certifications, like Windows or Novell), a power-grab (by someone like the IEEE, where the tests were half electrical engineering and the software bits were garbage practices from the 70s and 80s), or a way to artificially restrict the number of available practitioners (arguably another money-grab).
No certification system is going to magically make large systems easier to write or whisk away bugs. Writing software is hard. It's that simple. People who have spent their entire careers writing software, from industry luminaries that you read about every day to the really, really good engineers you've never heard of, who are absolute wizards, these people are still writing howlingly bad bugs because writing software is hard.
You can have your certifications and legal requirements for training and so on, just don't pretend they will improve the state of the art. The best you can do is hold people's feet to the fire after they make mistakes, and if the best people in the industry can't be perfect, why would we expect threats of punishment to fix anything?
Engineering is about designing and building systems, usually with cost, time and reliability constraints. It's totally separate from whatever liability framework is being enforced this week.
I am a "Software Engineer". I hold a Professional Engineer designation by APEGS, my schooling was for Software Engineering. I advocate for regulation in the industry but also don't think it needs to be sweeping and catch-all.
My job has me working within Industrial Control environments. Programming mistakes can kill people or damage equipment worth millions. When I receive a software package from someone I want to have some trust in a system that this person wasn't hired off the street for lowest wage. My employer has a good reputation in our industry and is asked to come clean up messes from programmers overseas who provide a bad system and walk away from it.
If your job doesn't have you playing with lives of people or holding the wellbeing of a company in your hands then regulation shouldn't be as stringent. But to say that every project of that magnitude has an Engineer overseeing and holding responsibility over it isn't overreaching imo.
The only thing I'm aware of that seems to actually work is to hold engineers accountable for results and give them the autonomy to set their own process. I would argue that even very rigorous methodologies like NASA's Systems Engineering[0] process match that description.
[0] https://www.nasa.gov/connect/ebooks/nasa-systems-engineering...
OTOH, not every engineering project requires a PE - and the same would be true for programming as well. Unless money, lives or other regulatory items were on the line then a PE would not be required. That would still leave the overwhelming majority of software not requiring any form of certification for its creators. So there's that.
A "sailor" could be a captain, cook, look-out, marconist, machinist, steward,... anyone who's enlisted on a ship doing a set of tasks to keep things going.
Is a technical writer a software engineer then? I would say so, yes. Why? Because they are involved in an intrinsic part of the entire process of building and maintaining a piece of software.
The problem with "software engineer" as you frame them, is that you also raise the bar to an incredibly high to attain level as things stand today. Why? Because of how the field has kept on compounding ever more complexity over the past decades. It's extremely hard for mere mortals to memorize a a vast and ever changing corpus of knowledge and experience, be able to dive deeply in any codebase and understand all the parts while also have time left to write detailed, readable and understandable technical documentation.
Case in point: Virtually everyone has a gazillion tabs open with an equal number of googled StackExchange posts.
To keep up with the analogy: I don't think the radio-operator will act as a navigator; and neither does the navigator know the fine details of how the innards of a radio look like.
Hence why you most software engineers are specialists in their trade. And often, specialists in a small fraction of the entire knowledge domain.
Regardless, software engineers are without a shred of doubt programmers. Programming is exactly that: feeding a Von Neumann machine a list of instructions in order to "make it do" something. No more, no less. It doesn't matter what your role is in that process - defining the problem, working on an instruction set, typing the instruction set into the machine, documenting the instruction set, verifying the output,... - you're basically a programmer.
The primary reason why we call ourselves "software engineers", really only is because Margret Hamilton - thé Margaret Hamilton of the Apollo AGC computer - came up with the label in order to legitimize the work she and her team did at NASA:
https://en.wikipedia.org/wiki/History_of_software_engineerin...
In fact, the rise of complexity has caused a "software crisis "in the late '60s to '80s. And it was named as such: a "software crisis":
https://en.wikipedia.org/wiki/Software_crisis
All that is old becomes new again. The more I read about the history of our discipline, the more I'm convinced that we are just chasing our own tails over and over again.
Arguing over who is a "programmer" and who is a "software engineer" is - ultimately - basically arguing over semantics and marketing.
At the end of the day, the world doesn't care how the pie was made. They simply want to be able to fly safe, watch TV and file their taxes efficiently.
It’s a curious thing about our industry: not only do we not learn from our mistakes, but we also don’t learn from our successes. – Keith Braithwaite
This is analogous to, for example, a civil engineer certifying a bridge for a certain load with a safety factor.
On a funny side note I had a very bad Emacs breakage recently and at first couldn't understand why checking out the latest known correct Git version wasn't working on my main machine. It was working on another computer (btw copying my entire Emacs config is, well, also one git command away, so is backuping). Turns out: for whatever reason the file containing the list of files recently opened by Emacs got corrupted in a very strange way and that's one of the rare Emacs file I'm not committing into Git. Took me a few minutes to sort out.
TDD has really helped me in this regard because it forces me to start building the model from ground up as opposed to in media res.
Also, I read a couple comments above, and I feel that people who wrote them have no idea who Joe was. To me Joe is an inspiration, and I think his words are usually not there to be debated ;), after all he cocreated Erlang, and Erlang and the OTP is a masterpiece imo.
Joe was awesome, on so many levels. You have to love the healthy rebellious streak and the talent to back it up.
> "I Google a bit and after a while find a posting where some poor unfortunate soul has encountered exactly the same problem that I have. My heart leaps for joy. My trembling fingers enter the magic spell that will remove the curse, and ... nothing. The problem remains."
and
> "I'm lazy, I'm a good for nothing slacker. But when I want to put a diagram into LaTeX I don't want to have to read a 391 page manual first. Now I know you will accuse me of laziness and of being of unsound moral character,"
I wouldnt go so far as questioning his morality. But if you're not constantly focused on learning, even the minor details of the stacks you're working with, you'll increase the difficulty enormously. He sums up the danger of that attitude perfectly in his closing remark
> "Fortunately eleven minutes with the Google casino worked. The second suggestion of how to fix my problem worked - and I still don't know why emacs could not find aspell - and life is too short to find out why."
He's fixed it now. He has no idea what was wrong or how to arrive at a solution. Next time he faces, even the same problem, he'll be back on Google trying his luck.
I'm a big fan of learning the why. But it only makes sense if you use the technology enough.
He's also got a habit of asking why and finding out (keep in mind by training he was a physics PhD), this essay notwithstanding.
If you believe the statements he was making were rhetorical in nature, but are dismissive of them, while also crediting that as an individual he was insanely intelligent, with both a level of experience and a level of curiosity that outshines most of us...perhaps you missed the points he was making?
There isn't a next time because Joe died last year.
I think you misunderstand the point. Time is truly limited thing you have in life, and you are using much of that time understanding minor tool that are not the major point of what you are trying to do, that doesn't seem productive and is indeed infuriating.
About the final mark, those eleven minutes should even be needed, things break unfortuntatly, and if who has deep understanding of every single tool you put your hands on, you will not have the time to do whatever you need to do.
A few years ago, I had the "pleasure" of have to use docker on windows, on a complex stack, the docker windows client was always breaking with the solution always being revert to previous version, wait issue fix, update. Ofc, before that we needed to waste some time to check if it was I who broke something or if it was an update. The lesson was, only update sporadically, which also has its downsides. Or should I instead have a deep understand on how docker for windows client worker and submitting the fix myself? Do you know if I had the time for it?
Too many things in our field are held by duct tape that is always tearing. I'm also culprit of that. But saying that because tools not being newbie friendly, or some tools breaking it's the fault of the user is not really a good a approach. Being a programmer shouldn't be about fixing your editor every time it breaks, or spend hours learning arcane tools that are not about programming.
I guess we could look at stackoverflow/google as a more sophisticated index rather than as a sole resource.
We could make everything easier on ourselves if we had more intelligent tools.
We build web pages to help us come up to speed quickly. For example,
But it would be better if our tools could bring us up to speed as we learn.
If we know one computer language well, shouldn’t a tool be able to guide us quickly to the syntax and idiomatic concepts in another language? We know many concepts:
Strings, collections, maps, arrays, sets, dates and times, functional concepts, sorting, regex, concurrency, ...
Basically, a cookbook of examples, etc.
I’m working on a Swift Cookbook to make it easier and faster for the next “guy” (person).
https://github.com/melling/SwiftCookBook/blob/master/README....
Ideally, in the future, the recipes are built into the editor.
You could ask “how to create a mutable map” then choose a computer language the get examples, etc.
Our tools should know the 1000 most common things we’d like to do and be ready to assist without requiring Google.
Our time is limited.
Do it enough times and you will start to see patterns and gain an understanding - I would hope.
I don’t have any problem with reading a 391 page manual first: I’ll come away with a solid understanding of what I’m doing, and I’ll be far more effective in the future. Reading the manual is an investment that pays off ten-fold in short order. The problem isn’t that I don’t want to read a manual, it’s that the “scrum master” breathing down my neck to increase my “velocity” and close tickets sees me reading the manual and says “why are you wasting time reading when you could just randomly google until you find a solution or interrupt your also busy coworkers with inane questions that they don’t really know the answers to either?”
With regards to fixing bullshit transient bugs in other people's software: usually understanding the full root cause does not matter. It's going to update, and bring forth a whole new suite of bugs and oddities in short order. Your machine is a weird, ungovernable collection of state that cannot be fully understood and rarely presents the same way twice. If I had a dollar for every time I followed the definition of insanity and did the same thing over and over to get different results, I wouldn't need to work anymore.
But when you have found a StackOverflow post that ends up working to fix some whack-a-mole stupid thing, it's not like you move on and that knowledge goes poof into the aether. You might forget some details of what it was, but the next time something along those lines comes up, there will at least be the trace of a memory of what fixed it the last time. Over time, you build up this pattern matching apparatus, and in a couple years you can look at a bizarre nested exception trace generated from deep inside some Javabean hell, and you know that, "Oh, something is wonky with DNS on this machine" or whatever. It looks like magic from the outside, but it is utterly mundane.
In my daily work, I don't have time to understand everything. There, i've said it. I'm not lazy. I'm not stupid. I just don't have time when I'm trying to get a task/job/chore done. I appreciate good abstraction/encapsulation. A good tool does this. A bad tool fails to do this. Same with documentation, really.
Don't get me started!:)
The real problem seems to be writing bug-free programs, which seems to be difficult mostly because it is hard to specify what a program should do formally (i.e. in code). Note that bugs are never about the program not doing what it is told, but are always a mismatch between the program and the programmers mental model of the program.
Fortunately, there is a new shiny technology that will make all this complexity go away.
- The input to the program is beautiful.
- The program is beautiful.
I think it would make more sense if the word "beautiful" was replaced with the word "correct"...
It would also help strengthen his argument for why programming is so difficult!
I think that's a big part of why it's so hard. You've got leaky, imperfectly understood, unreliable subsystems, and you're trying to build the best system you can on top of it. And what you produce inevitably is a leaky, imperfectly understood, unreliable system... which becomes somebody else's subsystem. And so it goes.
You say: We need to create perfect subsystems! Formal verification (or robust type systems, or better requirements, or mathematical reasoning, or some other approach) will save us! But it's not that simple. It starts clear down at the hardware level. How much can you formally prove about your CPU? After taking into account it's errata sheet? The union of the errata sheets of all the revs of the CPU? If you're running on PCs, the errata sheets of every CPU that anybody could conceivably be running on?
If you can't formally prove much about the CPU, how are you going to formally prove the OS and/or compiler? And if you can't formally prove those, how can you formally prove anything else?
It's leaky, unreliable, incompletely understood subsystems all the way down.
Then, what's left is a bunch of correct programs, stating the same, in very many very different ways.
Now you need to choose one of them. They're all "correct" - they produce required results when given particular input - but they obviously are not 100% equivalent.
What do you use, then, to choose one implementation out of all the others?
I think to call that quality "beauty" is fine. And that striving for it in your own programs is also right. Requiring it from others is a tricky subject, but as long as you don't go there, there's nothing wrong with talking about the beauty of code, programs, solutions, and so on.