Code is prose, maybe, but there are definitely lots of different types of prose, and I don't think code would be one of the types of prose that has protagonists, comedic characters, and damned villains (or if it is, it should not strive to be so). In other words please this recurring code is like great literature kick is really irritating.
maybe one off scripts should be like lyric poetry though.
"The method name getAbsoluteDifference() means to get the absolute difference between the pair of numbers. The method name contains a verb get.
It would not make much sense to name the method simply absoluteDifference(), because such name does not indicate any action."
I disagree. I want the property of 'absolute difference' between the two numbers. Getting that value is what I do when I make an assignment. Whether this value is cached or calculated is of little consequence to outside code provided it has no side effects on other state within the object. Should a method (member function, whatever) cause side effects within the target object, then the method has become a verb. Like, 'increase(by:)' - that's a verb, affects the state of the object ... well-named, friend.
Aside from that, I think the rest has embodied well Apple's talk about Swift API style from WWDC with a nice dose of input from this author.
Edited to add: 'getAverage()' shows up later. I fail to see how 'get' adds anything of importance considering its company 'reversed' and 'sorted' - they should all prefix with 'get' or they should not. I'm in the 'not' camp.
It would make me sad to type getSqrt(), getMin(), getMax(), getStrLen(), getSizeOf(), get…
Putting a verb in the function name is not a bad idea, but if you find yourself identifying the verb as “get”, then it’s a useless three extra letters.
I think for most people, "getFoo" generally implies direct access to a data member, not a calculation. This is a useful hint, and an argument for not using it in other contexts.
Good point. For me personally, I find myself using “get” whenever a function or method will query a database or some other external source to deliver the result. For example, getNormalizedDeliveryAddress(), or getRelatedComments().
Personally, for whatever reason in my mind, I think "get" as referring to something local which is why I choose between three different verbs, "grab", "fetch", or "query" (typically grab), as a descriptive prefix for functions that retrieve data from external sources.
I doubt that's most people unless most people are confused. The whole point of having getters and setters is to abstract away the implementation details of where the value comes from. Direct access to a data member is easily achieved via direct access to the data member, it doesn't require a method.
Back in the early days of Pascal programming for both DOS and Mac, it was common to put a 'the' prefix on just about every variable. I guess it was supposed to be more "English-like". You'd have variables like this:
theWindow
theUser
theFile
theLineCount
I hated it! I never did find out why people wanted to put in such a useless noise word in every single variable name, but I decided to never do it again.
Indeed, it is horrific. As is Hungarian notation. Anything where the type or locality ('m_foo', 'g_var') has infiltrated the name of the variable says to me that the variable is named badly.
I'm in the "do" camp, because using "get" (or similar verbs) offers a hint that the method does not mutate the object.
"Average" can be both a noun and a verb, so "getAverage()" clarifies that it's being used as a noun.
An alternate but less-common approach would be to assume verbs and conjugate, like "averaged()"... But what if the verb and noun have very different meanings?
- Don't force people to guess. Guessing takes time, and is an opportunity for a mistake.
- Explicit information is better than implicit information. Abbreviations, incomplete identifiers are a form of implicit information.
- Lying exists in programming. Identifiers that do not match their purpose can mislead programmers and introduce bugs. e.g: Including side-effects in a function is called "get", "read" or "retrieve".
- Coupling brings more information into a scope, making it more complex and decreasing readability.
This may not be a popular opinion, but for me read and retrieve are indicative of a side-effect. I consistently use retrieve to indicate fetching things from database, or remote locations (REST, RPC, whatever). Similarly, read, in the case of a parser or whatnot, indicates that the buffer will be advanced.
Maybe I'm just too biased because I try to have const-correct/mutable-correct code?
Sounds like you're building up a set of conventions which can be very useful when you're consistent with them and communicate them to others reading your code.
Agreed, these words have similar connotations for me as well. I have also seen deliberate usage of set vs update to indicate changes to objects in memory only vs persistence to databases, etc.
And of course, with sufficiently aggressive optimization, there may not actually even be a change to an object in memory (or the object in memory to change) in some cases. Not so with the database.
If it's a partial read that requires to track state, then yes. If it's a somehow self-contained read operation that returns a result, while it has side effects (I/O), it may not necessarily have to mutate variables in your program (e.g: load a small file into string variable, make a HTTP response and return the body, etc).
> The scope is to understand what the function does from its name, arguments list and the way it is invoked.
Good names mean a great deal, but this is too much to expect from them. Understanding what a function does includes issues such as its time complexity, whether it is thread safe, what (if anything) it modifies, what exceptions it might throw and what exception safety guarantees it honors... And there may well be specific corner cases - for example, in a function with 'find' in its name, what does it do if there are zero or multiple matches to the key being sought?
Intelligent naming may be the most underrated skill of high quality programmers, along with "simplicity".
My go-to example is the Tensorflow code base. It sounds intimidating, deep learning, etc., right? But take something like the Seq2Seq implementation, and marvel how elegant and readable the module is. Some part of that is due to the simplicity of "programmer happiness languages" like Python and Ruby (sorry Java, JavaScript), but it's also clear that the easy part for them was making it work, while the part that probably took most of their focus was engineering simplicity. To even be in that position means you're already really, really good.
I typically contrast this with another Seq2Seq implementation in another certain library (I won't call out anybody) done by a PhD student, that looks very intelligent, but with no focus on engineering simplicity or elegant naming, it is an exercise in frustration to get through.
I disagree! This is a bad mindset that gets dispelled when you use a language that distinguishes between functions and actions. Writing to a database is doing something; returning the second value of a tuple isn't. There's no good reason to put a verb in the function that takes a tuple and projects out its subcomponents. "first" or "firstOf" gets the point across more concisely.
30 comments
[ 4.4 ms ] story [ 113 ms ] threadmaybe one off scripts should be like lyric poetry though.
I disagree. I want the property of 'absolute difference' between the two numbers. Getting that value is what I do when I make an assignment. Whether this value is cached or calculated is of little consequence to outside code provided it has no side effects on other state within the object. Should a method (member function, whatever) cause side effects within the target object, then the method has become a verb. Like, 'increase(by:)' - that's a verb, affects the state of the object ... well-named, friend.
Aside from that, I think the rest has embodied well Apple's talk about Swift API style from WWDC with a nice dose of input from this author.
Edited to add: 'getAverage()' shows up later. I fail to see how 'get' adds anything of importance considering its company 'reversed' and 'sorted' - they should all prefix with 'get' or they should not. I'm in the 'not' camp.
Putting a verb in the function name is not a bad idea, but if you find yourself identifying the verb as “get”, then it’s a useless three extra letters.
Make every word count.
"Average" can be both a noun and a verb, so "getAverage()" clarifies that it's being used as a noun.
An alternate but less-common approach would be to assume verbs and conjugate, like "averaged()"... But what if the verb and noun have very different meanings?
- Don't force people to guess. Guessing takes time, and is an opportunity for a mistake.
- Explicit information is better than implicit information. Abbreviations, incomplete identifiers are a form of implicit information.
- Lying exists in programming. Identifiers that do not match their purpose can mislead programmers and introduce bugs. e.g: Including side-effects in a function is called "get", "read" or "retrieve".
- Coupling brings more information into a scope, making it more complex and decreasing readability.
Maybe I'm just too biased because I try to have const-correct/mutable-correct code?
Good names mean a great deal, but this is too much to expect from them. Understanding what a function does includes issues such as its time complexity, whether it is thread safe, what (if anything) it modifies, what exceptions it might throw and what exception safety guarantees it honors... And there may well be specific corner cases - for example, in a function with 'find' in its name, what does it do if there are zero or multiple matches to the key being sought?
My go-to example is the Tensorflow code base. It sounds intimidating, deep learning, etc., right? But take something like the Seq2Seq implementation, and marvel how elegant and readable the module is. Some part of that is due to the simplicity of "programmer happiness languages" like Python and Ruby (sorry Java, JavaScript), but it's also clear that the easy part for them was making it work, while the part that probably took most of their focus was engineering simplicity. To even be in that position means you're already really, really good.
I typically contrast this with another Seq2Seq implementation in another certain library (I won't call out anybody) done by a PhD student, that looks very intelligent, but with no focus on engineering simplicity or elegant naming, it is an exercise in frustration to get through.
It is very nice to read.
I disagree! This is a bad mindset that gets dispelled when you use a language that distinguishes between functions and actions. Writing to a database is doing something; returning the second value of a tuple isn't. There's no good reason to put a verb in the function that takes a tuple and projects out its subcomponents. "first" or "firstOf" gets the point across more concisely.
https://en.wikipedia.org/wiki/Shakespeare_Programming_Langua...
"for each card in deck" is much better then "for each item in list" as card and deck gives much more information!