10 ms·
Overcoming Intuition in Programming
- bordercases 11y agoEdsger Dijkstra's work was almost entirely oriented towards breaking programmer intuition, emphasizing that we should reason /as/ the machine and eventually /ahead/ of the machine. http://www.cs.utexas.edu/users/EWD/ewd10xx/EWD1036.PDF http://www.cs.utexas.edu/users/EWD/ewd10xx/EWD1036.PDF
- amasad 11y agoDijkstra's work is definitely an inspiration. The only thing I disagree with his views is that using analogies and metaphors in programming is always bad.
- mrestko 11y agoWow, he has interesting handwriting.
- poof131 11y agoYep, you can even get it as a font.[1] [1] http://www.fontpalace.com/font-details/Dijkstra/ http://www.fontpalace.com/font-details/Dijkstra/
- musha68k 11y agoThank you very much for sharing this. Edit: It always feels as if Dijkstra had been a true 50/50 growth/scarcity mindset kind of guy, in any case it's a very worthwhile read I think so I've re-shared your article over here: https://news.ycombinator.com/edit?id=10837146 https://news.ycombinator.com/edit?id=10837146
- bordercases 11y ago> 50/50 growth/scarcity What exactly do you mean by this, how does Dijkstra represent it and where can I learn more?
- ilostmykeys 11y agoThe idea behind the ultimate user interface is for programming labguages to dissolve over time leaving us with a natural conversation between man and machine (and at some point the distinctions betweem man and machine will dissolve) While I understand what he and others have said, which is what I had believed in the past, I think that the emphasis to think like a machine is heavily misguided as we as users need to steer programming languages toward their natural end (pun intended) which is where AI is headed. But we're miles away from that so the argument he puts forward is temporarily valid.
- Sacho 11y agoI'm not sure this is a great idea. "Natural" communication is incredibly inefficient and lossy. Note that academics communicate via meticulously written papers, often involving very formal language. Business processes are structured in worksheets, graphs, etc. What we seem to yearn for is the ability for a computer to transcend our inability to express ourselves. I am not so sure that is where we are(or should be!) headed. There is a certain internal clarity when you manage to formalize your thoughts and arguments, to test them for logical inconsistency and errors. Programming languages are an inherent helper in that regard. I think the biggest hurdle for programming languages currently is flow control. Specifically, programming languages are mostly still written top-down, leaving the implicit assumption that code is executed in the order you read it in. This is obviously a false impression for pretty much any program written nowadays. Inventing a new way to present code so that program flow is easier to visualize, is in my opinion the "next big thing" in programming language UI. This is something tools and concepts like UML have tried and failed to revolutionize, so I'm not sure what the way forward really is.
- ilostmykeys 11y agoWell, those are some deep thoughts. I appreciate the response:)
- deleted 11y ago[deleted]
- userbinator 11y agoI wouldn't call it "intuition" exactly, but more of a "desire to avoid responsibility" --- I've worked with the programmers he describes, the ones who will spend literally hours searching for a library/library function to do some trivial task when he could've written it in tens of minutes at most. The functionality of the one that gets chosen invariably remains 99% unused, adding bloat and making the dependencies more complex. Software ecosystems with many large framework-ish standard libraries tend to encourage this behaviour more. we should be careful to not enable the belief that programming should be as easy as gluing things together Absolutely agree, although a lot of it is.
- rileymat2 11y agoOn the other hand I have seen many functions that were written in 10 minutes that are utterly broken except for the most common cases. Where a library function should have been used because the programmer did not understand the depth of the problem.
- yoklov 11y agoIt's easier to fix those than extract a dependency or remove bloat.
- MaulingMonkey 11y agoNot when those ten minute functions add up and become a bloated dependency it isn't.
- enraged_camel 11y agoYep, exactly. 80% of a feature may take 20% of the time to develop, but the rest (edge cases) will take the majority of the time, and that's time you could have spent working on core features for your system. That's why it's almost always better to use an existing library: chances are most of the bugs will already have been encountered and squashed. I find the whole "do it yourself" mentality to be a form of NIH syndrome.
- Animats 11y agoI used to refer to this as "ritual-taboo programming", where people know what rituals work, and which to avoid, but don't understand why. This comes from reading books which are all examples, but don't provide reference documentation. I used to consider this a vice; now, it's normal. It's necessary to deal with the flood of sort-of-working software components one has to deal with today. Dijkstra was once the head of the "programming is hard and programmers should suffer" school of thought. Few people read his books today.
- edejong 11y agoDijkstra would agree that programming is hard, but not that those who program should suffer. Quite the contrary, I'd like to add, as he would often point out that programmers currently suffer because of their leaky abstractions and continuous bug fixing. He wanted to bring programming back to mathematical fundamentals, so it is simple to reason about. It is my personal opinion that this ethos is the drive behind the renaissance of functional programming. Programming is hard. I've been programming for 25 years now and if anything, it never gets easier. To find the right abstraction, so only the correct things become simple, is one of the hardest tasks.
- klibertp 11y agoFP is not "easier to reason about" (for humans; it is easier for machines). It's getting popular because it promises composability and reusability: the very thing OOP promised and failed to deliver. FP will fail, too - there's no silver bullet! - and then we'll move to something else.
- strmpnk 11y agoYet composability is exactly what makes it easier for humans to reason about. It's the small surface of a composable part that fits into more immediate representations in our mind. Whether or not it's natural mapping functions to and from concepts people might already operate with isn't the same problem. I'd argue that one can be offset with practice, though it's certainly not something that is easy for everyone. In that sense, FP might be a bit more immune to bad intuition, if only that you have to give up on mapping structure to insufficient analogs. The late object oriented point of view makes this step trivial for our minds and is thus a significantly complicated trade-off to quantify.
- jakejake 11y agoIt's an interesting idea and one that I find to be true, but also complicated. We're also trained as programmers not to reinvent wheels poorly. Or not install a library to do something that is already supported by an existing library you're already using. When you need to do something like, say, open a new browser window, it's not that surprising to find a lot of posts about how to do it with jquery. I don't find it always bad. As long as you understand that you are using a library, it's ok to go searching for its edges.
- pixie_ 11y agoI talk with a lot of programmers that think that abstracting everything is super important. Everything must be a black box and the programmer should have no idea what's happening inside of it. Their code is an over engineered mess of interfaces, dependency injection, and code so deep and isolated you have no idea how anything ever works (I mean like even if you had the source code it's so convoluted you could never make any use of it.)
- userbinator 11y agoAre they mostly Java, C#, or "advanced C++" programmers by any chance? I've noticed such designs seem to be the norm in those cultures. On the other hand, C and Asm programmers tend to be more KISS+YAGNI in their code. Perhaps it correlates with the ability of the language/tools to make it easy to generate huge amounts of code without much thought: if you can create a dozen classes with a dozen methods by a few tens of clicks in the IDE, you're far more likely to do so compared to writing each one of those classes, functions, or even the instructions in them manually. It's a form of cargo-cult thinking combined with the fact that a lot of beginning programmers are exposed to the "abstraction is good" dogma without ever realising that it can turn into too much of a good thing. Vague statements like "single responsibility principle" (what is a "single responsibility"?) can encourage a ridiculous amount of over-refactoring, driven by the idea that shorter functions are better --- which is true up to a point, but I've seen it taken to extremes where more lines in the file are function declarations and their opening/closing braces than actual, purposeful, code. They almost always argue that a shorter function is better ("after all, isn't it easier to read 1 small line than 10?") but neglect to realise that they've actually increased complexity of the whole by forcing readers to go through deeply nested function call stacks. Meanwhile, names tend to get longer due to the specificity of these tiny pieces, which doesn't help much with readability. In some very extreme cases I've seen, the name ends up being longer than the code it describes.[1] Instead, I think we should be teaching abstraction as a tool like any other --- use it when it helps reduce complexity by reducing code duplication, and warn against its overuse. Under-abstracted code is tedious and repetitive, but reasonably straightforward to understand, since most people tend to find reading things linearly to be quite easy. Over-abstracted code is highly nonlinear and takes you through an elaborate maze-like path. [1] http://git.eclipse.org/c/aspectj/org.aspectj.git/tree/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor.java http://git.eclipse.org/c/aspectj/org.aspectj.git/tree/org.as...
- d23 11y agoWhat a convoluted way of saying: "use frameworks and libraries, but not all the time." Yeah, we get it, some people use libraries too much. Some people reinvent the wheel too much. It's not too hard to understand that judgment is key when deciding on one over the other. Did I miss something, other than the attempt to coin the phrases "framework negative space" and "framework intuitive space"?
- girvo 11y ago> not too hard to understand that judgement is key The state of most commercial codebases and a lot of colleagues I've worked with, and my own code as well show that it is indeed that hard, I'd like to argue. It's easy to state, difficult to do well.
- quanticle 11y agoI wonder how much "nice" IDE features like auto-completion and auto-refactoring go towards encouraging an "intuitive" mode of thinking. I've definitely noticed that when I work on Java or C# code in vim, I have to think about it much harder than when I work on the same code in IntelliJ or Visual Studio. The lack of automated refactoring forces me to slow down and think about what I'm doing, and reason about all the implications of my change, rather than just clicking some buttons and letting the IDE take care of the rest. That said, while I'd like to use as my sole development tool, I'm not sure I'd be able to. The (proprietary) framework I'm forced to use is basically impossible to navigate without some kind of IDE support. Yeah, it's not ideal, but it's the state of the world I have to deal with.
- CodexArcanum 11y agoAlthough his actual point had almost nothing to do with intuition, I still would like to argue in favor of intuition. Maybe not while writing code, but I find intuition very powerful when reading, reviewing, and refactoring code. This is what people often talk about as code smells. When you've trained yourself in how good code looks, then bad code stands out to you. Once intuition has led you towards where attention is needed, then analysis can begin to devise the best solution. I find this to be a critical technique and tell people all the time to train their intuition. It's a tool like any other, to be honed and applied with skill.
- freedrull 11y ago> I get a lot of questions from aspiring programmers on what’s the best tool or languages to learn. It’s almost always a premature question to ask. I often think about how to answer this question to beginners as well. I think he is right, the answer is probably "it doesn't matter".
- TurboHaskal 11y agoExplain that to HR drones. Tooling matters a lot if you want to be doing this for a living.
- TeMPOraL 11y agoEvery now and then spend a whole weekend (or just a week of after-work hours) learning the new hot X to the point you can honestly say you know something about it (it doesn't take that much for an experienced coder to learn a new thing) and bam, you have another buzzword for your CV. Select as needed to get through HR filters.
- vonmoltke 11y agoWhich is great, if the HR filter is simply "does X appear on the resume". It it is "does X appear on previous job experience" you are still screwed.
- marcosdumay 11y agoI don't have many resumes out there today, but I've never let HR people know if any X belonged to what previous experience, or home project or what. If they wanted to know, they'd have to ask me. Very few times, they did.
- TurboHaskal 11y agoStill not the same as working experience. And honestly I'd rather get payed for tinkering around. Resume Driven Development is where it's at. Docker? Our "modular monolith" works just fine, but with Microservices we can now rewrite everything in Rust and Elixir. Lock ourselves with yet another build / automation tool just to remove trailing whitespace. Add RethinkDB and Redis and that new graph database now that we're at it. Let's pray for updated NixOS binaries! For toy projects I'll stick to OpenBSD, Perl and ancient tools like make, awk or even rc.
- nbouscal 11y agoThe experiment referenced about disfluency has repeatedly failed to replicate. Meta-analysis here: https://www.academia.edu/11918605/Disfluent_Fonts_Don_t_Help_People_Solve_Math_Problems https://www.academia.edu/11918605/Disfluent_Fonts_Don_t_Help...
- lfender6445 11y agosome of the pitfalls to intuition echo the side effects of programming by coincidence, outlined in pragmatic programmer https://pragprog.com/the-pragmatic-programmer/extracts/coincidence https://pragprog.com/the-pragmatic-programmer/extracts/coinc... > Don’t code blindfolded. Attempting to build an application you don’t fully understand, or to use a technology you aren’t familiar with, is an invitation to be misled by coincidences.
- DanielBMarkham 11y agoI have become very framework-adverse over the past few years as I've switched from corporate programmer to startup programmer, and from OOP programmer to FP programmer. Frameworks, especially OOP frameworks, tend to throw you into a universe of nouns and verbs that can be quite complex and completely of the author's making. Everything works great -- until it doesn't. And then you're spending your valuable time and brainpower learning about some framework instead of about how to do the job you're trying to do. That's almost always a fail. As the author mentions, it just gets worse: many times you're suckered into thinking the answer for your problem is yet another plug-in or framework. Now you have even more stuff to keep track of. OOP forces you to answer the question: what does this system represent? Once you do that, then you're left with several metric tons of how to represent it well, which can lead to a _lot_ of stuff. FP, on the other hand, forces you to answer the question: what, exactly, do you want the system to do? As it turns out, unless you're strictly happy-path, the shortest way to an answer is just to do the work. (Of course, nobody is saying to throw out core libraries and start writing in machine code. But if you're bleeding to death from paper cuts on WhizBang 4.0 that you just downloaded last week, you screwed up.)
- ourmandave 11y agoEsp. when WhizBang 4.0 is a complete rewrite of the codebase so throw out everything you know about WhizBang 3.0.
- DanielBMarkham 11y agoAnd your existing code already has workarounds for 3.0 which are invalidated by the upgrade.
- ourmandave 11y agoDon't worry about those workarounds. They're on features that were deprecated. =)
- lowbloodsugar 11y agoI find that I use OOP to model what I want my system to do rather than naive OOP of "I have a square and a circle". Unfortunately, this invariably leads me to Greenspun's tenth rule.
- z3t4 11y agoI think this is the reason why "functional" programming results in fewer bugs ... or that you need to be really smart to do it. Or because you most of the time is refactoring the program (from an imperative language).
- aalhour 11y agoI have been thinking about this since last night, and here are my thoughts. I totally agree with Amjad on avoiding framing programming as an intuitive activity. But on the other hand, framing it as a hard intellectual activity for beginners is also troublesome. I am facing this now as I am helping my younger brother in his Computer Science B.Sc. program, and taking different isolated courses for few months two or three times a year makes academic/intellectual studying for this industry without experience a hassle. I keep listening to him and one of the most common complains he says is: "I don't know how all these - OS, Automata, Java, Web, Algorithms and Math - pieces fit together." I think I can relate to this frustration/confusion because I went through it when I was obtaining my B.Sc. degree but I cannot exactly remember nor reproduce how I overcame this phase, or made sense of "it" all (for lack of a better term). Can you folks help me with this? How would you guide or help a beginner like this person in programming?