Hacker News new | ask | show | jobs
by khendron 1360 days ago
One of the advantages of functions is that a well-named function is self-documenting. If you can take a bunch of lines and wrap them in a function whose name summarizes exactly what it does, then you have improved readability in my opinion. In this example, I don't really need to know the details of how the query parameters are extracted. I just want to know I've got them.
3 comments

Emphasis on well-named. Naming things is hard.

Maybe not relevant in simple toy examples, but you don't have to look far until to find a function that isn't so easy to name.

Emphasis also on "bunch of lines".

Usually when I see one-line functions they cost more in short term memory than they save. There's good exceptions to this with something like a horrible conditional that is necessarily horrible so you can bust it out into a method with a doc comment about the horribleness, its history, and its subtle madness. But developers that just break out one-line methods all over the place wind up writing hard to understand code.

One-line functions are also nice when a comment would've been warranted otherwise. But yes, easy to go overboard with it.
its also a level of indirection... It's sad but functions often slow performance down. but this depends on the language.
Can't be many languages where that matters in 2022. Auto-inlining of short functions was a thing in the 1990s.
This may be true for compiled langs. In interpreted langs this is not the case. Function calls in Python for example are notoriously expensive.
Beat me to it. Yes, I ran a quick benchmark[0] and not running a function always wins. now, one may argue that you are running a call, but if the interpreter was smart it would convert the small function calls to just a noops.

[0]: https://github.com/Nomarian/crapbenchmarks/tree/main/call

  Summary
  'Perl/nofunc' ran
    1.63 ± 0.30 times faster than 'Perl/func'
    1.73 ± 0.34 times faster than 'Lua/nofunc'
    2.11 ± 0.55 times faster than 'Lua/func'
    9.37 ± 1.62 times faster than 'Python/nofunc'
   12.18 ± 1.90 times faster than 'TCL/nofunc'
   16.02 ± 2.58 times faster than 'TCL/func'
   18.64 ± 3.02 times faster than 'Python/func'
If you're hand-wringing about the performance impact of function calls, Python is probably the wrong choice anyway.
> Naming things is hard

Naming is hard unless you have a sensible concept hierarchy, and then naming is easy.

Concept hierarchies are hard, unless you have a sensible system model, and then concept hierarchies are easy.

System models are hard, unless you have domain expertise, and then system models are easy.

Not everything is a neat concept though.

Look at the Porter stemming algorithm for example. It simply does not decompose into something that is easy to put names on.

> A consonant will be denoted by c, a vowel by v. A list ccc... of length greater than 0 will be denoted by C, and a list vvv... of length greater than 0 will be denoted by V. Any word, or part of a word, therefore has one of the four forms: CVCV ... C CVCV ... V VCVC ... C VCVC ... V

Looks fine to me.

Domain expertise is hard.
Those functions get more annoying when debugging though. Because now you have to jump to the body of the function to see if it really does what it says. And you view the body out of context so it is harder to see if there is a wrong assumption between the callee and caller.

On the whole I think such functions are valuable. But they do have downsides.

Genuinely, they ate not annoying to me at all when debugging. I check whether function returned what I expected from its inputs and either look for bug there or move on.

I don't recall much jumping put and in.

Yeah, but these little 5 line functions with one caller whose only purpose is to avoid a 50 line function somewhere else are almost never named well. At best, I can infer about 20% of what is going on without stepping into all those little helpers.