Live data from Hacker News

Small functions considered harmful

medium.com

61–70 of 121 posts

Re: Small functions considered harmful

#62
post #52
post #25

During my earlier years, I would get into all types of dogmatic debates, such as "DRY-considered-harmful" or "small-functions-considered-harmful" . With experience, I've realized that such abstract debates are generally pointless. Any principal can lead to bad results when taken to an extreme, or badly implemented. Thus leading to people declaring that-principal-considered-harmful , swinging the pendulum to the oppos…

Unfortunately, I've had the misfortune of working with horrendous programmers who write functions that are hundreds of lines long, duplicated all over the place, and are a pain to understand and maintain. As a maintanance programmer I had that misfortune very often. But I don't believe it's really so relevant to the article. Having short-functions and DRYness is indeed prone to abuse, but it still works as a general…

I think even most people who believe in short functions, would disagree with your boss. The following SO thread does a pretty good job summarizing the short-functions principle.

https://softwareengineering.stackexchange.com/questions/1334...

The whole point of a guideline is that it's not a rule. It's a heuristic that people can selectively apply, based on the specific context and their level of experience.

Re: Small functions considered harmful

#63
post #25

During my earlier years, I would get into all types of dogmatic debates, such as "DRY-considered-harmful" or "small-functions-considered-harmful" . With experience, I've realized that such abstract debates are generally pointless. Any principal can lead to bad results when taken to an extreme, or badly implemented. Thus leading to people declaring that-principal-considered-harmful , swinging the pendulum to the oppos…

This basically boils down to 'bad code is bad'. DRY and short-functions are supposed to be guidelines, not rules, and when you find yourself violating them, you're supposed to question why. Sometimes there's a good reason for it, often not, and it will help newbies get to the point where they can answer these questions themselves.

[deleted]

Re: Small functions considered harmful

#64
post #49
post #21

Earlier quoted context omitted.

> I have yet to see these dogmatic Clean Coders blindly applying Martin's advice. You're lucky. I've seen it plenty of time. In one extreme case we even had to let go a perfectly (formerly) competent dev after he read that book and went crazy (yeah, seriously).

I'd be interested to see what his code looked like and how the code reviews progressed before firing him. I think these discussions are important, however, we must ground them in a concrete reality. That's what I appreciated about Clean Code, it was grounded in addressing real live code. And the reader is able to choose whether they agree with the conclusions or not. With that said, all too often, like in this articl…

I don't know Go, but your example looks absolutely beautiful.

On the other hand, I'm one of those "smaller than that" people :) I mean, I am ashamed that I left the time-to-string function in [1] too long. It could definitely be split up (and I find value in that, I just haven't had time / a reason to revisit that code).

[1] https://github.com/mdpopescu/public/blob/master/SocialNetwor...

Re: Small functions considered harmful

#65
post #25

During my earlier years, I would get into all types of dogmatic debates, such as "DRY-considered-harmful" or "small-functions-considered-harmful" . With experience, I've realized that such abstract debates are generally pointless. Any principal can lead to bad results when taken to an extreme, or badly implemented. Thus leading to people declaring that-principal-considered-harmful , swinging the pendulum to the oppos…

Rules like DRY or keeping line counts low are based on surface metrics and definitely lead people to over-fit the model based on incomplete information.

Underlying principle of maintainable code is "simply" that it is a concise and flexible expression of knowledge. The "simply" part is in quotation marks because, of course, it takes a good amount of self-awareness and meta-consideration to understand why some ways to express knowledge are better than others. There is also a limit to how "perfect" it can get, because it really depends on the audience too.

This is also why it's OK to let it slide sometimes and move on to more interesting topics - there are diminishing returns on splitting hairs, once broad strokes of good encapsulation and basic readability are applied.

Re: Small functions considered harmful

#66
1. Functions which are "longer than they should be" decrease code quality.

2. Measuring the "number of lines per function" is extremely easy.

Code quality tools have a bad tendency to equate (1) and (2) for the same reason that the proverbial drunk searches for his keys under the streetlight. This has legitimately bad consequences.

This is further compounded by the way that small functions ease mock-based testing. While certainly attractive in the abstract, when a code base is overly influenced by this I find that it is substantially more difficult to understand via inspection.

All that said...I find the whole "X considered harmful" formulation almost unbelievably annoying. Here it doesn't even make any sense.

Re: Small functions considered harmful

#67
post #50

It seems like the author's idea of the term abstraction is limited to substituting procedures with functions (or worse, class methods). The claims that "all abstractions leak" and that adherence to DRY makes code "hard to follow" is what gives me this impression. This line of thinking happens if you think of code in procedural terms. And if your sense of abstraction is to hide procedural side-effects behind function…

Arguably lambda, monad, etc. are generalizations, not abstractions: http://www.emu.edu.tr/aelci/Courses/D-318/D-318-Files/plbook... Abstractions that don't leak aren't abstractions, as the essense of abstraction is the simplification and removal of detail. Monad is a generalization of a pattern seen in many places, so it doesn't have to "leak".

I kind of agree with you (I think), but I'd present (or think) about it differently to avoid terminological squabbling.

More specifically: I'm skeptical of the distinction that your referenced article attempts to introduce between generalizations and abstractions: that distinction feels after the fact, trying to retconn into existence some classification that just isn't that clearcut. Regardless of what's correct terminology here, emphasizing the distinction simply leads to semantic quibbling, not better programming practices. The criticism that "abstractions always leak" might apply equally to generalizations - or encapsulations. Whatever you're going to call it; the idea at some level is that you're never entirely free of implementation details.

To be clear: I agree the words may well have different connotations and even different meanings, but that does not imply that they are mutually exclusive: what's an abstraction from one angle may well be an encapsulation viewed from another, and a generalization in some other context. And perhaps some aspects of a given construct aren't relevant when you consider it to be an abstraction rather than a generalization; but I'm not sure it matters here.

Instead, I think it should be emphasized the there are two different ways of looking at the statement that "all abstractions leak":

- You can consider that any abstraction in an executing program is merely a way of thinking about something that's ultimately a real physical process; and that that physical process may well have relevant behavior that escapes the confines of your abstraction. For example, the abstraction that your mergesort is O(N log N) is in some sense leaky because more memory needs longer wires means slower access so it's false - in some sense.

- You can consider clearly self-consistent and completely rigorous mathematical concepts that might be used as abstractions as a kind of counterexample. Clearly, there are thus abstractions that do not leak. Mergesort is O(N log N) - not in physical time, but in # of operations. We sort of "define" the problem not to exist.

Frankly: I don't think the "physical process" view (while certainly valid!) holds much value beyond that of a cautionary tale. Rather than give up and say "it's impossible" the lesson should be that it's valuable to choose your goalposts. So, for instance: if you define a correct program that adds N numbers to be one that returns (say) the true sum in at most N milliseconds, you're going to run into trouble: you may not be able to guarantee you won't be swapped out; you may run into trouble if your numbers are absurdly large; and you can't rule out that asteroid impact that's about to destroy the computer. But you can carefully choose those goalposts such that if the program completes, and if (condition XYZ) then it returns the numerical sum.

Does that distinction seem pointless? I don't think so; because as it turns out in the real, physical process world this allows us to separate responsibilities. It's fairly easy to ensure a physical environment that will high likelihood (albeit not fully 100%) satisfy the requirements you pose. And by separating responsibilities like that, it becomes easier to avoid needlessly leaky abstractions, and those abound too. In short: you may not be able to make an abstractions that's reliably perfect, but you should be able to make abstractions that given certain preconditions are perfect. And that matters because it's easy to compose perfect abstractions, and it's not even hard to keep most of the complexity in the perfect and leak-free world.

In short: "all abstractions leak" is thoughtcrime that can all too easily hide lazily constructed, poorly chosen abstractions that don't compose well :-).

I prefer to think that it's inevitable that some abstractions leak, but if you're clever (and perhaps a little lucky) you can contain the leakiness such that other abstractions are leak-free. And if you want, call those latter abstractions: generalizations. But programming can choose to be almost all about those generalizations, not the leaky abstractions.

Re: Small functions considered harmful

#68
post #2

I find a lot to agree with here. It's all very conceptually neat and (if you're lucky) easy to read from the top down, where you enter one function and read off a list of other functions which are called in order. But then if you look into any of those other functions they also call more functions and so on, several levels deep. And when you have to debug someone else's code because the data after function 15 of 17 i…

I tend to agree, but not with your particular example; the boundry between how you manage a resource and what you do with it seems like the perfect place to put an abstraction. The file mingling can be in one big function, but there are benefits to separating it from the open/close logic.

Re: Small functions considered harmful

#69
post #25

During my earlier years, I would get into all types of dogmatic debates, such as "DRY-considered-harmful" or "small-functions-considered-harmful" . With experience, I've realized that such abstract debates are generally pointless. Any principal can lead to bad results when taken to an extreme, or badly implemented. Thus leading to people declaring that-principal-considered-harmful , swinging the pendulum to the oppos…

Rules like DRY or keeping line counts low are based on surface metrics and definitely lead people to over-fit the model based on incomplete information. Underlying principle of maintainable code is "simply" that it is a concise and flexible expression of knowledge. The "simply" part is in quotation marks because, of course, it takes a good amount of self-awareness and meta-consideration to understand why some ways to…

> Rules like DRY or keeping line counts low are based on surface metrics and definitely lead people to over-fit the model based on incomplete information.

The principles are actually sound, but letting metrics drive the design process is a problem all on its own.

https://en.wikipedia.org/wiki/Goodhart%27s_law

Re: Small functions considered harmful

#70
I think the author doesn't understand the small-function-philosophy (at least not the same way I do). Let me clarify how I see it:

- Build a ton of small functions that are reusable across any project. You are essentially making useful concepts. (i.e. a library). Bottom-up.

- Once you have those, a business problem often will only be about 3 or 4 of those powerful, reusable functions.

So something like sending out a newsletter might end up being:

function sendNewsletter(letter) { database.getAllUserRowsAsIterator().forEach((row) => { sendmail(x.address, letter); } }

Now if we want the whole newsletter not to fail if there's a single exception, we can make another reusable construct "count exceptions" that's a wrapper function that catches all exceptions and builds a hashmap.

If you want this to work in a larger project, this requires having reliably unit-tested code and doc-blocks so that other people can reuse your abstractions, and then having roughly comparable coding skill to you.

Post reply on HN