Hacker News new | past | comments | ask | show | jobs | submit login
When programming books are wrong (programmingbooks.dev)
50 points by cenny on Feb 20, 2022 | hide | past | favorite | 24 comments



The link was supposed to go to an article on the site (https://www.programmingbooks.dev/articles/book_is_wrong/)


HN adjusts submissions to use the canonical URL if present in the HTML. Check the source of the page and its canonical URL (on mobile and apparently you can't do view source in iPadOS' Safari).


You’re right, the page has

  <link rel="canonical" href="https://www.programmingbooks.dev">
which isn’t the canonical URL for the same content.


Tangential, check out Achoo for viewing inspecting the HTML source on iOS https://apps.apple.com/us/app/achoo-html-viewer-inspector/id...


I think this is one of the better lists out there. I own almost all of the books in this list.

But don't get your hopes up too much. I'm still a lousy programmer.


This is a nice list.

I will highly recommend The Little Schemer. You will change after reading this book. It is that good. This book made me truly undersy recursion. I understood recursion before, and used it to solve problems, but this is the book that totally scratched my surface and instilled recursion in it.

Pragmatic Thinking and Learning is the first book of its kind that I ever read. I was surprised by the quality of it. It is a very nice book with scientific and actionable advice. Will recommend it, too. (Although there are some issues like oversimplified model of brain, divided into L and R mode, and in one place it preached different type of learners theory, which is now thoroughly discredited.)

For an approachable programming book, i.e. book not CLRS, Skiena, or DPV, I will not recommend Grokking Algorithm. I will recommend A Common Sense Guide to Data Structure and Algorithm from PragProg Bookshelf. This is a much better and more complete book with exercises that are effective in learning the topics well.


Thanks for the feedback and nice words!

I will look into “A Common Sense Guide to Data Structure and Algorithm” and see if I agree with you.

But yes, little schemer is so good, wished I read it earlier than I did.


wow great site indeed my friend


Respectfully disagree. Many of these books advocate habits that actually interfere with effective code development.


Have you tried looking at the context in which the books were written and applying similar principles to your domain? Often, as time goes on, specific rules or patterns may stale and be less applicable, but the principles remain rock solid.


I don't buy that. The post quoted from _Clean Code_ by Uncle Bob:

> The ideal number of arguments for a function is zero (niladic).

Uncle Bob is an idiot for making this statement. Taken at face value, just where is the data for the function to operate on come from? With no parameters, it must come from data at an outer scope, usually a global, which is a bad idea. Within the context of the language Uncle Bob is blathering about, Java, each "function" has an implicit argument, which is the object itself. So even if Uncle Bob wanted a zero-argument function in Java, he's not getting one. The arguments are still coming from an outer scope.

Just this one statement makes me less inclined to take anything he says seriously.


> Uncle Bob is an idiot for making this statement. Taken at face value, just where is the data for the function to operate on come from? With no parameters, it must come from data at an outer scope, usually a global, which is a bad idea. Within the context of the language Uncle Bob is blathering about, Java, each "function" has an implicit argument, which is the object itself. So even if Uncle Bob wanted a zero-argument function in Java, he's not getting one. The arguments are still coming from an outer scope.

You're kind of making the author's point for them here. The entire premise of OO languages is to colocate functionality with the structure of the relevant data for that functionality.

If you write a function which takes zero arguments attached to the class Integer (perhaps toString), it does in fact have zero arguments. This makes it simpler to reason about in the context (key word from the point the author was making) of Java. In that context, it is self-evident that any method attached to a class that takes zero arguments is operating entirely on either the data within the class or static data available system-wide.

The idea you're presenting is mostly pedantry and you've confused function arguments with data accessible to a function.


> Uncle Bob is an idiot for making this statement

Bold claim for someone who didn't even read the whole quote in context.

> The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification-- and they shouldn't be used anyway.


To be fair it doesn't make any more sense even with the full context. It is just a silly thing to say and it was said without much of a supporting argument at all, never mind any real evidence for the validity of the claim. That is an unfortunately common problem with Clean Code and a lot of other work by Martin.


I think there is a point to "less function arguments is better".

A good example is difficult to come up with, but the basic idea is usually a function with 4+ args can either be split into two functions or args can be turned into a sensible data type.

Here's an okay example:

    areaIrregOctagon :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int

    type Octagon = (Int,Int,Int,Int,Int,Int,Int,Int)
    areaIrregOctagon :: Octagon -> Int


I think there is a point to "less function arguments is better".

I think the real problem in your example isn't the number of arguments but passing separate values that logically belong together as a single coherent piece of data. You could make the same argument about passing a Point parameter for a 2D position instead of a pair of separate co-ordinates (and the argument would still be just as valid if you did).

Of course that isn't what Martin said anyway. He said the ideal number of arguments is zero, which is absurd. The ideal number of arguments is however many you need to pass in the relevant information for your function to do its job, hopefully in a representation that is clear and easy to work with. If he'd suggested that this will often be a small number because there are often more effective ways to represent the data in functions taking many arguments (and look, here are some examples of those ways) I might well have agreed with him.


People get such hate-boners for "Clean Code" specifically, it's weird. I once thought they might have had a point until I read the book and, while I found much to disagree with, it's actually not a bad book (I have more negative things to say about an oft-cited "counter" book, "A Philosophy of Software Design"). I think there's useful things to learn and consider in it, and even though I think you can do better by thinking for yourself, the average bar is so low among programmers that I think many would be improved by substituting their non-thinking flailing around for non-thinking dogmatic following of such books' rules of thumb. Working in such a dogmatic environment would be oppressive, though you at least have a framework to move beyond some of it. Presumably such environments exist and maybe that's a source of some hate, though I've more often seen oppressive environments that e.g. won't accept any Python commits which violate the changing PEP8 lint checks despite PEP8 itself allowing for differences of opinion.

There's even more context that people should consider. From earlier in the same chapter:

"The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that. This is not an assertion that I can justify. I can’t provide any references to research that shows that very small functions are better. What I can tell you is that for nearly four decades I have written functions of all different sizes. I’ve written several nasty 3,000-line abominations. I’ve written scads of functions in the 100 to 300 line range. And I’ve written functions that were 20 to 30 lines long. What this experience has taught me, through long trial and error, is that functions should be very small."

My relevant point here is that it's clearly not a book full of careful supporting arguments and cited research or really even hyper-specific non-fuzzy rules. It's a style guide for how to make "clean code", built from the author's experiences and idea of what "clean" means. Disagreement is natural, and often also based on nothing more than different experiences rather than careful arguments/research. It's also very contextual, as the book itself notes in places -- different languages, tooling, or emphasized programming paradigms will produce different ideas of what clean means.

For the issue about function arguments, in the full context it's very clear that in Java we don't idiomatically interpret the implicit "this" to be an extra function argument as we do in idiomatic Python with its explicit "self". Immediately after the quoted sentence on number of arguments is this: "Consider, for instance, the StringBuffer in the example. We could have passed it around as an argument rather than making it an instance variable, but then our readers would have had to interpret it each time they saw it."

That the bytecode for a method using an instance variable includes an "aload_0" instruction to load up "this" and "getfield" to get the instance variable value is an implementation detail. Would it have been better, from a purely functional perspective, to pass the StringBuffer around explicitly anyway? Maybe. Same maybe when it comes to unit testing concerns. Anyway, I don't see much complaining when function bodies make use of implicit built-ins like + or - or sin() or PI, instead of passing all such things as explicit arguments. That way leads to Enterprise FizzBuzz in the Java equivalent.

Sure, data not part of the method body has to come from an "outer scope", but this is not "usually a global" but an instance var, and in the very worst is a package-namespaced var. Is it a great sin to lift something into an instance variable? No, not in Java. And even for true 0-arg functions (static methods), the data can come from the method body itself. This is naturally part of the style advocated throughout the book, where you might have e.g. 10 lines of printing out some literal strings (perhaps a little help manual), you can extract those ten lines into a standalone 0-arg static method and the original method will be shorter and cleaner.

Edit: one last thing for consideration, Linus has written in the kernel coding style guide "...if you need more than 3 levels of indentation, you're screwed anyway, and should fix your program." Is he an idiot for making such a statement? Is it a silly thing to say?


I wouldn't characterise my views on Clean Code using those words but I do believe that Martin has probably done more to damage progress in our industry over the past decade or two than almost anyone else.

I don't doubt that his views are a reflection of his own experience or that he truly believes in them and passionately advocates them. Unfortunately none of that makes him right on these issues and it's never been clear to me what experience he actually has that qualifies him to speak with the authoritative tone he adopts.

Worse is that the way he presents, everything from the folksy nickname to the less than subtle implication that if you disagree with him then you're "unprofessional", is designed to stifle debate. It's like he invokes No True Scotsman on anyone with a dissenting opinion before they've even spoken.

The trouble with this is that the very people he targets -- the younger, less experienced, more easily influenced developer -- are often unable to see these things for themselves. They see widely recommended books like Clean Code and take it as gospel. And then the rest of us have to clean up the mess when those juniors end up working for us and produce junk of the kind Martin has often presented.

And finally, in response to your edit, I don't think Torvalds is an idiot but I also think in this respect his opinion is based on the kinds of software he has worked on. I have worked on certain kinds of algorithms where deep nesting is exactly what you want, and unlike most who dogmatically advocate no more than N levels of indentation, I have years of test and profiler results to prove it. It's true that those algorithms were quite specialised in nature and normally I too wouldn't write code more than a few levels deep.

The point in all of these cases is that dogma is not a substitute for understanding. In a field as huge as programming there are likely to be useful exceptions to almost any rule. Teaching the what without explaining the why can be harmful.


I really disagree about damage to our industry over the last 10 or 20 (or 30) years. But I haven't deeply considered such a topic. I have thought a bit about damage to specific areas (e.g. don't get me started on systemd) but damage to such a broad topic as "our industry" I'm inclined to first look for kinds of "original sin" that predates the 90s since "our industry" is older than that. My favorite computer book in the last few years remains The Psychology of Computer Programming which was written in 1971. So many problems brought up in it still bother us to this day, though some have been solved or mitigated or obsoleted. For lack of progress since then in certain areas, is there even really a single person or group left to blame? I'd sooner put ongoing damage to progress or other things as due largely to human nature in things like not knowing history and not learning lessons, the struggles we face as a brand new field of human enterprise (not having hundreds of years to develop guilds and so forth like older enterprises like law or civil engineering have) with incredibly low barriers to entry and dramatically shifting changes in both scale and process in less than an average career's time.

On the other hand I understand the broad malaise about agile (in any of its 50+ forms (I like showing/horrifying people https://thedigitalprojectmanager.com/agile-methodologies/ and there's a fun youtube talk I've misplaced (ed: this one https://www.youtube.com/watch?v=abshdgwqz5Q))) and desire to point at any of the signatories of the original agile manifesto (Bob among them) or progenitors of Extreme Programming processes as having outsized influence in where we are today.

Perhaps Bob has in that way and other ways done more harm than good (I disagree). But if we're dealing with such suppositions, let me bring up another supposition I thought of when I asked myself "if I had to come up with names of industry harmers, who would even make the list that I don't think Bob would land on?" Suppose Bill Gates from the 90s to the 2000s did more harm than good (ultimately I disagree with this one too, though less readily). Whose harm was greater, Bill's or Bob's? If we assume both suppositions are true, I think it's no contest, and Gates' harm was orders of magnitude greater and is still more afflicting us in a myriad of ways despite him not being at the helm of MS for many years while Bob continues consulting, writing books, and making bad tweets. A more interesting contest to consider in this game where to me the relative goods and harms seem within a similar order of magnitude might be Bob vs Stroustrup vs Pike. Well, it's fun to lightly think about such suppositions, but I'm not sure anything useful can come from it. It's probably best left ignored, especially when there's no deep thinking going on.

I might have a different perspective if I ran into these groups of younger programmers who treat Bob's word as gospel and make a mess of things I had to clean up. Instead my experience is running into programmers (young and old) who instead don't have any theory or principles or rules of thumb, and inevitably create Big Balls of Mud (http://www.laputan.org/mud/). When I do attempt to clean up such balls, at least partially to form a little oasis, Bob's rules are helpful, as are others'. Getting shit under test (specifically unit test -- fast test, i.e. all that is championed by Feathers' Working Effectively with Legacy Code) helps. Breaking dependencies (often to get shit under test) helps. Refactoring big classes with seven arguments in the constructor into a handful of smaller classes with fewer-argument constructors or method calls usually helps (though beware of Ravioli). Thinking about SOLID principles helps. Rewriting without OOP sometimes helps. I look back and see a lot of helpful practices I picked up from somewhere not-Bob, yet many are advocated by Bob. I can't complain too much if he advocates a mixed bag of things I like and things I don't like, compared to if he was almost entirely wrong and there were clear harms.

To give an example of "things I don't like", or rather, misinterpretations of over-zealous youngsters, there's this idea that Bob says "Don't write comments." If I actually ran into a dogmatic team requesting I remove all my comments from my commit before it can get past review, I'd pull out Clean Code and have us go through an entire chapter (ch 4) that's all about Comments. Clearly, Bob is a bit more nuanced on this, given there's an entire chapter on his thoughts. The chapter does in fact cover some "whys" as well as "whats", including his primary "why" he's down on comments being that they often lie. Anyway within that chapter I'm sure I can easily find justification for some of my comments, and begin breaking whatever sense of dogma caused dumb things like "no comments" to take hold, with the eventual goal being to not waste time on such trivial things.

I don't really think there's all that much "dogmatic push" in Bob's book, even if supposedly there are tons of teams out there interpreting it so. But if they are interpreting it so, then like Bible Thumpers there's often something in the source material itself to move them toward seeing nuance (though nothing in Bob's works to my knowledge has anything like Revelation 22:18-19). There's even an out of context sentence in that chapter by Bob where he wrote: "Some comments are necessary or beneficial." Whaaa, I thought he said no comments ever? (By the way it's not like the idea of "No comments" is clearly attributable to Bob -- you read a lot of old code that far predates him and find a concerning lack of comments. Having a no comment style comes as much from laziness as any principled avoidance of comments -- and at least when it's driven by principle like in Bob's case it's mainly "make the comments redundant to the code by changing the code, then remove them", so the consequences of not many comments are less because at least the code was changed to better support that lack. At least, if it was done to the real principle, and not to some dogmatic perversion like "linter says no comments allowed, because Bob, take them out!")

I dislike that the 'philosophy of comments' or style of commenting seemed to Bob to be important enough to deserve a whole chapter. Comments often lie -- so what? That's not a big challenge. To me the whole topic is just not that important -- which is to say that I'm not too miffed by extremes in either direction of over-commenting things or under-commenting things. My goal after getting a dogmatic team on this issue to see nuance would be to then have them not care so much about it in general and spend time elsewhere.

I disagree with your characterization that he "targets", like a predator, younger, less experienced, developers. His books and consulting fees are for all. But whatever. I too have issues myself with commonly recommended books like Pragmatic Programmer or GoF. Most recommended books seem to be recommended to younger devs because they're often the only ones asking for any recommendations, too many older devs have given up on the idea of learning and are content with their balls of mud, or in better cases actively seek out books and don't need recommendations as much. But it's hard to sustain a book club at the office (or anywhere). The solution, if Clean Code specifically is a blight on younger devs, is to recommend more books, look for better reading orderings if possible, and stay firm in the assertion that no single book will be sufficient. My preferred "read this first if possible" would be The Practice of Programming; it's not at all useless to read after a few others but it's less helpful the more experienced (in a real N years way, not "same year N times" way) you are. At least it's short.

> dogma is not a substitute for understanding

I 100% agree. I also think neither Bob nor Linus (I certainly don't) nor the Ghost of Dijkstra nor many other famous programmers would disagree that there are times and excuses for deep nesting in a function, there are times for very long functions, there are times for very deep call chains, there are times goto is needed, there are times to write code instead of the platonic ideal of solving problems with no (new) code, ... and generally speaking when programmers make broad proclamations they're very often in actuality just rules of thumb with room for disagreement, nuance, preconditions, tradeoffs, and outright exceptions. It would be much easier for me to jump on Clean Code if it was actually just a slideshow of such proclamations presented bullet point style, but no, it's a book, and deserves nuanced critique suitable for such a medium.


The article itself addresses this in detail at the very beginning. Quoting it a bit:

"This statement makes no sense in Haskell (or lambda calculus) since all functions take one argument, and functions with zero arguments are illegal. Does that mean that the ideal function can not exist in Haskell?

No, this is an unfair judgment. Uncle Bob wrote this book with an OOP (Object-Oriented Programming) perspective with examples in Java. The point is that many arguments can be hard to use, understand, and can be a smell of too many dependencies. "


You're going to judge a book and the man by a context-free quote? That's kind of stupid, you know that right?


A simple “no” would have sufficed.


Even if you do not agree with the coding style they propose, it is still useful to know and helps understand others code (and the rationale behind it). It is true though not everything applies nicely.


What kind of habits do they advocate that interfere with writing good code?

I would love to hear more about this opinion.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: