7 ms·
How many functions are good? If I add a dozen, is that better? Short methods are good—have any evidence for that? I don't think you do, because such evidence as
by gruseom 13y ago
How many functions are good? If I add a dozen, is that better? Short methods are good—have any evidence for that? I don't think you do, because such evidence as there is points in the opposite direction (look it up in Code Complete). It's proper to name functions properly? I agree! What's "properly"?
Hammering these dogmas harder doesn't make them any truer, it just creates a feeling that you know what you're doing in a "If the English language was good enough for Jesus Christ then it's good enough for the state of Texas" kind of way. We have almost no empirically verified knowledge about software development. One of the few things we do know (sort of—the studies are old and shaky) is that code size is a predictor of error rates. Think that's relevant?
- Skinney 13y agoShort methods/functions are good in that they do very little and thus are easier to read and grasp than a function spanning 50-100 or more lines. Short methods/functions are also easier to name properly. As Clojure, F#, Haskell and friends show, it's better to have 100 functions working on one datastructure, then having ten functions for ten datastructures.
- cousin_it 13y agogruseom's comment raised the bar for evidence in this discussion, and gave some examples of evidence. "As Clojure, F#, Haskell and friends show" - can you point to a study? Relevant link: http://www.slideshare.net/gvwilson/bits-of-evidence-2338367 http://www.slideshare.net/gvwilson/bits-of-evidence-2338367
- Skinney 13y agoNo study no. But since those languages are built around that line of thinking, and becouse those languages are great, and becouse that line following your quote is in alot of the books about learning said languages, I belive the statement to be correct.
- gruseom 13y agoThat line is by Alan Perlis [1]. It's great, but not relevant to the question above, which is: all other things being equal, what's the best way to do functional decomposition? If you're moving between 1 and 10 data structures, then "all other things" are so far from being equal as to make for a completely different matter. [1] http://www.cs.yale.edu/quotes.html http://www.cs.yale.edu/quotes.html
- ufo 13y agoThe important difference in those FP languages is a) they encourage pure programs with little side effects. This is much more friendly towards small functions. b) You have the freedom to create functions only where you need to. In the OP's example, he is forced to create a new named callback after each IO call.
- Skinney 13y agoThe reason those languages are more friendly towards small functions has nothing to do with pure functions/programs. You can use the same concepts in C/C++ or Java/C# just as easily, I've done it, it's not hard. What makes those languages more friendly towards smaller functions has to do with how easy it is to create a new function in those languages. Creating a function in C/C++ for instance, is a pain becouse of the boilerplate involved (header files...). In the OP's example, he's imposing named functions on himself when he doesn't actually need to. For some reason he also declares functions within the same scope that he calls it, which just makes it cluttered in my oppinion. He would probably be alot more happy with promises.
- mattmanser 13y agoThat's a book that's citing sources from over 20 years ago, before unit testing, improved tools, compiler warnings and code analysis tools were even available. Massive changes have happened to the way we code since then. Hell OO had only just started entering the conciousness back then. We're not even talking about things like DI, just simple concepts like OO. Code Complete still has many lessons to teach, but it's certainly not gospel in this day and age (unfortunately my copy is buried in some boxes from a move and I can't find it at the mo to re-read that chapter!). I personally have seen massive changes to the way we code, people just seem to understand how to split out code into more logical chunks than they used to. Even as recently as 8 years ago, when I start professionally, I remember people used to constantly ask how to pass variables by reference, global variables, all sorts of nastiness that meant that methods weren't really being used properly. These days I honestly haven't seen a by ref pass or a global variable for years (apart from in an old, truly terrible VB.Net program I've just been given to maintain & update, ugh). Programming really has changed massively. And there certainly are fairly famous proponents of short functions out there, Kent Beck, Robert Martin. It's advice that's changed over the last 20 years, but I don't know whether there's studies to back it up, all I can give you is that the general consensus seems to have changed. Back to the point, I certainly don't hate long methods, what I hate is methods that do many different things. That's just bad code in my book, especially if they start bleeding lines into each other and get jumbled up as tends to happen as your code ages. I admit it's very easy to go too far down the rabbit hole, with a massive tree of confusingly nested methods and it's a balancing game. But when you see a long function you can usually tell straight away whether it's justified or not. Is it doing a complicated thing that justifies a hundred or two hundred lines or is it just doing loads of little simple things. And often if it's doing simple things, invariably other functions in the same code file will also be doing those simple things with tiny variations and it can be refactored to reduce the TLOC and improve maintainability when you need to update that functionality. And that's usually a sign of a programmer how hasn't learnt to do DRY yet and is relatively inexperienced (in the .Net world anyway, I'm not having a dig at all, I appreciate js still massively changes every year). A function that does one thing and one thing only is: - generally short - testable - name it intelligently and then others don't even have to read the code to know what it does - easier to spot bugs - functionality doesn't get mixed up - reusable code becomes a lot more obvious Some of these hold especially true with javascript given its lack of block scope. Long functions are generally a strong code smell, in my experience anyway. They generally contain bad code, regardless of whether they'd have been broken up or not. Functions that start declaring random anonymous objects, which I see a lot in javascript, are especially dubious. It's an artefact of javascript's design that because it's so difficult to declare reusable objects and namespaces and manage code between files a lot of javascript programmers just end up writing these huge blobs of code. As to where I see this happening in javascript, as an example I was reading Meteor.js's code the other day and was actually surprised at just how bad the code is. Every function seems to do 5 different things, it declares object right in the middle of functions rather than extracting it out, loads of frankly crazy coding practices. EDIT: In fact, now that I think about it, I remember once using that bit of CC to argue that long functions were better discussing it with a friend. Funny how you can do a complete 180 over time.
- jasonlotito 13y ago> How many functions are good? As many as needed. > If I add a dozen, is that better? If your programs path needs to do 12 things, then yes. Each function should do one thing. If in documenting your function, you use the word and, that's a safe bet that you are actually writing two functions as one. > Short methods are good—have any evidence for that? I don't think you do, because such evidence as there is points in the opposite direction (look it up in Code Complete) Unless there is another reference I missed, Code Completes reference referred to no more than a screen's height, which at that time was ~ 25 lines. Assuming not every line is a line of code performing some action, I'd still consider that a small function. > It's proper to name functions properly? I agree! What's "properly"? That's hard to answer, which is why so much has been written on it. Couple that with community idiosyncrasies (like Obj-C naming vs Java), you have a lot of "proper" ways to define functions. Within the realm of the community standards, I subscribe to the thought that the method names should tend to be verb oriented. Talk about actions, or perform an action. After all, functions do something. > We have almost no empirically verified knowledge about software development. Well, there is quite a lot. Much of it's older (in the history of software). > One of the few things we do know (sort of—the studies are old and shaky) is that code size is a predictor of error rates. Think that's relevant? Be careful about this. It's not as open and shut as you'd like to think. Indeed, it's about as verifiable and confirmed as cyclomatic complexity is. Without going into too much detail and sticking strictly the context here: "code size" is an awful metric. By that notion: int a = b + c; Is dramatically better than: int hours = timesPerformed + hoursPerPeformance; Layer that into the concept of lines of code: is that lines of functional code? Lines of any code that isn't a comment? Any lines that aren't a comment? Lines of code that are only functional? All lines, including comments? All lines, including comments, except for standard headers? All of those are valid deductions. After all, while it might seem obvious to remove comments, they could cause confusion, right? And this ignores even the basic question: is a line merely a line on the screen? Or is it a languages statement? A single operation? Would a complex for clause with multiple assignments and statements count as one line? All this is to say that code size is not the holy grail of error rates. My own though is that taking CC and LoC and putting them together is best. A function with low complexity and with fewer lines of code is better than a longer function. Many smaller, lower complexity functions are also better than a single highly-complex function that is longer than any single function, but smaller than all the others when combined.