Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> In this case I hope nobody is proposing a single 1000-line god function. Nor is a maximum of 5 lines per function going to read well.

This is the key. Novice devs tend to write giant functions. Zealot devs who read books like Clean Code for the first time tend to split things to a million functions, each one a few lines long (pretty sure the book itself says no more than 5 lines for each function). I worked with a guy who extracted each and every boolean condition to a function because "it's easier to read", while never writing any comments because "comments are bad" (according to the book). I hate that book, it creates these zealots that mindlessly follow its bad advices.



Or, the fun one I run into is devs who write a mix of 1000 line functions and tiny little 5 line functions with no discernible pattern to which option is chosen when.

The truth is that what makes code readable is not really (directly!) about function size in the first place. It's about human perceptual processing and human working memory. Readable code is easily skimmable, and should strive to break the code up into well-defined contexts that allow the programmer to only have to carry a handful of pieces of information in their head at any given moment. Sometimes the best way to do that is a long, linear function. Sometimes it's a mess of small functions. Sometimes it's classes. Which option you choose ultimately needs to be responsive to the natural structure of the domain logic you're implementing.

And, frankly, I think that both versions do a pretty poor job of that, because, forget the style, the substance is a mess. They're both haphzardly newing up objects and mutating shit all over the place. This code reads to me like the end product of about four sprints' worth of rushing the code so you can get the ticket closed just in time for sprint review.

I mean, let's just think about this as if we were describing how things work in a real kitchen, since I think that's pretty much what the example is asking us to do, anyway: on what planet does a pizzeria create a new, disposable oven for every single pizza? What the heck does

  pizza.Ready = box.Close()
even mean? Now we've got a box containing a pizza that's storing information about the state of the object that contains it, for some reason? Demeter is off in a corner crying somewhere. What on earth is going on with that 'if order.kind == "Veg"' business, why aren't we just listing the ingredients on the order and then iterating over that list adding the items to the pizza? The logic for figuring out which ingredients go on the pizza never belonged in this routine in the first place; it's ready aim fire not ready fire aim. etc.


This is in the article (seems to have been edited after your comment):

>I wasn’t sure if I wanted to mention this or not, but I ended up editing the post because there is something that bothers me with this function, and it is that business with the oven.

>[...]

>this code makes no sense: why would you create a whole new oven to make a pizza? In real life, you get an oven once, and then you bake a whole lot of pizzas with it, without going through the whole heating cycle.


The problem with any good idea: As soon as it becomes dogma, it doesn't matter how good the original idea was, it will turn itself bad.


And programmers are way worse than people in general when it comes to being dogmatic.


I think this is an experience thing. There are a lot of inexperienced developers, and inexperienced developers tend to become very attached to development philosophies, and attribute all problems to the lack of adherence of their pet philosophies.

This tends to wear off with exposure to the real world. Not only will you find undeniably good code that's written in flagrant disregard to the holiest of doctrines, you'll also find garbage written The Proper Way, more damning still sometimes you'll discover it was written by your own hands.

I don't think it's a coincidence many of the ideas that have the most fervent and zealous followers have names that sound righteous, if it isn't clean code it's pure functions or more recently memory safety. Clearly nobody who is on the "side" of dirty, impure and unsafe code can be right?


> I think this is an experience thing.

Ahhhhh...yes, but...

There are two kinds of people when it comes to dogma: The faithful, and the preachers. The inexperienced developers are the faithful. They cling to the scripture without proof that it is actually necessary.

Insofar, I agree with your post.

But the faithful need someone to preach the faith, and those are usually not the inexperienced ones. Those are usually experienced developers. Their personal reasons to cling to the dogma are varied: Some may have started as faithful themselves, for some it's stubbornness, an unwillingness to change, maintaining a feeling of superiority, the fear of becoming obsolete, ...

So here we are in disagreement. The preacher is the product of experience and development over time. And in my book, the preachers of dogmas are more of a problem than the faithful who follow them. Because it's the preachers who write the scripture, the preachers who make up arguments why alternatives to the ideology are bad, and the preachers who seek to isolate their flock from the "evil" preditions of alternatives.

> I don't think it's a coincidence many of the ideas that have the most fervent and zealous followers have names that sound righteous, if it isn't clean code it's pure functions or more recently memory safety.

Closing my answer on another point of agreement, it is absolutely not a coincidence, that the wording of dogmas in programming sound eerily similar to that in religious teachings ;-)


Well said. Following a set of rules is no substitute for experience, despite any pressure to do so.

Since every situation is unique, even if similar to others, I think it's always best that programmers rely on their judgement and experience when writing code instead of a set of axioms.

And besides, blindly embracing a set of rules is acting more like a robot, instead of a human being.


"Agile" is another of those words, used to whitewash stiff, heavy and dogmatic dev processes.


I prefer to read this in such a way that implies that programmers are not people. :p

I jokingly refer to our customers/users as "humans" at work.


Hard not to become dogmatic when your living depends on getting every comma exactly right and you're getting instant impartial feedback every time you get something not quite right :)


I disagree. Programming allows for so much freedom and flexibility in how you approach problems. I find that a large portion of the job is following your gut feeling and putting it into words.


I don't understand this widespread sentiment at all. If the dogma-idea is right, it's right. No matter how dogmatic the people who are defending it are.


Most of these ideas are tradeoffs. If a particular tradeoff is the right thing to do 80% of the time, then it is clearly a good idea. But if you understand it as dogma, you'll do the wrong thing 20% of the time.

Take the pizza example. Which is better, linear code or small functions? It's a series of tradeoffs. Once you get above a screen of code, or 10 ifs, functions become hard to read. Once the same logic has been written 3x, abstracting it is usually a win. Even if it is small. And there is a fuzzy area where it isn't obvious which is better, and debating it is probably a loss over writing it and moving on. Doubly so if you're defaulting to the same kind of decisions every time and so the style is consistent.

In a world full of pragmatic tradeoffs, dogmatism is rarely the right choice. (Unless you haven't learned the tradeoffs.)


My pithy description of software development is "a series of decisions in pursuit of a goal".

dogma invites people to stop using their critical thinking skills.

One of my favorite examples of this:

Everyone would agree that having a newborn in a car means safety is paramount. Everyone also agrees that left turns are less safe than right turns. No one would agree that this implies you should never make left turns in a vehicle with a newborn.

^But the above is how both security people and TDD proponents tend to act, as if there can be no risk assessment and critical thinking involved. We've all made right hand turns when we really wanted to go left because there was just too much traffic, even without a newborn in the vehicle.


I was thinking about no-tradeoff truths. But you’re right on those tradeoff situations.


There are very few ideas that are absolutely right. I don’t consider “facts” as ideas, although these days even the facts have alternatives too.


It doesn't matter how good the underlying idea is, a dogma is always bad.

Because ideas are highly unlikely to be universally correct, no matter how good they are. Even if an idea is supported by all available evidence, it MUST subject itself to scrutiny and possible falsification, all the time.

A dogma flies in the face of that. It is, by definition "any belief held unquestioningly and with undefended certainty" (quote from wikipedia). Once people follow an idea dogmatically, they are very likely to apply that idea no matter if it makes sense or not. They stop following logic and start following scripture.

It is bad enough if this happens in science, where we really do have systems so far supported by all available evidence. But it becomes a lot worse in areas like software development, where we know there isn't "the one" true way of doing things.

And to head off one likely reply to this: Yes, I apply this logic also to the assumption that "dogmas are always bad". If someone could present proof showcasing a dogma that only has good outcomes, with no negatives attached, then I am willing to change my mind on this.


just because people interpret a fact incorrectly doesn’t mean the fact stops being a fact, lol wth is this sub


What's a sub?


They're likely a reddit refugee referring to this site as a subreddit.


Oh man it's easy to spot someone who blindly follows Clean Code. I personally don't like it, but I am I fan of all of Martin's other books. It's just aggressively opinionated in a way that I just can't get behind. I'm sure I'm not alone but reading that book made me feel insane since he described things as objectively good that I found awful.


I don't know if it's because of clean code or because he calls himself my uncle or what else, but he's always rubbed me the wrong way.

I always ask people to think about printed pages and they look at me as if I'm crazy... But it's like, if you have to pick up a reference book or something, carefully find the right section addressing your problem, you want to read it, how many pages do you want to read at a sitting? For most the answer is ideally 1 but you can read 2-3 and still not get annoyed, right? If it gets longer than 10 then that's doable but not what you signed up for. Well if I print code onto those pages, and just assume that most of English lines are kind of filler which programming languages don't have, so no compression due to the sparseness of code, then you get ~40 LOC on a textbook page, ideally you would solve a problem in 40 LOC but if it took 120 LOC that is still perfectly readable, it's when it gets to 400+ish that something has really started to get confusing about the structure.

Same with diffs, 400-line diff is still reviewable, but barely.

The printed page isn't the point, the point is that these are kind of objective numbers, if I describe them in printed pages everybody seems to agree on these numbers... But then a book like Clean Code comes around, people want to have these tiny little scraps of an eighth of a page, bound together in a little flip book of half-index-card strips each pointing at other strips, “bake the pizza (see strip 37)”, and nobody thinks about whether this is actually an informational presentation mode that anybody really wants to use. “It works better for review time because you encourage only reviewing one or two pages of flip book at a time.” Yeah Bob I see what you're saying but, like, is this my “crazy uncle” now who insists that the usual book is going away because with the advent of Wikipedia and infinite content feeds all knowledge and story will forever be stored in such flipbooks? Just because editors who don't care about the overall story anymore because their attention span are shot to hell find it easier to review half an index card at a time? This is a good thing? Something feels off!

You get this same argument from people who believe in the layered server architecture. “Business logic needs to go in the business layer, database logic in the data access layer, presentation logic in the view layer, routing logic in the controller layer.” but you would never voluntarily read a book that was structured this way! “Matt saw Alice sitting there, a young girl of maybe 16, gorgeous in her melancholy and disaffected way, an old schoolmate of his. He waved. She beckoned. He said “Hi, how are you?” and she replied...” Right, the author gave you a data structure of adjectives to associate with Alice, you didn't have to flip to the Characters section looking for “ALICE_INTRODUCTION” and wade through all of the different ways she appears in the book to find “when Matt first sees her she is melancholy and gorgeous” and then flip all the way back to the story that you were reading, then flip to the Dialogue section looking for MATT_ALICE_INTRO_DIALOGUE, hope you left a bookmark back in the Main Story section back there! “Oh, but it is so easy to read the whole book if you can skim through the Main Plot part of the book without ever knowing anything about the characters or settings or repercussions or dialogue, “Matt saw Alice (ALICE_INTRO), she beckoned, they talked (MATT_ALICE_INTRO_DIALOGUE), he walked to the diner...”. And if you complain about the big all caps stuff someone says “well in a modern hypertext reader, those just become links and you never need to see them directly!” except you do because you have to maintain it... And it's like, I get it! You can probably compress most modern novels considerably if you remove all their descriptions and dialogue to appendices, it's not wrong! But writing is so much slower in that format, debugging is surprisingly so much slower in that format, the things that are faster are queries like “Did Alice ever mention her father to Matt in the recorded dialogue?” and then you make a refactoring change on the basis that Matt should not know anything about Alice's father and then it turns out that it generated a plot hole because somewhere in the Exposition layer the two were connected more obliquely, Alice wrote about it in a post-it on the fridge or something, that she was going to see her father who was ill.


The point of abstraction layers is more about responsibilities (and the abstractions).

For example, the DAL shouldn't know that a missing record is going to return a 404, instead it needs to be able to express record not found in it's API. The business layer should also not know that a record not found is going to return a 404. Instead the business layer needs to be able to express that a record was not found. The web layer needs to know that when a record not found is expressed, we return a 404.

This is why I'm not a fan of ORM's without a DAL. Too many people will sprinkle the ORM code directly into a controller and call it a day, and then ORM's will come up with all of these unmaintainable ways to "re-use" queries and all the nasty performance knobs that come with that.

And I'm not saying the gap between the layers needs to be that thick. If a DAL wants to hand back ORM models directly, more power to them, just disconnect them from the DB before you do. If the web layer wants to use those same models as the api contract, more power to them, that can always be fixed when and if they diverge.

And it's not as if these layers themselves must be proper layers, that's what I meant when I said responsibilities. The web layer is responsible for web concerns (security, api contracts, etc). If you want to treat the controller as an orchestration mechanism that you get from 15 different Dependency Injected services, great. It doesn't need to be a physical layer, but it should be a logical layer and the layers below being able to express everything the layer(s) above need to know is an important part of that sort of design.


I was this dev early in my career. A sharp overreaction to a giant ball of mud architecture with no tests and minimal consistency. I read all those books looking for some better way and inflicted all those rules on people.

I don't regret the learning, but I do regret being dogmatic. It was interesting that no one around me knew better either way, or felt they could provide reasonable mentorship, so we went too far with it. These days I write the pizza function on the left, and use comments sparingly where they add context and reasoning.


I just inherited a code base written by somebody in that exact same situation. Saving a single file associated with a model in 27 steps instead of about 4.


Clean Code says "Functions should not be 100 lines long. Functions should hardly ever be 20 lines long".

I think both 100 and 20 are a bit low, but much better than 5. As I mentioned in a comment a few days ago when I also corrected someone that misremembered a detail from the book, I am not a huge fan. But I also think it is mostly correct about most things, and not as terribly bad as some say. Listening to fans of the book is more annoying than to actually read the book.

(And that other comment when I corrected someone was about bad comments. Clean Code definitely does not say that you shall never comment anything.)


I went back to check and this is what the book says, verbatim:

"Every function in this program was just two, or three, or four lines long. Each was transparently obvious. Each told a story. And each led you to the next in a compelling order. That’s how short your functions should be!"

So I think it's fair to say the book advocates for functions 2-4 lines long.

And about comments, from the book:

"So when you find yourself in a position where you need to write a comment, think it through and see whether there isn’t some way to turn the tables and express yourself in code. Every time you express yourself in code, you should pat yourself on the back. Every time you write a comment, you should grimace and feel the failure of your ability of expression"

"Some comments are necessary or beneficial. We’ll look at a few that I consider worthy of the bits they consume. Keep in mind, however, that the only truly good comment is the comment you found a way not to write."

With opinionated sentences like these, it's not hard to see how one would read the book and adopt a "no comment" mindset.


It also completely misses the point of why comments are useful.

"Store user.age in age variable", is a useless comment which is indeed better expressed with clear code.

"Store user age in struct because when xyz() iterates over this it has no way to access the user object" is useful because it tells us why something is done, where it is used, and why the obvious solution isn't right.


I fought and lost this battle with one of our teams.

The tech lead insisted they use XML comments (Visual Studio) for everything.

///<Summary> ///Represents the User ///</Summary> public class User { ///<Summary> ///Users Age //</Summary> public int Age {get;set;}

  ///<Summary>
  ///Users First Name
  //</Summary>
  public string FirstName {get;set;}
}

ad nauseum.

Here's the thing. Swagger (.net) can pick up the XML file generated from these comments and it gives developers the ability to add more information to the Open API Spec file (swagger generates a UI off of it).

So it has a legitimate use, but if you don't have anything than to repeat what the damned code already says, it's harmful to the readability of the codebase.


A classic criticism of CC: https://qntm.org/clean


I love qntm's writing, be it criticism a technical book or blowing my mind with science fiction. I strongly recommend "There Is No Antimemetics Division".


I think that no sensible rule of thumb is possible unless we're specifying a language, because language "density" can vary so greatly.

I follow wildly different rules of thumb about everything from line of code count to how many methods per class to whether or not that functionality belongs in a class in the first place, depending on whether I'm writing Java or Python or F# or Racket.


It's not from Clean Code, but Refactoring.


I think I completely agree with that line. 5 is a nice goal to aim for. Sometimes you hit 1, some things really do take 20. 100 lines is almost always a bad idea (unless it's a 100 really boring and obvious lines).

I haven't read the book, and I can see how people can go overboard and can turn good advice into a caricature of it, but short, well-named functions that focus on a single thing are generally better than long ones that do dozens of different things. Separate those concerns.


I literally just pushed a 101 line function to prod that is named "download_and_extract" that downloads some files from a place, extracts them, then has a lot of error checking and a couple of logging statements and hands off to a few smaller functions to move and re-arrange files. It is long but it is readable and doesn't really fit a more abstract way of doing things. But that's my style I guess.


Length of function is not even a metric, it is at worst a code smell.


> I worked with a guy who extracted each and every boolean condition to a function because "it's easier to read"

Obviously, readability is important, but I've also seen things like this so often in my career where it's used as an excuse for anything. Most recently, trying to stop a teammate turning nearly every class into a singleton for the sake of "simplicity" and "readability", which I thought was a real stretch.


> pretty sure the book itself says no more than 5 lines for each function

The book was written by a Java dev who was dipping his toe into Ruby.

Go code, covered everywhere in an obnoxious rash of error handling, will be bigger.


That's why I don't read books.




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

Search: