Programming isn’t coding (2020)
occasionallycogent.com
occasionallycogent.com
---
Computer programming is a two-step process:
1. Understand the universe.
2. Explain it to a three-year-old.
What does this mean? Well, you can't write computer programs to do things that you yourself don't understand. For example, you can't write a spellchecker if you don't know the rules for spelling, and you can't write a good action video game if you don't know physics. So, the first step in becoming a good computer programmer is to learn as much as you can about everything else. Solutions to problems often come from unexpected places, so don't ignore something just because it doesn't seem immediately relevant.
The second step of the process requires explaining what you know to a machine that has a very rigid view of the world, like young children do. This rigidity in children is really obvious when they're about three years old. Let's say you're trying to get out the door. You ask your child, "Where are your shoes?" The response: "There." She did answer your question. The problem is, she doesn't understand that you're really asking her to put her shoes on so that you both can go somewhere. Flexibility and the ability to make inferences are skills that children learn as they grow up. But computers are like Peter Pan: they never grow up.
Because,
> Flexibility and the ability to make inferences are skills that children learn as they grow up. But computers are like Peter Pan: they never grow up.
LLMs will change all of this. Maybe in some decades we will see programming environments that don't require people to understand the solution in order to create a program. For example, it may be possible for people to create spellcheckers without understanding the rules of spelling.
Unfortunately this will create a whole new class of bugs due to AIs hallucinating code, and I'm afraid that the average software quality will take a hit.
Do you have some examples?
Now, I grant you that a lot of people work this way today. They're in trouble. We're about to enter the golden age for competency, and the dark ages for incompetence.
and in numerous other professions, nobody is signing off work that hasn't been checked by multiple parties either way, LLMs will be a pipeline in this process.
That's what model checkers are for, right? Here's a recent post about this
https://model-checking.github.io/kani-verifier-blog/2023/03/...
> Kani has helped fix at least eight different categories of bugs in a single pull request: https://github.com/nyx-space/hifitime/pull/192. Most of these were bugs near the boundaries of a Duration definition: around the zero, maximum, and minimum durations. But many of the bugs were on important and common operations: partial equality, negation, addition, and subtraction operations. These bugs weren’t due to lax testing: there are over 74 integration tests with plenty of checks within each.
> One of the great features of Kani is that it performs what is known as symbolic execution of programs, where inputs are modelled as symbolic variables covering whole ranges of values at once. All program behaviors possible under these inputs are analyzed for defects like arithmetic overflows or underflows, signed conversion overflow or underflow, etc. If a defect is possible for some values of the inputs, Kani will generate a counter example trace with concrete values triggering the defect.
> Thanks to how Kani analyzes a program, tests can either have explicit post-conditions or not. A test with explicit post-conditions includes an assertion: execute a set of instructions and then check something. This is a typical test case.
> Kani can also test code where there is no explicit condition to check. Instead, only the successive operations of a function call are executed, and each are tested by Kani for failure cases by analyzing the inputs and finding cases where inputs will lead to runtime errors like overflows. This approach is how most of the bugs in hifitime have been found.
I expect that in some decades LLMs will be able to leverage this kind of stuff
I'm counting with this being the case. I expect LLMs to be able to create things that didn't exist before rather than merely parroting what is found in the training set
I'm talking about 20 years from now
1. To do anything interesting and at any speed on my Apple //e I had to know assembly.
2. Then I got a Mac in 1992 and the original Mac Toolbox routines could do a lot from a higher level language.
3. Then Visual Basic made graphical programs easier and later WinForms, C# etc.
4. Then AWS made provisioning infrastructure a matter of just writing a bunch of yaml
5. Now that LLMs exist and ChatGPT is well trained on AWS APIs in various languages, I can use natural language and it spits out code that works 95% of the time with only slight tweaks if any.
If your problem is writing a link list, you still have to understand linked lists. If your problem just happens to be solved by linked lists, you can rely on a library.
Re point 5. If debugging is twice as hard as writing code. How long before AI becomes half as intelligent as the average programmer making said programs undebuggable by the average programmer? Is it a good thing to have black boxes writing black boxes?
It doesn't work this way. A programmer with a bit of experience knows to curb the desire for cleverness and write code they — and their teammates, probably having comparable intelligence and even less knowledge about specific code — can debug.
Unless they are on a coffee trip and hacking on a cool weekend project, of course. Now that's another question, what in the hell will AI's weekend projects be.
Are you suggesting AI will know to curb it's cleverness so that mere humans can understand it???
Edit: further, that assumes an AIs definition of simple matches that of a human programmer. If there's anything we've learnt recently, AI doesn't think like humans.
I bet that LLMs will create another level of bloat industry where computation will be as expensive as making a human to do the same thing, because there will be no human-can-do-it constraint anymore.
This promise of “AI will create cool software” is akin to “robots will fly in cars in vertical cities” of 19/20th century scifi. All we got is worse traffic and exponentially expensive housing.
Lol, no. How would you validate the output of that program if you didn't understand the rules?
LLMs have weighted predictive algorithms for auto completion which are often useful but do not and will not have the necessary understanding of context, ever. By design.
Therefore the reliability of their contribution will always be limited by the complete absence of context.
If my understanding is incorrect please help me understand why.
AI ultimately means humans are obsolete. Machines made most physical labor obsolete, AI will make most mental work obsolete eventually.
me: write a spell checker using Python.
ChatGPT: gives me a simple Python script that uses the Pychant library.
But a more realistic example…
These days, with my slight career pivot, I am working mostly with AWS APIs using various languages. Luckily, there are plenty of examples on the web and ChatGPT is well trained on them. I can often just tell it what I want on a very high level and I get very good results.
Using ChatGPT is more like working with an intern than a three year old if it is a domain it has been trained on.
He is doing things wrong. If he wants the students to use modern tools he first need to give a course on the tools and later another one on programming.
Otherwise he must not use modern tools (no git, no react) and use some simplified teaching environment (not ideal, but at least he will not be distracted by the tooling issues).
In my experience (I have to work a lot with Ph.D. students in science with very little IT expertise) the tools are always the issue, while the algorithmic thinking is rarely a problem, so probably a course on the tools is more useful than one on programming.
He must focus on tools that are not the fashion of the moment, so the terminal is okay, git is okay, React is not okay.
You don’t start woodworking by cutting a hardwood timber to length by eye with a circular saw.
You get familiar with the basics like a hand saw, tape measure, and some soft wood like balsa.
You’re first vehicle was _probably_ a bicycle or go-kart, not a truck or race car.
On the flip side, a core tool like node segfault commonly seems like a problem. Or at least a problem with poorly-written native extensions.
* coding = typing or clicking to have computers do stuff
* programming = knowing how to type or click to make computers do stuff given knowledge of the SDK, libraries, toolchain, and _ideally_ how to communicate effectively with the IDE
* software engineering = knowing when _not_ to program, knowing about components and the implication of their boundaries and contracts with the things outside of that component's boundaries, which in my world includes but is no limited to other methods in that same module, other modules in the same deployment, internal consumers, and most importantly any promises the code (or management) have made to _external_ consumers
---
* coding = able to use a hammer
* programming = able to assemble an Ikea cabinet, sometimes without the correct tools or complete instructions available
* software engineering = able to design an Ikea cabinet for others and striving for a very low RMA rate
If you're a good programmer, you know how to find your way out of the forest without knocking all the trees. Call yourself coder, programmer or engineer I don't care your leetcode scores and your fizzbuzz one liners, and the amount of stickers on your overpowered laptop.
You're there to make the computer do the damn thing you want it to do with the least amount of resources. And of course it has to be maintainable, this isn't your bedroom.
So respectfully, sir, take your taxonomy and pipe it straight to where the light don't shine. /s
That's engineering. That you don't want to care about terminology doesn't change that.
Or rather, they're used by different companies for the same type of jobs, some people make distinctions that other people don't know about, terms go in and out of fashion. They're all essentially synonyms because if there are differences, nobody agrees on them and there is no context in which they matter.
Same for junior, medior, senior, et cetera.
Except for architects. They're ex programmers.
The way I see it, these three all refer to the same things, but "coding" is hobbyist and "developing" is professional. "Programming" is somewhere in between / for both.
Many modern software systems seem to lack such specifications or models. In these cases software development seems more like tinkering than engineering.
They don't if there's no consensus
And I'm sure you ain't got the authority needed to affirm that those definitions are commonly used in those ways
Don’t care how many years you’ve been “doing this” for, you clearly haven’t spent enough time sorting your own shit out.
The industry is sick. So much money has flown into it over the years without anyone battling eyelashes at the sheer waste of resources, and I mean this both from the body count as the cpu cycles.
I look at most products built today that cost millions to get off the ground and you have buttons busting out of windows, incoherence everywhere, 5 seconds to start the said product, and 2 seconds between 'pages'. Every version increment is a slow decent to hell.
It all starts with the industry self-reinforced pumped-up resume culture, with hell holes like linkedin."Engineers". Please, have you met a real engineer? One that can do the maths, the design and build of a product? You need to wake up, engineering isn't writing docker files, cobbling python scripts copy pastes together and claiming that yaml is clean code.
I know you can assemble at least a thousand Ikea cabinets while I hammer away on my carefully designed cabinet made from trees I've chopped down myself and nails I've forged. It fits perfectly with the table made by my great grandfather.
By the time you've assembled 5000 cabinets they collapse as fast as you assemble them but you need 50 000 so you have to hire 300 people mostly to talk about how it is going, document the process etc. Ikea switches to THEIR new cardboard line that is both cheaper, faster to assemble and last even shorter. You get an even larger building and hire 100 more people. Then you put stickers with advertisement on the cabinets because woah the operation is getting expensive!
You put cameras on them cabinets to track the user. Everyone is doing IoT now, you cant fall behind. You launch an app to open, close, lock and unlock the cabinets again with in-app advertisements and purchases.
Ikea goes out of business etc
I look at you, and back at my cabinet, and at you again... I have no idea what it all means. I wish I was the one to think of cardboard cabinets... or do I? I'm not Ikea, no one would have cared for it? I try to convince myself that building my own cabinet was a poor choice only to end up rubbing it with oil and carving Suum Cuique into its ornament.
What? a true carpenter joins wood without fasteners /s
You can't use the title (neither can your employer) unless you are licenced to do so.
Software development ("programming" in your taxonomy) is a solitary activity. Software engineering involves multiple people and the explosion of complexity involved.
I do like your point about knowing when not to program. Will keep that in mind next time I think about this.
A lot of my software engineering mantras are centered around empathy management, both of internal consumers (future you, your colleagues, etc) and 100% unquestionably for external consumers (heh, "future you in 6 months" and folks that are forced to use your software, people who you want to renew). The world sucks bad enough already: don't swallow error messages and voluntarily tell your users the equivalent of "have you tried turning it off and on again?"
The taxonomy is missing "designing," "architecting," "crafting," and more things people like to say they do. To feel important. More important than someone(s) else.
And I often call myself a "professional typist" because the whole taxonomy is pompous BS.
I get paid to solve business problems.
That's far more pretentious than any of the things you listed.
- Coder: Can change scripts, HTML/CSS, SQL queries etc.
- Programmer: Can write scripts, small programs, declarative queries etc.
- Developer: Can write one or more of [applications, games, web sites, services] etc.
- Software engineer: Can create complex software with many moving parts.
- Bug-fixer: Deals with problems that four others will end up ignoring because they all moved on to other jobs creating new systems filled with more bugs that will be fixed 5 years down the road. Bug-fixers can like the work, but it's not glamorous because a lot of the time, it doesn't introduce new value.
They say people are good as their last project. It has rung true for me for years. I have become the bug-fixer again in my new project. But, it usually includes trying to come up with incremental improvements if there result of the issue was direct or indirect lack of something else.
Where I come from, certain braches of industry have simply made it illigal. For example, a nurse cannot call themselves doctors. It pertains to most knowledge-based branches of industry here, except for software development.
Programmers like to think that they spend all their time creating elaborate & complex abstractions
...and that's the essence of the problem. If you want to create needless complexity, you'll also suffer its consequences.
although there absolutely still is a pretty strong contingent of people that advocate for a reversion to a “simpler” way of doing things
I'm one of these, and I still avoid additional tools like the plague, unless they offer a very clear cost-benefit tradeoff. The vast majority of what I do needs only a few windows of a plaintext editor and a terminal. In my experience, others I've worked with who are also similarly minimalistic tend to be more competent too; at the other end of the scale, those who seem to love complex tooling are also the ones who need them as a crutch the most.
That said, I have a different view of the "coding" vs "programming" distinction than some of the other comments here; to me, the latter implies more mindless work while the former (exemplified by terms like "sizecoding" or "democoding") refers to a more intimate and lower-level knowledge of what's going on, along with increased creativity and a problem-solving perspective.
Android development is like this. Ironically the code I have developed for Android tries to hide all of that by providing another tool to the end of the chain that takes simple code and wraps it in a package of monstrosity for the designated 'correct path' tool chain to use.
But specific to abstractions, say you have some tool that promises some way to structure your data or allow you to plot a chart or something like that. It's important to know how to do what this tool does the "old fashioned way" without the tool, so you can even vet whether the tool is actually useful or just more cruft you really don't need if you did your due diligence.
This is true and fits my experience.
> Programmers like to think that they spend all their time creating elaborate & complex abstractions but far more time is consumed dealing with the tools and idioms encrusted with historical baggage.
I disagree. Junior developers spend a disproportionate amount of time learning how to use the tools but after about 3 years all the terminal and editor idiosyncrasies should be second nature. If a person is still struggling with tooling for any significant part of most weeks either something is very wrong or you’ve recently changed jobs (and will be up to speed soon).
It’s clear that the author spends a huge amount of time with beginners, which probably colors his perception too much.
I first learned coding/programming in the days of "big iron," and embedded (machine and ASM) coding.
These require a "Measure Twice, Cut Once" approach. In fact, the "coding" part is really just data entry.
These days, with integrated symbolic debuggers and IDEs, I can start coding right away, and writing a prototype is often MUCH faster than planning it out. I'll usually spend very little time, planning, and start coding, very quickly[0].
In the "days of yore," this would have me excommunicated.
But I have found that it results in extremely well-written, well-designed, and fast end results. I also tend to work very quickly.
Being experienced helps. In fact, it may be a requirement, as I can map out a design in my head that follows the desire path to a good result. I have very manageable failures, and seldom need to throw everything out, and start from scratch.
But even then, I'm not throwing out a whole boatload of invested time and effort. It's easy to toss a bad design, and that's critical, for me.
[0] https://littlegreenviper.com/miscellany/thats-not-what-ships...
https://www.youtube.com/watch?v=OgRFOjVzvm0
In my words, he says: devs continuously change tech stacks without poking at the layers underneath. So only a few become proficient enough to focus on the abstractions.
The same happens with designers, many become technicians of graphic design tools.
You could perhaps consider starting them with Racket or some other "batteries included" programming environments specifically designed to avoid tooling bogs?
But I would be on-board if someone said that CSS is not "programming" since (AFAIK) there are no iterations, very few conditional statements, no recursion, and "library" means something entirely different
I’m not inclined to do this, because I have way too long a list of higher priorities, but I could possibly be nerd sniped into showing some proofs of concept if the idea sounds outlandish.
I would agree with the author in the sense that there should be a class or segment of the class that tackles how software engineers leverage their environment and use common tools. But, the way I understand it, that sort of thing is common in formal curriculum, it just doesn't cover everything.
I wonder if this concern the author has brought up represents a perspective trap of having a significant level of lived experience. It's probably anxiety-inducing to think of someone leaving your class and not knowing 100% of the things a software engineer needs to succeed. But, really, if we think back to how we all were as students all those years ago, we were probably in the same boat.
For example, personally, I didn't know how to use source control until I entered the industry. I learned git on the fly because an employer needed me to. Multiply that same story a few hundred/thousand times that you've got an experienced practitioner.
But since you’ve started this topic, I gotta say I love Gradle and I think it’s the best build system out there (until you reach a certain (huge) scale - then look at Bazel). I learned it by reading the docs a few times and contributing to OSS projects, improving their build scripts and plugins. Feeling pretty confident with it now. I don’t get why it gets so much hate - as if people didn’t want to spend time to actually learn it. If Gradle gets this much hate, then CMake should get 100x more.
Its learning curve and user-friendliness, however, are truly abysmal imho.
I recall a few years after leaving university talking to a few friends who worked there in the Computer Science department. They would regale me with tales of students who would constantly complain to the dean that the assignments were too hard, why where they being forced to learn stuff not currently used in the industry, and bemoan the fact that they couldn't turn in their source code as a Microsoft Word document (seriously). They were, by God, paying all this money!
By the way, this was in the mid-90s. I can only imaging it being worse today.
But at that moment computers bifurcated: real computers for programmers, and appliances for the rest of them.
This is a design challenge: crafting tools that are laser-focussed on their actual purpose and trying to make it as straightforward as possible for users to do what they intent to do. It takes empathy and clear, simple and pragmatic thinking, which can be surprisingly hard for many people and I believe it becomes harder the more we become entrenched in our profession and its way of doing things.
In my own experience, if I had not discovered Processing I am not sure if I would have actually gone down this path and become a developer. Before that, I had so many frustrating experiences with tools and especially the command line. Everything was just so opaque to me, since I had no one with programming experience to guide me through and when I tried looking something up, I felt like I was going down a neverending rabbit hole. Now I really enjoy digging into the most obscure tools and programming languages, use Vim and Emacs daily (yes, you can like both) and actually enjoy writing shell scripts.
I think if beginners actually get to experience what it is like to program something that is meaningful to them, that they care about or just enjoy, they will become motivated to learn all the hard and annoying things as well. But they should not be stopped by hundreds of landmines and roadblocks before they even get there.
- it changes the names of static files (e.g videos), if you put "type=module" on a script tag it deletes it (after investigating its due some incompatibility with how parcel works and top level awaits)
- if you try to use any library that works on both the browser and node like fabricjs it fails at compile time (some parsing goes wrong), if you try to find some way to ignore such files you discover the only way is to host that script online because parcel doesn't touch these
- if you use shadow Dom in your app it appends everything inside those twice when hot-reloading modules (tbf that has an easy solution that listens, to listen a parcel event to force a reload, about 3 lines of JS)
And some other smaller issues, in conclusion it was a mistake, I converted it to webpack an it works all better now, I should have gone with webpack from the beginning and avoid things I haven't used before just from fake promises of simplicity.
In what way is trying to cram learning react into one week a good idea? Especially if someone is already unfamiliar or struggling with classes and functions and using the tools. I've seen experienced programmers not really grasp react in a week.
This feels like a "if we skip all the fundamentals to train 'marketable' programmers as fast as possible then they struggle with fundamentals" problem.
The terminal might seem arcane, but the fact that you can copy/paste commands in there is a huge win. I'd much rather copy/paste some terminal commands into a safe place than try to take notes on what to click on to see what in a Windows system.
1. Coming up with an algorithm which really means expressing it in SOME language. That language can be pseudo-code or plain English.
2. Getting the computer to execute that algorithm. That requires that you get the computer to understand what you say is your algorithm.
The latter can be called the "tooling" issue.
The "tooling issue" is as important as algorithm development. Algorithm is great but you must be able to express it, in a way that somebody else besides you hopefully the computer understands it.
It's like a composer would come up with a fantastic song in their head, but then for one reason or another were not able to play it to anybody.
Tooling is about communicating with the computer, getting it to understand you, do what you want it to do.
Not sure they still run.
Ah, but the terminal is also the territory where the low-dependency, instant-gratification, just-get-coding tools live.
But why do you care about the backward culture more than the real students?
This is so true.
Can you see why students might be confused?
These two often overlaps but they doesnt have to.
Nope. Totally not. I spend all my time creating super-simple code using as few abstractions as possible. If anyone thinks my code is "elaborate" then I done it wrong.