Camp 3: Those of us who have viewed coding as a craft.
Math - the study of well defined concepts and their relationships. Solving problems with proofs.
Engineering - solving well characterized problems based on math and physics (which can include materials with known properties, chemistry, approximations, models, …), and well defined areas of composability (circuits, chemical processes, structural design, …)
Craft - solving incompletely characterized problems with math, physics, engineering and enormous amounts of experience, intuition, heuristics, wisdom, patterns, guesses, poorly understood third party modules, partial solutions pulled from random web sites …
Art - Solving subjective problems by any means necessary.
> Engineering - solving well characterized problems based on math and physics (which can include materials with known properties, chemistry, approximations, models, …), and well defined areas of composability (circuits, chemical processes, structural design, …)
Eh, I think you’re overselling how precise and well defined engineering is in other fields. Engineering in other fields is just as much dealing with poorly characterised problems as it is when writing code (it takes quite a lot of characterisation to go from “we want a bridge here”, to an actual damn bridge, and that’s all an engineers work).
Really the core of engineering is just a very broad set of practices and principles that allows people to solve poorly characterised problems using maths, physics, enormous amounts of experience, intuition, heuristics, wisdom, patterns, educated guess etc in a reasonably consistent and repeatable manner. Doesn’t matter if you’re building a web browser, a motherboard, or a bridge. You don’t get a good result without a healthy dollop of wisdom, experience, educated guesses, and a handful of fuckups (which hopefully you notice before you let people use the thing).
Engineering in other disciplines is no less messy, haphazard, and experimental than it is in software. It just isn’t as publicly documented as it is software, probably because it’s hard to build an open source bridge.
Well, most engineering fields have well defined applied math that spans from the problem domain to the solution domain.
Logic in digital circuits.
Algebra and calculus for analog circuits, most physical objects, properties and processes.
Differential equations for dynamical systems and dynamical behaviors.
Sure there is a lot of creativity in engineering, but there is usually a whole area of math known to be suitable for expressing solutions clearly, given the area of engineering.
Contrast with the utter lack of standard notation across software tools and implementations, for describing all the trade offs, gotchas, glue, historical drift & complexity, theories of memory, caching, user affordances, potential overflows, races, etc. that is implied by a program’s code.
Sometimes a language provides islands of engineered code, like message passing in Erlang, or memory management in Rust, or a precise mathematical library like BLAS.
But most aspects in most software programs are created ad hoc, or inherited from someone else’s rats nest of an implementation, and never formalized completely, if at all!
Any clarity in representation quickly leaves planet applied math.
> Sure there is a lot of creativity in engineering, but there is usually a whole area of math known to be suitable for expressing solutions clearly, given the area of engineering.
Take it from someone who’s studied the maths you’ve described and applied it in a professional capacity. Just knowing the maths isn’t anywhere near enough. It’s like knowing how quick-sort works, interesting and useful, not even close to enough to actually build anything.
> Contrast with the utter lack of standard notation across software tools and implementations, for describing all the trade offs, gotchas, glue, historical drift & complexity, theories of memory, caching, user affordances, potential overflows, races, etc. that is implied by a program’s code.
The entire field of computer science is dedicated to developing and using this type of notation to describe and understand the basic principles that underpin every programming language, database and algorithm you’ve ever touched. The notation exists, you just don’t use it. In the same way an engineer in another field doesn’t bother doing structural analysis, or circuit analysis from first principles, they just grab a pre-finished tool and apply it to their problem. Normally by just passing the problem to a computer that does all the heavy number crunching, and checking the outputs make sense.
> But most aspects in most software programs are created ad hoc, or inherited from someone else’s rats nest of an implementation, and never formalized completely, if at all!
>
> Any clarity in representation quickly leaves planet applied math.
Again, I think you’re vastly overestimating the precision of other fields of engineering. There might be more rigour in design in some places, but only because “just making a thing and see if it works” is expensive, but other engineers absolutely spend huge amounts of time just making things to see if stuff works.
There’s a reason why “safety factors” are a thing, and reason why they’re usually 10x or greater. That safety factor is also the “we’re not sure how well this works, so we made it ten times stronger than we think we need, just in case, factor”. Engineering in other fields is people doing maths all day long, it’s mostly reading data sheets, assembling Lego brick components, and hoping to hell the manufacturer didn’t lie too much on their data sheet. Plus some design and simulation on a computer for good measure.
You wanna see “ad-hoc or inherited from someone else’s rats nest of an implementation” in a different field of engineering. Then go look at any electronics catalog, or lookup YouTube videos of people testing parts against the specsheet and discovering how wildly different they can sometimes be.
Dodgy, badly implemented, never formalised engineering exists everywhere. That’s why bridges collapse when they shouldn’t (Genoa Bridge), why planes crash when they shouldn’t (Boeing 737 Max), why cars emit more emissions than they should (VW), why buildings get emergency modifications after being built to prevent them from being blown over (601 Lexington Avenue). Software engineering does not have a monopoly on botches, last minute hacks, and dodgy workarounds. Engineers in other fields were merrily employing all of them to great effect for centuries before software turned up.
I recall a self taught dev (or maybe from a bootcamp) coming up with a cascade of nested if-else, nested 8 deep. Someone with a background in CS asked him what he was trying to do and basically concluded that what he was trying to do could be expressed as a state machine. To which the initial dev replied that it was "way too fancy" and that he didn't need the code to be fancy, just work.
The ugly part: The nested-8-deep solution was faster to market and costs less. And, it will be thrown away in 6 months during the "big rewrite after we scale". So the perfect-is-the-enemy-of-good state machine solution written by an expensive engineer has less value. Oompf.
Possibly. Or not. It could be that the elegant expression can be written in less time by the expensive engineer, doesn't need to be rewritten in 6 months, and it may be that both of these people are getting paid the same anyway. So you can make up any "just so" story that you like about a made-up anecdote. If programs A and B implement the same function and both have adequate performance, then the differences between the two artifacts come down to style.
> If programs A and B implement the same function and both have adequate performance, then the differences between the two artifacts come down to style.
What about maintainability? Extensibility and ease of debugging?
I've seen chunks of projects re-written, just because it was simply impossible to extend them without significant efforts!
Well yes, that's what we're talking about. I mean that the compiled artifact is equivalent, but of course you may have reason to care about the style of the code.
I have a camp 4: viewing coding as a roadblock. A necessary obstacle to achieving some result. This is how companies view programming. They don't know about it, don't care about it, they just know they have to do a lot of it to produce their next product.
Tacking roadblocks as they come up in service, creating a better product … that sounds a lot to me like engineering except with some words twisted around?
I cringe every time I see someone use the term "craft" in the context of computer programming. It feels like a desperate attempt to seek adoration as a "sub-genius" in a poorly understood field. Computer programming is hard because the platform is either poorly documented or changes very quickly. Too much of my professional work is about finding a "super hero" (their term, not mine) solution to a poorly documented problem. It is tiring, and not-at-all heroic. Coding bootcamps have taught us that when you tear down the gatekeeper walls, more people can write CRUD apps (that the world actually needs) than ever thought before.
[otherwise a (code) monkey could do it] is missing the point of programming.
I know managers who code (occasionally) who think similar. I thought so personally before I had actual prolonged experience with professional programming.
It is hard to express it concisely: why it is fundamentally wrong (category error: like thinking that perl regexes can be reduced to DFA--it is impossible in the general case even if DFAs can [sometimes even should] be used in many cases instead).
It is the same reason why waterfall programming fails most of the time. It is the same reason why generating code from UML diagrams produced by analysts is also a failure in the general case. It is the same reason why log normal distribution can be a good model for software estimation https://news.ycombinator.com/item?id=26393332
And no, you can't replace all programmers with a LLM prompt for the same reason (at least until [if ever] it reaches AGI and then humanity would have much bigger problems).
"agile" became a noun but if you look at the origins, you might get why "craft" may be applied to programming. Try "The Pragmatic Programmer" book.
Engineered projects, formally (or close to it) verifiable: 3D rendering pipeline, distributed database management, garbage collection process, ...
And craft. Which, based on the internet I have experienced, many apps unjustly inflicted upon me, and some memorable restarts between game saves, is most code.
Craft code necessarily involves amateur code, code which isn't economically worth engineering (when you can just throw unit tests at it. Or just wait for user reports!), code referencing weakly characterized libraries or interfaces, and code involving features that have become complex enough that the best reference model for its expected and unexpected behaviors is now itself.
Bzilion's Law of Coding Formalism Levels: "Any ambitious enough software project will descend into an exercise of pure desperate craft. Just before it becomes gambling."
Math - the study of well defined concepts and their relationships. Solving problems with proofs.
Engineering - solving well characterized problems based on math and physics (which can include materials with known properties, chemistry, approximations, models, …), and well defined areas of composability (circuits, chemical processes, structural design, …)
Craft - solving incompletely characterized problems with math, physics, engineering and enormous amounts of experience, intuition, heuristics, wisdom, patterns, guesses, poorly understood third party modules, partial solutions pulled from random web sites …
Art - Solving subjective problems by any means necessary.