Hacker News new | ask | show | jobs
by waltertamboer 1156 days ago
"The problem, of course, is that few of us can agree on what "clean code" means, and how to get there. A rule like "methods should only do one thing" looks great on a T-shirt, but it's not so easy to apply in practice. What counts as "one thing"?

I don't agree with this statement at all. From my experience this is perfectly possible. Maybe I'm misunderstanding the statement... why would it be hard to write methods that only do one thing?

6 comments

Because it's an artificial constraint that makes code worse. You end up with a whole bunch of functions that have only a single call-site and half a dozen parameters that don't make much sense. If you can only understand what a function does by looking at the call site then the function is no longer a self-contained piece of functionality and it shouldn't exist.

When you write very simple code you can have short functions that do one thing. When you work on more complex projects some functions will just be 300 lines long and breaking them up will just make the code harder to understand and harder to work with.

Take sqlite for instance: https://github.com/smparkes/sqlite/blob/master/src/vdbeaux.c

You'll find plenty of cases where functions do multiple things in sequence and those functions are long-ish because of it, and some "clean code" type programmers would feel compelled to refactor the code and make it way worse.

"If you can only understand what a function does by looking at the call site then the function is no longer a self-contained piece of functionality"

Wow, this is a solid guideline. Alright perhaps "SOLID" isn't the best adjective to use, but it's great advice :)

I find this in line with John Ousterhout's "Philosophy of Software Design", where there's a guideline saying that modules (classes/functions/components/etc) should be deep and interfaces simple. Instead of dividing methods/classes due to their size in lines, you should be dividing where interfaces can be simpler. Because a complex interface imposes a lot of complexity in the consumers of the module.

His book was pretty good, and I very much agree about the importance of good interfaces. It's the essence of computing, because file formats, data types, and protocols are just interfaces by another name.
why would it be hard to write methods that only do one thing?

Two big problems with this approach. First of all reasonable people can disagree on what "one thing" actually means. Let's say you want to take a csv file of numbers and return a numeric array-of-arrays. How many 'things' is that, 1 or 4 (read, parse, validate, convert)?

Secondly it is many time both computationally more efficient and 'aesthetic' to do everything in one in-line sweep rather than:

  x=f(x)
  x=g(x)
  x=h(x)
  ...
While both approaches can be taken to extremes, I generally agree with what John Carmack wrote on the topic many years ago http://number-none.com/blow/blog/programming/2014/09/26/carm...
The point (which I don't 100% agree with, but can see) is that what it means to "only do one thing" is sometimes debatable.

Say I write a 1000-line method that implements a red-black tree data structure, including returning closures that allow you to search for, add, or remove nodes. I could claim that this method does precisely one thing: it implements a red-black tree.

Or, say I write a ten-line method that takes a list of names and returns the unique names ordered alphabetically. Someone could complain that the method does too much, because it both finds unique names and sorts them alphabetically.

Does the `main()` function in GCC only do one thing? It compiles a program, that's one thing right? Alright, have fun writing an entire compiler in one function.

Besides, Bob Martin even mentions this in his book "Clean Code". Page 35:

> The problem with this statement is that it's hard to know what "one thing" is...

He finally concludes that a function is only doing one thing if:

> you can extract another function from it with a name that's not merely a restatement of its implementation.

Which is just dumb. Let's call our function `compileCProgram()`, well according to the second heuristic this is only doing one thing. Anyways, if even the guy who wrote the book about clean code admits that it hard to figure out what one thing is, I'm inclined to say you may be slightly disingenuous here.

It seems like the author could be looking at your method at the statement level, for example. What does that if/else do? One thing or two? What does this say about the method?

But as I commented elsewhere, there's not a lot of attention to topical scope in the article either, so it also sets out to do the metaphorical "one thing", and then somehow merges with the broader philosophical world...

“One thing” can mean different things depending on the level of abstraction.

If you don’t understand that, I can understand how the rule could seem confusing