9 ms·
I am wary of designs that make code significantly longer, as both these examples do. The improvement in local readability is often superficial and the cost in o
by gruseom 13y ago
I am wary of designs that make code significantly longer, as both these examples do. The improvement in local readability is often superficial and the cost in overall readability (not to mention bugs, which increase with code size) is often nontrivial.
In the examples, each line of code with a named function appears more readable, but this is only because its meaning has become less dense—and as there is also now more code to read, the two factors arguably cancel each other out. Meanwhile the new code has more non-locality: the eye of the reader must jump between the various function invocations and declarations. That's a lot of jumping, and it will get much worse as complexity grows.
Introducing a name has costs as well as benefits. For example, it adds indirection: the name now stands between the reader and the thing that is named. To overcome this, a name should say something about the problem the code is solving. If all it says is something about the code itself, that's not good—it adds weight and obscures the problem (because you're now taking more code to solve it). It feels like you're simplifying code by factoring it in this way, but you may only be spreading it out more, making pieces which are logically bound together further apart from each other.
A sign that this is happening is when you can't think of a good name for the code you are factoring, or when the name refers only to the code itself. "wtfFriendAction" is a comical example, but I think "gotFriends" is more instructive: it tells you nothing more than "I am the callback for getFriends", and thus adds no information to the original code, only verbosity.
- jay_kyburz 13y agoI don't think naming your functions has to make the code "significantly longer". Perhaps 2 lines per callback. And yes it can be hard to name functions, and I think the OP has not created very good example, but a good name that accurately describes what the function does means I don't have to read it if I don't want to. A better example would have been some node.js code that has 5 levels of nesting, each with a some significant code within. You've just got to name them.
- gruseom 13y agoThe examples are 40% and 20% longer. That is significant. The trouble with small examples is that their problems don't seem like a big deal because their entire codebase isn't a big deal. You have to apply them many times over to get any sense of their compounding effect, which is what really matters. But by definition, that's out of scope of a discussion whose examples are small. The only way out of this paradox is to pay close attention to apparently small effects.
- mattmanser 13y agoOne of the things that really annoys me about modern JavaScript programmers is that they seem to have forgotten the basics. Functions are good. Short methods are good. Reusability is good. Properly naming your functions is good. Separation of concerns is good. Complaining about a couple of extra carriage returns and a few extra characters to properly name the method is insanity.
- andreypopp 13y agoThe problem with callbacks is they are not about reusability — they force you to organise your code around I/O and not around your app logic... hence the names like wtfFriendAction.
- Skinney 13y agoThere is a difference between callbacks and lambdas. Nothing forces you to provide a lambda as a callback. If that lambda will only ever be used once, then it's ok as long as it's short and easy to understand what it does. If that function is required multiple places, you make a proper function out of it, and pass that function instead of a lambda. Callbacks allow for abstractions like map, filter, reduce... Used properly, they can actually increase reusability instead of prohibiting it.
- andreypopp 13y agoIt's like you didn't read my comment — how functions like wtfFriendAction help reusability?
- Skinney 13y agoIn this small example it doesn't, getFriendsById however, does. I would imagine that wtfFriendAction could be used multiple places though. wtfFriendAction is additionally a very, very poor name. It should be called "addFriendToFriendList" or something. Another thing is that the author himself states that the function doesn't actually makes sence, hence the ugly name.
- ufo 13y agoIMO, the biggest problem is the extra indirection, not the raw lines of code. As for names, the problem is that he is forced to make a new callback whenever he does an IO operation and then needs to make up a name for it on the spot. Ideally you should never be forced to split code into functions unless you actually want to do so and when you can choose where to create functions its much easier to create good abstractions and good names.