Hacker News new | ask | show | jobs
by johndfsgdgdfg 1556 days ago
I pretty much lost respect for him when he started advocating short methods.

From [1]:

> In my Ruby code, half of my methods are just one or two lines long. 93% are under 10.

Are there professional engineers out there who reads this tweet and thinks striving for one or two lines methods is a good idea? I really don't understand how does this person have so much fame or so much authority on architectures? What exactly are his accomplishments other than selling books and seminars? Can someone please explain how come Martin Fowler is so revered among developers?

[1] https://twitter.com/martinfowler/status/893100444507144192

4 comments

> Are there professional engineers out there who reads this tweet and thinks striving for one or two lines methods is a good idea?

Striving for the shortest possible methods (less than 10 lines is good) is a standard in Smalltalk. It's not a bad idea, at least, it's been shown to work over and over again over the last 50 years. Ruby takes a lot of inspiration from Smalltalk, although it lacks the biggest factor that made short methods work so well in Smalltalk: the interactive editing of the code as it runs.

Another example where a subroutine longer than a few lines is frowned upon is Forth. Also in that case, interactive editing is the main motivation, along with the fact that the amount of irrelevant bookkeeping grows linearly (or worse) with the subroutine length (unless you use local variables or the return stack, which are both hacks in Forth).

In any case, "professional engineers" who don't even know Smalltalk... No, I mean, the history and breadth of their field, probably should not be too judgemental about what works where, outside of their immediate expertise.

Have you read his books or just his tweets?

1-line methods is taking things to an extreme (though you can write a lot of logic into a single line in Ruby, so maybe it's not as crazy as it would be in C...) but I found the discussion in his refactoring book about reorganizing methods and naming things very illuminating.

It's an idea so simple it sounds stupid sometimes to try to explain to people, and yet, I never stop seeing new code that could be improved by something as simple as methods with accurate names.

E.g. I've seen a lot of stuff like:

```

// This does X

[some obtuse nasty inline regex or five-layers-deep nested object call or otherwise crazy individual line of code]

```

That maybe eventually gets detached from that comment line and now there's just some nasty line that nobody on the team understands anymore that can't as-is be easily tested in isolation from a bunch of other stuff.

A perfect opportunity for a one-line method, that can have a descriptive name and can have its own specific tests.

And yeah, again, that's the extreme case, but most codebases have tons of opportunities for 5-10 line methods being extracted with helpful names. If you find yourself writing a comment to describe a block of code, maybe make that comment your method name instead. And sometimes you try it, and realize "wow, it's hard to extract these methods without an insane amount of input params and return values for each bit" and maybe that's an important thing to realize about the code you're looking at anyway. ;)

> // This does X

> [some obtuse nasty inline regex or five-layers-deep nested object call or otherwise crazy individual line of code]

… which no longer does X

Through happenstance, my "first" specialization (subsequent experiences demote it to third place, as skills I discounted became more appreciated later in life) in the industry was performance analysis. Over time I came to understand the overlap between Knuths admonishments on optimization and "too clever by half" coding (ie, the large intersection between Knuth and Kernighan), and rather than abandoning it entirely I channeled that effort into finding more benign forms of optimization. There are code smells that are slow. There is slow code with higher cyclomatic complexity than a faster version. There is slow code that is less maintainable. These are not hard to find if you look for them.

The one that snuck up on me was sort of the corollary to Screechingly Obvious Code, and a cousin to Pandora's Box - which is, strictly speaking, and antipattern (except that in the end of the original story, Hope was left in the box).

If you have a function that is Obvious except for one small part, factor it out into its own function. The care comes in picking the incision points. The inputs and outputs to the new method need to be obvious (ie, don't factor out a function with side effects, that makes for spooky action at a distance), which may require some temporary data structures in order to iron out.

Going further, if you are considering a behavioral change that may not be obvious (performance optimization, error handling for very obscure cases) that has no prayer of being screechingly obvious, determine what lines will need to be changed, extract method on that code first, commit it, and only then make the change to the extracted code. Mikado method often comes into play here. Get used to revisionist commit history techniques.

What I've found through long observation is that people are more comfortable reverting such changes if they break when you are not there, which in turns make them more open to approving the change in the first place. "Will this bite me on the ass later?" is a pretty important consideration for most people. The commit history is very clean, and someone can revisit your decision years from now, when your user base and hardware are orders of magnitude bigger, when the runtime and hardware have very different timing ratios between different activities, and so on. And critically (for the optimization obsessed), compilers are very good at inlining leaf functions, which means the 'cost' of the context switch can be negligible in practice.

Also I don't know about anyone else but I've found that my attachment to such code is also fairly low. You are much more likely to get encouragement to 'go for it' when broaching the subject of undoing one of these changes, instead of a lecture about watching for regressions (I tend to "over-invest" in robustness, so deleting my code statistically represents a reversion to the mean wrt to code quality).

And perhaps more importantly to this conversation, they tend to tune out these leaf node methods when tracing code looking for bugs or trying to add new features, bugfixes. These structures don't nerdsnipe us, causing us to dump state on short term memory and have to start over. If I had a dollar for every time I said, "Aha! I found the place where we return null! Wait, why was I looking for that?" I could retire. This is, in my mind, the critical quality of Screechingly Obvious Code - in uses up a single slot of short term memory, facilitating code traversal.

Cargo cult programming at it's maximum expression.

M. Fowler, Uncle Bob, Kent Beck, GoF authors...

Any book or post by these people is always brought up as a must read. A must read to understand why you should *not follow cargo cults* and see with your own eyes how toxic and damaging these guys are to software engineering culture.

In one hand, I'd say these guys are absolutely revered among computer science students (their main target to sell their books) and developers who have been stuck in the OOP and design pattern rabbit hole for decades without evolving.

In the other hand, the criticism is more present that ever. It's ironic, because the criticism has even lead Uncle Bob to jump the wagon and start to sell Functional Programming in Clojure as a new super *secret formula* and *best practice for real engineers*.

I fully agree. If I see those names attached to a project I take it with an extremely healthy dose of scepticism (and usually run the other direction).

I'm somewhat glad I made it out the other side; as a babe in arms programmer I was fully taken in by these ideas. It's a great game of fun creating these overly complex, but ultimately arbitrary, sets of rules. They serve no real purpose other than creating and solving mental puzzles. There's a reason Software Architects don't (shouldn't) exist any more.

Any "musts" in Software Engineering that purport to be universal must be met with lots of skepticism.
I haven't written any ruby, but I've seen very short methods used in Erlang and it can be useful. If you write one or two line methods, they're mostly to help name a concept and make the place they're called look more sensible.

Organizing all those small functions can be a challenge, though. Which is why I don't tend to have functions quite that small. But a lot of 10ish line functions tends to work ok. But then, Erlang doesn't have loops, and I don't like anonymous functions (unless they're so short and simple I don't expect to find them in a stack trace), so that tends to make things short by necessity.