Live data from Hacker News

My takeaways from "Clean Code"

medium.com

21–30 of 60 posts

Re: My takeaways from "Clean Code"

#21

> Zero or one argument is easiest to understand and maintain. > Have No Side Effects Can someone explain how you use zero argument functions that doesn't have side effects? I am trying to wrap my head around these two statements.

Having no side effects doesn't mean it can't do something. Only that it shouldn't do anything unexpected.

    storeItem.makeAvailable();
That should only make the store item available. It shouldn't re-enable a sale that was on the storeItem when it was made unavailable.

Re: My takeaways from "Clean Code"

#22
Don’t Pass Null? This is idiotic if you want performant code and don't want to have to use static empty object constants littered throughout your code.

Null is perfectly fine in place of an object. The author mentions this saves you debugging time. No, it will cause you pain later because you won't see errors that should happen. Instead they are masked by operating on some dummy object that you don't give a rats ass about.

Re: My takeaways from "Clean Code"

#23
post #3

Nice article! But I have to disagree with these: - Minimize the number of arguments - Avoid output arguments Basically, you're arguing against some principles of functional programming, advocating the use of state . There's no good or wrong with state, I think, there's only a trade-off. Heavy use of state = easier/faster to code, harder to debug/read. IMHO these kinds of generalizations are pretty dangerous. We shoul…

Basically, you're arguing against some principles of functional programming, advocating the use of state. Is that true? "Minimize the number of arguments" nudges you towards datatypes or maps instead of lists of implicitly related variables. No state there, just keeping functions relatively simple in terms of their inputs. In the latter case, "avoid output arguments" is absolutely a principle of functional programmin…

No state there, just keeping functions relatively simple in terms of their inputs.

Yes, yes! I definitely agree but what I meant is "principles of functional programming outside functional languages". When you understand the trade-offs that these principles bring to the table, you can apply them in OO languages -- in some cases. But here he's banning it for good with that statement!

Re: My takeaways from "Clean Code"

#24
post #3

Nice article! But I have to disagree with these: - Minimize the number of arguments - Avoid output arguments Basically, you're arguing against some principles of functional programming, advocating the use of state . There's no good or wrong with state, I think, there's only a trade-off. Heavy use of state = easier/faster to code, harder to debug/read. IMHO these kinds of generalizations are pretty dangerous. We shoul…

This won’t win me any friends, but I personally think that Clean Code is one of the most dangerous programming books to be released in the last decade. There’s a lot of good advice in the book, but it is written by and for Java programmers, and it comes with its share of risks if you take its advice. If you’re developing in a dynamically typed OO language like Ruby, it’s almost always bad advice to follow Clean Code…

> If you follow Martin’s advice enough, you will end up with lots of very short methods on lots of very small objects—and have a hard time understanding just how your program fits together.

I have never found this to be the case. Quite the contrary, in fact. Far too many objects that do way to much, or functions that do X and Y.

Indeed, I'm puzzled by your statement:

> Yes, it’s good to have short, readable, meaningful methods. Reducing method size too much...

Which directly contracts this:

> If you follow Martin’s advice

I guess the key word is 'enough', which is really just bad wording. "If you don't follow Martin's advice" is better. The qualifier here is you don't make short methods for the sake of having short methods. You make methods as short as they need to be to do that thing they promise to do.

So then we come to it: either you support having your methods do more than they should, doing more than one thing and having side effects, or you support Martin's suggestions. And yes, it really is that black and white. Sure, you could suggest that following his advice "enough" leads you to nothing but one line methods, but that would be silly.

Re: My takeaways from "Clean Code"

#25

> Zero or one argument is easiest to understand and maintain. > Have No Side Effects Can someone explain how you use zero argument functions that doesn't have side effects? I am trying to wrap my head around these two statements.

1. They're not orthogonal rules. 2. Some functions are queries that don't require an arguments. Eg. getVariable().

I just find that minimizing parameters makes a mess with tons of side effects. When I see nothing but 0 and 1 parameter functions, the code is typically doing the logical equivalent of refactoring `add(a,b);` into `push(a);push(b);add();` which makes a mess when there is more than the trivial case.

jQuery.ajax is a 33 parameter function. No one complains, and it is nice that it doesn't have side effects.

Re: My takeaways from "Clean Code"

#26

Earlier quoted context omitted.

1. They're not orthogonal rules. 2. Some functions are queries that don't require an arguments. Eg. getVariable().

I just find that minimizing parameters makes a mess with tons of side effects. When I see nothing but 0 and 1 parameter functions, the code is typically doing the logical equivalent of refactoring `add(a,b);` into `push(a);push(b);add();` which makes a mess when there is more than the trivial case. jQuery.ajax is a 33 parameter function. No one complains, and it is nice that it doesn't have side effects.

Sure. Usually when you find a strict rule, it's a rule to be considered ceteris paribus -- when all other things are fixed in place. So while thinking about parameters, I think about minimising them and ignore other considerations. When thinking about side-effects, I think about minimising them and ignore other considerations.

It's when the rules conflict that mere rule-following ends and professional judgement begins.

Basically, as noted legal scholar Captain Barbossa observed, they're less like laws and more like guidelines.

Re: My takeaways from "Clean Code"

#27

Earlier quoted context omitted.

It’s horrendous advice for Ruby. As I said in a different comment, this book wouldn’t annoy me if it had been called Clean Code . There’s a Ruby shop in Toronto that I interviewed with a couple of years back. As soon as I learned that they considered Clean Code a good book to be learned from, I knew that I didn’t want anything to do with their software development process (and I write very good, clean, and readable s…

As someone who is just diving into Ruby, I'm curious what specifically you think is bad advice for Ruby?

I’m going to have to go from memory here—I borrowed someone’s copy to read a few years ago, realized that it was not a very good book, and didn’t bother buying a copy for myself (and I’m not going to “borrow” an electronic copy, either). If I don’t have some of the specifics correct, please forgive me.

One of the things that stands out in my mind is a few related pieces of advice, most of which are fairly good in isolation:

- prefer composition to inheritance

- prefer more smaller methods (as I said elsewhere, I believe that there’s even a point where it’s suggested that a one-line method is “ideal”)

- prefer smaller objects

In isolation, each of these things is fairly good—but when combined, you change from a codebase of large, unreadable functions, to an unreadable codebase of lots of little, tightly-coupled, smaller objects with smaller methods all composed into doing something that would be simpler to understand as a few medium-size objects and medium-size methods.

In Ruby, all of this is…fungible is the best word I can think of for this. Because of Ruby’s duck-typing, mixins, and most importantly, lambdas and blocks, the best place for your logic to reside is as close as possible to where it’s being used. This doesn’t mean write large methods—it means that all of the advice that’s given for Java written before late 2008 (when lambdas were barely a twinkle in the JSR process and Sun still mattered) doesn’t apply when you have anonymous blocks of code that you can apply immediately and functionally.

The best description I’ve got for this ultimately is related to many of the things said about Gamma, et al.’s Design Patterns: in other languages, design patterns are just features that the language gives you, rather than something you have to implement. Iterators? Built into Ruby, and better because of blocks. In Ruby, you don’t need to learn the lessons given to Java programmers in 2008, because the language gives you more power and expressiveness already. Add a little bit of metaprogramming (in the same way that attr_reader/attr_writer/attr_accessor is implemented, for example) and you’ve got programs that express your intent clearly, but are nearly impossible to apply Clean Code to because you’re doing something smarter (not clever, but smart).

To address the three points that I mentioned a couple of paragraphs ago:

- prefer composition to inheritance: good advice, but composition in Ruby also means considering how blocks and mixins can help you understand your code better.

- prefer more smaller methods: I’m not as sold on this; the more methods you have, even if they’re private, the harder it is to understand just how your code works because you now have a larger API to understand. (And, like someone else in this conversation, I’ve had to deal with 2+kloc functions in other languages; I just haven’t had that happen in Ruby, where the largest functions that I’ve dealt with are in the low hundreds—and those are very rare but focussed functions (e.g., a lot of error handling where you don’t necessarily want to introduce state that lives outside of the function).

- prefer smaller objects: As with smaller methods, I’m not as sold on this. The more objects you have, the more interface you have to remember, the harder it is to remember how to compose everything back into the logic you’re trying to implement.

By all means, extract code—DHH’s advice on what they’re calling “concerns” in Rails is very good (I’ve already done that with more than a small bit of our current Rails application; I’ve also done it with other code over time).

Re: My takeaways from "Clean Code"

#28
I haven't read "Clean Code", but I grokked through a bunch of Uncle Bob's stuff in creating Obvious Architecture and I have to say that I think that many programmers don't/won't get what Uncle Bob is going on about because many programmers want to take the parts they agree with and throw away the rest in the name of "pragmatism".

In reality, Uncle Bob's stuff is actually better when taken holistically and when applied together, but it's hard to do and when taken to their logical conclusion, it is so outside the norms of OOP, that people freak out about it not being "proper OOP" as they were taught in university and in mainstream things.

Re: My takeaways from "Clean Code"

#30

Earlier quoted context omitted.

This won’t win me any friends, but I personally think that Clean Code is one of the most dangerous programming books to be released in the last decade. There’s a lot of good advice in the book, but it is written by and for Java programmers, and it comes with its share of risks if you take its advice. If you’re developing in a dynamically typed OO language like Ruby, it’s almost always bad advice to follow Clean Code…

> If you follow Martin’s advice enough, you will end up with lots of very short methods on lots of very small objects—and have a hard time understanding just how your program fits together. I have never found this to be the case. Quite the contrary, in fact. Far too many objects that do way to much, or functions that do X and Y. Indeed, I'm puzzled by your statement: > Yes, it’s good to have short, readable, meaningf…

No, it isn’t that black and white. Many of Martin’s suggestions are silly, especially when applied to languages that are more expressive (like Ruby, CoffeeScript) or otherwise have no relationship to Java.

I distinctly remember arguments with people who were reading Clean Code at the time who really believed that one-line methods really were the ideal.

The trick is knowing what does “doing more than they should” actually mean? If you follow Clean Code as I’ve seen some people follow it (including the Ruby dev shop I mentioned elsecomment), you will end up having substantially larger interfaces at the cost of understanding just what it is that your program is supposed to do in the first place.

I’ve dealt with programs written the Clean Code way (an explosion of methods, classes, and objects), as well as programs written with too much going on in one place (e.g., 2+kloc functions). Neither is fun to deal with, but it’s generally easier to assimilate the basic business purpose of the 2+kloc function than something that has a larger interface surface than it needs to have.

Post reply on HN