6 ms·
>>On the flip side, I've seen people take this to the extreme.<< indeed, I have seen functions that contain only one line of code. Even if that is intended for
by mironathetin 13y ago
>>On the flip side, I've seen people take this to the extreme.<<
indeed, I have seen functions that contain only one line of code. Even if that is intended for reuse, it makes no sense, because the function call is one line too. Readability goes down the drain this way.
If a reader tries to understand a logic and thinking has to be interrupted by searches and trying to find the right code window, split-ups don't do good things.
Polymorphism, if applied wrong, is a notorious tool to hide the logic from the readers too. If the code decides at runtime, which implementation is used, comments become really important. Especially when this decision is made completely elsewhere in the code.
Think strategy pattern, for example.
The underlying problem is IMHO developers blindly following rules. This can be seen a lot. If you ask them 'why' and you get a textbook answer, be careful.
- chongli 13y agoDepends on the language. In Haskell function calls are extremely lightweight, syntactically speaking, and so it's actually quite common to write one line functions. A one-line function may consist of a composition of a dozen or more other functions and be given a short, one-word name. This makes perfect sense for reuse. Or it can be something as simple as this: odds = filter odd While that might not make sense if you only call odds once, you might end up calling it a dozen times! You may also want to limit the scope of this function definition by using a let or where clause. This can aid readability if it allows you to avoid repetition.
- NigelTufnel 13y agoI've tried to learn Haskell for a several times and the composition-heavy/flipping-so-currying-will-work/no-variables style always made the programs difficult for me to understand. Probably the classic case of Imperative-Guy-Struggling-To-Get-FP.
- aaronem 13y agoSpeaking as an "imperative guy" who's lately been learning Common Lisp, I tend to suspect the confusion you're encountering is not so much a property of the functional style in general, as of Haskell's style in particular. While I'm admittedly not best placed to comment on the matter, it seems to me that what Haskell offers is not so much greater power than a Lisp, as greater concision, as well as a language structure which doesn't allow for the sort of "escapes" into imperative behavior that a Lisp programmer can employ. In fact, now I think about it, I'd say that Lisp and Haskell are in this way roughly analogous to Perl and Java. I'm sure this claim will infuriate partisans of all four languages, so let me hasten to point out that the only sense in which I mean it is that Lisp and Perl allow the programmer considerable stylistic freedom ("TIMTOWTDI"), while Haskell and Java go to great lengths to enforce that style which their respective implementers consider the One True Way. Both these traits have benefits, of course, or one would've probably outcompeted the other by now; of particular note here, though, is that the One True Way style requires a lot more front-loading on the part of the developer than the TIMTOWTDI style does -- in the latter, you can more or less "fake it 'til you make it", while in the former, trying to "fake it" results in a nasty dressing down from the compiler, and you can't accomplish anything until you've become at least a neophyte, preferably a proper acolyte, of the One True Way. All of which is a very long-winded way of saying that if what you're interested in is not so much Haskell specifically as the functional style in general, you might be well advised to start with a Common Lisp or a Scheme, where you can study the functional style without needing first to understand any large and rather dry bodies of theory. Granted, you'll probably screw it up a lot right at the start, at least if my own experience is any indication. But Haskell's a big elephant to swallow all at once, and starting in a Lisp or a Scheme will let you nibble around the edges at your own pace, rather than being required to choke down nine-tenths of the entire carcass just to get to Hello World.
- chongli 13y agoPointfree style is a tricky style to get right. There is a bot on the #haskell IRC channel (lambdabot) that has a function which will transform any valid Haskell function definition into pointfree style. The results that come out of this are often totally ridiculous! Here's an example (stolen from the IRC channel, @pl is the bot command to do the transformation): @pl transform k z = reverse (foldr (\x y -> y ++ [fst(head(filter (\a -> snd a == k-1) (zip x [0..])))]) [] z) Transformed into: transform = (reverse .) . flip foldr [] . (flip (++) .) . flip flip [] . (((:) . fst . head) .) . (. flip zip [0..]) . filter . (. snd) . (==) . subtract 1 Yeah, neither is readable. This function ought to be broken up into cleaner, more declarative parts. In fact, the whole function can be reduced to this: transform k = map (!! k) Much more readable, wouldn't you agree? Now all you need to know is what map and !! do.
- amag 13y ago>> indeed, I have seen functions that contain only one line of code. Even if that is intended for reuse, it makes no sense IMHO it can make a lot of sense. In many cases you can clearly specify the intention of that one line by putting it in a function with an appropriate name. Just look at the example from the OP: void HandleNop() { SPIDataPut(SPI0_BASE, HOST_REPLY_POSACK); } When you want to handle a NOP, you're not interested in how that NOP is handled, you just want it handled...:)
- InclinedPlane 13y agoThere is nothing wrong with a one line function. Nothing whatsoever. There are huge benefits to extracting a single line of code into a function. I'll just link to a stackoverflow answer I made on the subject several years back: http://stackoverflow.com/questions/785145/one-line-functions-in-c/785217#785217 http://stackoverflow.com/questions/785145/one-line-functions... Summary: Performance almost certainly isn't an issue (compilers are smart). Abstraction leads to better design, using a well-named function can improve readability, making it easier to understand, easier to prove correct, and easier to modify. When you keep code inline it increases the inertia of the given design and implementation, extracting even a single line into a function (when warranted) can make it far easier to drastically change implementation. And if you want that single line of code to become several lines, or to switch to calling out to a web service, implement caching, add error checking or what-have-you that's made much easier when it's encapsulated inside a function than when it's sitting inside a block. Componentization is always good, even when the components are sometimes very small. Like all design choices extracting code into its own function requires judgment based on experience but when done right it can have many benefits, even when it's a single line, even when it's a fraction of a single line. Blindly following a rule such as avoiding making functions too small is just as big an error as avoiding making functions too large.
- henrik_w 13y agoSteve McConnell makes some good points about this in Code Complete too, one of which is "small methods tend to become bigger". Even if it started out as a one-line method, it is not unusual to later find the need to add something else to it. This is from memory (I don't have the book here), so I can't give a more specific reference to it.
- yummyfajitas 13y agoA single line function makes sense because it allows you to alter functionality later without worrying you forgot about some instance of that pattern: def logUnexpectedError(t: Throwable) = log.error("Oops: {}", t) After I get it together and start keeping proper metrics: def logUnexpectedError(t: Throwable) = { log.error("Oops: {}", t) statistics.errorCounterByClass(t.getClass()).inc() }
- ufo 13y agobut on that opther hand, this means added complexity in all the cases where you dont overload it. Whoever reads the program will always have to keep overloading in mind.
- pedalpete 13y agohence a good naming convention. If the function name is clear, than it shouldn't be a mind drain at all, particularly if it is only a one line function.
- mironathetin 13y agoI see, you provide many counter examples for a valid one liner. Indeed, these are good points. Thats the beauty of a forum, if used in a productive way :o).
- pdpi 13y agoA one-line function is perfectly fine (in fact, it's a good sign!), as long as you're translating domain-specific function calls to implementation-specific one-liners. It means your underlying implementation maps well to the problem.