Closed Fabien-Chouteau closed 7 years ago
On 2/14/2017 4:35 AM, Fabien Chouteau wrote:
Those function names are good procedure names. ;-)
I don't get it. I didn't use Get_* :)
True, and much appreciated. This is directly related though.
[begin preaching]
Because Ada distinguishes functions from procedures, the naming scheme for them can be different, to the benefit of the reader. At the language level, procedures can never be used as functions, and vice versa. (Yes, functions can go do things as well as return a value, but they can never be called like a procedure, ie in a statement context.)
Procedures always represent a set of actions that do something, whereas functions always return (and thus represent) values. It is true that functions can perform some set of actions too, but should they? Rarely, but sometimes yes. That amounts to side effects, a possibility with functions that can lead to nasty issues, and so are to be avoided when possible. "Memo functions" and such, eg random number generator functions, have side effects by definition, but those effects are benign.
So procedure names are ideally actions, ie imperative verbs that mean "go do this thing", but function names are ideally either predicate names (for boolean functions) or nouns. Nobody would find the name Compute_Sine to be a good name for the mathematical Sine function, for example. We just want to say "Sin (X)" in an expression.
This is not just my opinion. It is a very common one and it reflects the original language design. That's one reason why it is the scheme specified in the Ada Quality and Style Guidebook. See section 3.2.5 "Program Unit Names" in the document, available here: http://www.adaic.org/resources/add_content/docs/95style/95style.pdf
My personal scheme is slightly different, in that I find the "Is_" prefix for predicate names to be redundant, but that is a minor point. I've used both.
All of this is about readability, critical to so many other desirable qualities, such as reliability, which is why I harp about it all the time. I spend a lot of time refactoring names to represent the domain space and for readability, because I think it is that important.
A naming scheme is a way of passing more information to the reader, similar to the many other things we tell the reader by our choices in the code. For example, if we declare something (eg a variable) at the level of a package body, we are telling the reader, because of the reader's knowledge of the visibility rules, that this entity is used by multiple units within the package body. Such use is not required by the language, it could certainly be used by only one of them, but if so that would be a misleading choice of placement. We'd be forcing the reader to recognize that the usage is not global to the package body after all, something they would rightfully assume on first encountering it.
[end preaching]
So, to give a concrete example, the name "Read_*" would be a procedure name because "read" is an imperative verb.
I don't make a big deal of many things (I hope!), but readability is critical to so many other desirable qualities that I consider it very important.
So, to give a concrete example, the name "Read_*" would be a procedure name because "read" is an imperative verb.
I think I agree with that, actually can you write a short version of your preach in design.md or a new file style.md so that we can capture it. I don't know if we will have means to automatically enforce this kind of naming scheme.
In this very instance (Microbit.IO) I'm reusing the naming of the main MicroBit library (in python), so I'm sort of following the domain. I can at least document this choice.
On 2/20/2017 9:26 AM, Fabien Chouteau wrote:
So, to give a concrete example, the name "Read_*" would be a procedure name because "read" is an imperative verb.
I think I agree with that, actually can you write a short version of your preach in design.md or a new file style.md so that we can capture it. I don't know if we will have means to automatically enforce this kind of naming scheme.
I'll be happy to write it up. You're right, though, I don't think it is automatically enforceable, we'll have to rely on manual reviews.
In this very instance (Microbit.IO) I'm reusing the naming of the main MicroBit library (in python), so I'm sort of following the domain. I can at least document this choice.
Who will read it more, Ada users or Python users? :-) :-)
I'll be happy to write it up. You're right, though, I don't think it is automatically enforceable, we'll have to rely on manual reviews.
Thanks!
Who will read it more, Ada users or Python users? :-) :-)
Frankly, Python users I hope :)
On 2/20/2017 4:27 PM, Fabien Chouteau wrote:
I'll be happy to write it up. You're right, though, I don't think it is automatically enforceable, we'll have to rely on manual reviews.
Thanks!
Who will read it more, Ada users or Python users? :-) :-)
Frankly, Python users I hope :)
In half-serious mode: you could get fancy and introduce a renaming for each routine, introducing the Python name. Or just a comment. :-)
I don't get it. I didn't use Get_* :)