9 ms·
Programming for the lowest common denominator? Something about that sounds wrong. I generally agree with "use only as much cognitive overhead as needed to get
by qorrect 9y ago
Programming for the lowest common denominator? Something about that sounds wrong.
I generally agree with "use only as much cognitive overhead as needed to get the job done" ( I'm enjoying that term ) - but it seems like a slippery slope that could slowly bring everyones abilities down to the least capable developer.
- stouset 9y agoIt's also an excuse to avoid any sort of abstraction whatsoever, which makes solutions to genuinely difficult problems impossible to read, since one has to wade through the low-level details at every step. To me, it's a bit like telling a person how to get from point A to point B by telling them when, how hard, and for how long to step on the gas and what angles to put the steering wheel at. Sure, that might work to get someone out the driveway, but good luck getting to the grocery store that way. I will genuinely never understand the go philosophy that "excessive" abstraction is bad, with no attempt to justify why current levels of abstraction — which are charitably hundreds of times more complicated than the difference between, say, go and ruby — are good, right, and just. Everything we do on a computer from processing to memory access to networked communications to rendering to handling input to relational data modeling to… anything is dozens of layers away from what's actually happening. But somehow right now we're at the optimal level of abstraction and any more would just be too much. Okay.
- teej 9y agoHere's the thing though - most programmers are not working on "genuinely difficult problems". Yes, abstraction is a useful tool but like many tools it's harmful if used improperly. Code has a tendency to live way longer than a programmer expects. Writing code that is simple, quickly grokable, and low risk to change is really important. Especially when 3 generations of software developers have come and gone between the original author and the current maintainer. I think falcolas's philosophy is spot on - treat most problems plainly and simply. In the rare event a genuinely difficult problem arises, use your tools to get it done right.
- stouset 9y agoAbstraction is the process by which you now have the privilege of saying that what most developers do is not a hard problem. There's a reason why we're solving the problems of today today, and not two decades ago. You're right that code is read many more times than it's written. That doesn't argue against abstraction — it argues for it. But it argues for choosing the right abstractions, and that's where I feel like we do a poor job as an industry. I've worked in large code bases with no abstractions and the grass is assuredly not greener. Every solution to every problem is as I said before — akin to reading directions specified in pedal pressure and steering wheel angles, rather than in terms of streets and turns.
- clusmore 9y ago> You're right that code is read many more times than it's written. That doesn't argue against abstraction — it argues for it. But it argues for choosing the right abstractions, and that's where I feel like we do a poor job as an industry. Completely agree with this point. My go-to example of why abstraction should be used to increase readability is street directions. Imagine somebody asks you for directions to a restaurant, and consider how different your answer would be depending on how well the other person knows the city. If they are a tourist, you might need to give them very detailed directions, down to the level of "go forward X blocks, turn left, continue for Y blocks", etc. Conversely if they are a native, the directions could simply be "It's right next to Z". Obviously the latter directions are useless to the tourist but the former are far from ideal for the native -- it's just way to verbose, easy to forget and easy to get confused by. Understand your audience.
- Veedrac 9y ago> no attempt to justify why current levels of abstraction — which are charitably hundreds of times more complicated than the difference between, say, go and ruby — are good, right, and just It seems to me that Go is part of a reaction from people who are not happy with current levels of abstraction.
- stouset 9y agoEvery person who's bet against additional layers of abstraction has been on the wrong side of history so far. I see no reason why that trend ought not continue. Some of those layers will be rethought, of course. Some will be merged. But it's inevitable that new layers will be added on. Abstraction is fundamentally the process that allows us to solve progressively harder problems, by sharing knowledge of our solutions to similar problems. It's central to our understanding of math, physics, biology, psychology, and every other scientific field you can name. Software engineering is no exception.
- Veedrac 9y agoThe losing minority, sure, but the wrong side? AAA games? Linux? Rust? Vulkan? WebASM? Yes, some abstraction is beneficial. But too much abstraction leaves you with, you know, the decrepit state of modern software. Abstraction as you actually see it isn't letting us solve "progressively harder problems", it's letting GMail take up more RAM than my OS does from boot. Meanwhile most of the really interesting problems are still done in fairly primitive languages.
- stouset 9y ago> AAA games? You mean the ones built on a handful of abstracted 3D engines like Unreal, Source, id Tech, CryEngine, Unity, etc? > Linux You mean the operating system that abstracts away from us things like filesystems, hardware access, shared memory, time sharing, networking protocols, access control, multicore processors, etc.? > Rust You mean the programming language that adds a new abstraction of "borrowing and ownership" to help simplify the confusing existing abstractions of memory management and data race detection? > Vulkan You mean the API that abstracts away parallel computation on graphics hardware, upon which they intend for dedicate graphics abstractions like OpenGL and WebASM to be abstracted? > WebASM? You mean the API that abstracts away running low-level machine code — not on your own machine, but sandboxed on remote machines via web browsers. > Meanwhile most of the really interesting problems are still done in fairly primitive languages. Do you want to take a guess why I'll argue that you consider the obscenely complicated task of "delivering secure, multiuser, interactive applications with offline persistent data storage to hundreds of thousands of remote clients" a non-interesting problem? It's only because of the incredibly successful and complex network of abstractions that are Ethernet, IPv4, TCP, DNS, TLS, HTTP, HTML, JavaScript, SQL, graphical image formats, web browsers, database servers, caches, switched networks, load balancers, and so on that these kinds of achievements that would have been considered monumental even thirty years ago are not "really interesting problems" today. Abstraction has allowed us to break apart the component parts of this incredibly complicated problem into small, independent, coordinating layers. The fact that you think that something like delivering web applications is a non-interesting problem practically makes my argument for abstraction all by itself.
- jstimpfle 9y agoParent's comment was against excessive, i.e. superfluous abstraction. And that pretty much by definition must be avoided. Abstraction in itself is a good thing. I just think of it as "compression". We have to express solutions to problems in the shortest way possible, otherwise they become unmaintainable. What most people fail to see that a dead simple language like C provides with all of the tools to solve many problems with good or optimal abstraction. And if you add abstraction like OO and implicit memory management to solutions for many complex or performance-oriented problem domains, these solutions become effectively non-solutions. Because in these problem domains, decisions about memory allocation or data organisation are part of the solution.
- stouset 9y ago"Excessive" abstraction is a misnomer. I can practically guarantee you that whatever level of abstraction we're working at today, we'll be working several layers deeper ten years from now. Arguing that, e.g., generics are "excessive" abstraction when we're already dozens of layers away from manipulating transistor voltages is bordering on the absurd. The issue people should be fighting against isn't excessive abstraction, since the only way to do so is to counterproductively inhibit abstraction in the general sense. We as an industry should focus on how to develop good abstractions while avoiding bad ones. Not that I have any particular insights on how to approach that problem. I'm just convinced that avoiding abstractions at all is throwing the baby, bathtub, and entire bathroom out with the bathwater.
- carapace 9y agoKernighan’s law: “Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
- fbomb 9y agoPerhaps, but doesn't the fact that a piece of code has bugs imply that it wasn't actually written as cleverly as possible?
- carapace 9y agoNo, the presence of bugs in a piece of code only implies that that piece of code exists. ;-)
- le-mark 9y agoThe code may not be buggy, but may surround bugs, thus the non bugged code still has to be debugged/understood. The easiest code to debug is the code that's never written (fastest too). Juniors/freshers never get this and always try to impress with their cleverness. KISS will always be true.
- nitrogen 9y agoProgramming for the lowest common denominator? Something about that sounds wrong. No, that's almost exactly right. In my experience designing, building, inheriting, and maintaining systems that in some cases predate the dotcom boom, and in others need to run invisibly for just as long into the future, it's the simplest design that's the best design (but, as they say, no simpler). I'm not talking about avoiding useful language features because nobody wants to learn them. I'm talking about the structure of the system itself. Minimize layers, minimize context, keep things as linear as possible. Don't use polymorphism just because you can, don't use functional tricks that obscure rather than enlighten the flow, don't make version zero an SOA, etc.