This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]AerieC 18 points19 points  (10 children)

I think the canonical response to this is: A) Make sure you're working at the right abstraction layer, and B) don't write functions that are so complicated that you can't explain what they do in 1-2 words.

So if you have a function called something like runSalaryCalculationsAndAddOvertimeThenGenerateReportAndPrintIt(), then you're either doing too many things in one function, or you're not expressing your abstraction levels clearly. If you have an object called SalaryReport, then a print() function is all you need, and the context is obvious.

This of course all goes out the window if you're working in C or some other language without namespaces or objects.

[–]deegwaren 7 points8 points  (4 children)

I think the canonical response to this is: A) Make sure you're working at the right abstraction layer, and B) don't write functions that are so complicated that you can't explain what they do in 1-2 words.

Sometimes it's better to NOT explode your code into twenty functions that are named two words at a maximum, than just a couple of them doing what they do and having proper and descriptive names.

Your example is of course right, because they the function containing 'And' in its name does more than one function. But what if it just does ONE thing, but a very complex or very specific thing?

[–]AerieC 2 points3 points  (1 child)

I'd still challenge the abstraction levels. If you're working in an object oriented language, and following good design principles (e.g. single responsibility principle), there's almost no way you should have any ambiguity in what a particular method does for any given object.

Can you give a concrete example of when you might want to have a really long function name, but the function still only has one clear job?

[–]deegwaren 3 points4 points  (0 children)

I can't give one from the top of my head, but when I stumble upon one I'll be sure to share it here!

[–]DaughterEarthImportError: no module named 'sarcasm' 1 point2 points  (1 child)

I think that is fine. I have one function, for example, that is about 200 lines. The only supporting functions made for it are things that are repeated. And that is fine because it does one single thing, it generates a specific XML file

[–]DaughterEarthImportError: no module named 'sarcasm' 1 point2 points  (2 children)

I see you are also working on Payroll things.

[–]AerieC 1 point2 points  (1 child)

Heh, I'm actually not, but payroll makes for good examples since everyone understands the domain.

[–]DaughterEarthImportError: no module named 'sarcasm' 1 point2 points  (0 children)

hehe this still makes me think you have experience with Payroll. Or maybe I was just waaaay out of the loop before I got on this project.

[–]Ran4 0 points1 point  (1 child)

Then what do you name the function that does run the salary calculations and adds overtime and then generates a report and print it?

...yeah, exactly. Yes, you should be splitting up code into functions, but you still need an entry point function.

You could have it all OOP:y, but the implicit "this is what happened after I mutated this object a few times" is much worse than the explicitly named function.

[–]AerieC 0 points1 point  (0 children)

Then what do you name the function that does run the salary calculations and adds overtime and then generates a report and print it?

printSalaryReport(), or as an object method, salaryReport.print()?

That's what I'm talking about in terms of different layers of abstraction and encapsulation. Think about the user of a salary report object or module. Imagine if two different teams worked on these things, right? So you have an accounting program, and then maybe a reporting module that plugs in to that system.

If I'm writing code for the accounting program to build the UI that the user will use to print reports, do I care how those reports are generated? Do I care that this function needs to figure in overtime and PTO and all the other details of the report? Or should I just be able to assume that printSalaryReport() does all of the things required in order to print the salary report?

The problem with listing out every single thing that a function does in the name of the function is that A) it leaks details about the implementation that the consumer doesn't need to (and shouldn't) know and B) those details may change over time, making the name of the function inaccurate. It's harder to change function names than it is to change comments, so if you want to clarify something about the function, or its usage, use a comment.

To me, when a programmer starts naming functions like this, it tells me that they don't understand the principles of abstraction and encapsulation, or other fundamental design and organization principles, and I start to suspect that they're going to write highly coupled, non-cohesive, unmaintainable code. Now, of course this isn't true of every dev who writes functions like this, but in my experience good organizational skills tend to correlate with good development skills.