I have a project where we have a mix of different naming when a function needs to find an object using a property given in parameter. I am wondering if there is a naming convention for the following:
function getObjectUsingName(name){} // A
function getObjectByName(name){} // B
function getObjectWithName(name){} // C
More basically, it there a different meaning between them or it is only a matter of choosing one?
I would say it is only matters for easy to read the code. And usually people choose "by". So function getObjectByName(name){} would be the nicest way but it is only based on my experience.
Related
I implement several global functions in our library that look something like this:
void init_time();
void init_random();
void init_shapes();
I would like to add functions to provide a check whether those have been called:
bool is_time_initialized();
bool is_random_initialized();
bool are_shapes_initialized();
However, as you can see are_shapes_initialized falls out of the row due to the fact that shapes is plural and therefore the function name must start with are and not is. This could be a problem, as the library is rather large and not having a uniform way to group similiar functions under the same naming convention might be confusing / upsetting.
E.g. a user using IntelliSense quickly looking up function names to see if the libary offers a way to check if their initialization call happened:
They won't find are_shapes_initialized() here unless scrolling through hundreds of additional function / class names.
Just going with is_shapes_initialized() could offer clarity:
As this displays all functions, now.
But how can using wrong grammar be a good approach? Shouldn't I just assume that the user should also ask IntelliSense for "are_initialized" or just look into the documentation in the first place? Probably not, right? Should I just give up on grammatical correctness?
The way I see it, a variable is a single entity. Maybe that entity is an aggregate of other entities, such as an array or a collection, in which case it would make sense to give it a plural name e.g. a set of Shape objects could be called shapes. Even so, it is still a single object. Looking at it that way, it is grammatically acceptable to refer to it as singular. After all, is_shapes_initialized actually means "Is the variable 'shapes' initialized?"
It's the same reason we say "The Bahamas is" or "The Netherlands is", because we are referring to the singular country, not whatever plural entity it is comprised of. So yes, is_shapes_initialized can be considered grammatically correct.
It's more a matter of personal taste. I would recommend putting "is" before functions that return Boolean. This would look more like:
bool is_time_initialized();
bool is_random_initialized();
bool is_shapes_initialized();
This makes them easier to find and search for, even if they aren't grammatically correct.
You can find functions using "are" to show it is plural in places such as the DuckDuckGo app, with:
areItemsTheSame(...)
areContentsTheSame(...)
In the DuckDuckGo app, it also uses "is" to show functions return boolean, and boolean variables:
val isFullScreen: Boolean = false
isAssignableFrom(...)
In OpenTK, a C# Graphics Library, I also found usage of "are":
AreTexturesResident(...)
AreProgramsResident(...)
In the same OpenTK Libary, they use "is" singularly for functions that return boolean and boolean variables:
IsEnabledGenlock(...)
bool isControl = false;
Either usage could work. Using "are" plurally would make more sense grammatically, and using "if" plurally could make more sense for efficiency or simplifying Boolean functions.
Here's what I would do, assuming you are trying to avoid calling this function on each shape.
void init_each_shape();
bool is_each_shape_initialized();
Also assuming that you need these functions, it seems like it would make more sense to have the functions throw an exception if they do not succeed.
what's the naming convention for a function that searches an entity by 4 parameters?
for instance GetCarByColourBrandStyleAndType sounds way too long although is descriptive enought IMO
Can't you just use SearchForCar for instance?
The paramaters (I expect are type, brand, color...) should give clarification? You can always make one or more parameters optional when you have for example another function saying GetCarByBrandColor()
When I wrote some general programming utility code, I found that it's good to have both inplace mutator and new object creator member function for one functionality.
For example, some class which represents path in file system may have "normalize" functionality. Path object may mutates itself into normalized one, or returns new normalized path object.
class path {
...
void normalize_itself()
path get_new_normalized_path()
...
}
I've tried some convention for this one, but most of them are not satisfiable.
'normalize!' for inplace function like ruby - good, but most other languages don't support special character to be included in identifier.
'normalize_ip' for inplace function - since most of my function usages are inplace, I think it's too ugly.
'get_normalized' for non-inplace function - acceptable, but can be confused with other simple getter function for member.
'normalized' for non-inplace function - sometime not uniform, and easily confused with its inplace counter part.
write non-inplace function as free function - lack of intellisense assistance of IDE, sometime visibility issues.
I'd like to find some good/practical convention to distinguish two function.
I think normalize for your mutator and grab_normalized for your object creator would work.
I am wondering if there exists already some naming conventions for Ocaml, especially for names of constructors, names of variables, names of functions, and names for labels of record.
For instance, if I want to define a type condition, do you suggest to annote its constructors explicitly (for example Condition_None) so as to know directly it is a constructor of condition?
Also how would you name a variable of this type? c or a_condition? I always hesitate to use a, an or the.
To declare a function, is it necessary to give it a name which allows to infer the types of arguments from its name, for example remove_condition_from_list: condition -> condition list -> condition list?
In addition, I use record a lot in my programs. How do you name a record so that it looks different from a normal variable?
There are really thousands of ways to name something, I would like to find a conventional one with a good taste, stick to it, so that I do not need to think before naming. This is an open discussion, any suggestion will be welcome. Thank you!
You may be interested in the Caml programming guidelines. They cover variable naming, but do not answer your precise questions.
Regarding constructor namespacing : in theory, you should be able to use modules as namespaces rather than adding prefixes to your constructor names. You could have, say, a Constructor module and use Constructor.None to avoid confusion with the standard None constructor of the option type. You could then use open or the local open syntax of ocaml 3.12, or use module aliasing module C = Constructor then C.None when useful, to avoid long names.
In practice, people still tend to use a short prefix, such as the first letter of the type name capitalized, CNone, to avoid any confusion when you manipulate two modules with the same constructor names; this often happen, for example, when you are writing a compiler and have several passes manipulating different AST types with similar types: after-parsing Let form, after-typing Let form, etc.
Regarding your second question, I would favor concision. Inference mean the type information can most of the time stay implicit, you don't need to enforce explicit annotation in your naming conventions. It will often be obvious from the context -- or unimportant -- what types are manipulated, eg. remove cond (l1 # l2). It's even less useful if your remove value is defined inside a Condition submodule.
Edit: record labels have the same scoping behavior than sum type constructors. If you have defined a {x: int; y : int} record in a Coord submodule, you access fields with foo.Coord.x outside the module, or with an alias foo.C.x, or Coord.(foo.x) using the "local open" feature of 3.12. That's basically the same thing as sum constructors.
Before 3.12, you had to write that module on each field of a record, eg. {Coord.x = 2; Coord.y = 3}. Since 3.12 you can just qualify the first field: {Coord.x = 2; y = 3}. This also works in pattern position.
If you want naming convention suggestions, look at the standard library. Beyond that you'll find many people with their own naming conventions, and it's up to you to decide who to trust (just be consistent, i.e. pick one, not many). The standard library is the only thing that's shared by all Ocaml programmers.
Often you would define a single type, or a single bunch of closely related types, in a module. So rather than having a type called condition, you'd have a module called Condition with a type t. (You should give your module some other name though, because there is already a module called Condition in the standard library!). A function to remove a condition from a list would be Condition.remove_from_list or ConditionList.remove. See for example the modules List, Array, Hashtbl,Map.Make`, etc. in the standard library.
For an example of a module that defines many types, look at Unix. This is a bit of a special case because the names are mostly taken from the preexisting C API. Many constructors have a short prefix, e.g. O_ for open_flag, SEEK_ for seek_command, etc.; this is a reasonable convention.
There's no reason to encode the type of a variable in its name. The compiler won't use the name to deduce the type. If the type of a variable isn't clear to a casual reader from the context, put a type annotation when you define it; that way the information provided to the reader is validated by the compiler.
Scheme uses a single namespace for all variables, regardless of whether they are bound to functions or other types of values. Common Lisp separates the two, such that the identifier "hello" may refer to a function in one context, and a string in another.
(Note 1: This question needs an example of the above; feel free to edit it and add one, or e-mail the original author with it and I will do so.)
However, in some contexts, such as passing functions as parameters to other functions, the programmer must explicitly distinguish that he's specifying a function variable, rather than a non-function variable, by using #', as in:
(sort (list '(9 A) '(3 B) '(4 C)) #'< :key #'first)
I have always considered this to be a bit of a wart, but I've recently run across an argument that this is actually a feature:
...the
important distinction actually lies in the syntax of forms, not in the
type of objects. Without knowing anything about the runtime values
involved, it is quite clear that the first element of a function form
must be a function. CL takes this fact and makes it a part of the
language, along with macro and special forms which also can (and must)
be determined statically. So my question is: why would you want the
names of functions and the names of variables to be in the same
namespace, when the primary use of function names is to appear where a
variable name would rarely want to appear?
Consider the case of class names: why should a class named FOO prevent
the use of variables named FOO? The only time I would be referring the
class by the name FOO is in contexts which expect a class name. If, on
the rare occasion I need to get the class object which is bound to the
class name FOO, there is FIND-CLASS.
This argument does make some sense to me from experience; there is a similar case in Haskell with field names, which are also functions used to access the fields. This is a bit awkward:
data Point = Point { x, y :: Double {- lots of other fields as well --} }
isOrigin p = (x p == 0) && (y p == 0)
This is solved by a bit of extra syntax, made especially nice by the NamedFieldPuns extension:
isOrigin2 Point{x,y} = (x == 0) && (y == 0)
So, to the question, beyond consistency, what are the advantages and disadvantages, both for Common Lisp vs. Scheme and in general, of a single namespace for all values versus separate ones for functions and non-function values?
The two different approaches have names: Lisp-1 and Lisp-2. A Lisp-1 has a single namespace for both variables and functions (as in Scheme) while a Lisp-2 has separate namespaces for variables and functions (as in Common Lisp). I mention this because you may not be aware of the terminology since you didn't refer to it in your question.
Wikipedia refers to this debate:
Whether a separate namespace for functions is an advantage is a source of contention in the Lisp community. It is usually referred to as the Lisp-1 vs. Lisp-2 debate. Lisp-1 refers to Scheme's model and Lisp-2 refers to Common Lisp's model. These names were coined in a 1988 paper by Richard P. Gabriel and Kent Pitman, which extensively compares the two approaches.
Gabriel and Pitman's paper titled Technical Issues of Separation in Function Cells and Value Cells addresses this very issue.
Actually, as outlined in the paper by Richard Gabriel and Kent Pitman, the debate is about Lisp-5 against Lisp-6, since there are several other namespaces already there, in the paper are mentioned type names, tag names, block names, and declaration names. edit: this seems to be incorrect, as Rainer points out in the comment: Scheme actually seems to be a Lisp-1. The following is largely unaffected by this error, though.
Whether a symbol denotes something to be executed or something to be referred to is always clear from the context. Throwing functions and variables into the same namespace is primarily a restriction: the programmer cannot use the same name for a thing and an action. What a Lisp-5 gets out of this is just that some syntactic overhead for referencing something from a different namespace than what the current context implies is avoided. edit: this is not the whole picture, just the surface.
I know that Lisp-5 proponents like the fact that functions are data, and that this is expressed in the language core. I like the fact that I can call a list "list" and a car "car" without confusing my compiler, and functions are a fundamentally special kind of data anyway. edit: this is my main point: separate namespaces are not a wart at all.
I also liked what Pascal Constanza had to say about this.
I've met a similar distinction in Python (unified namespace) vs Ruby (distinct namespaces for methods vs non-methods). In that context, I prefer Python's approach -- for example, with that approach, if I want to make a list of things, some of which are functions while others aren't, I don't have to do anything different with their names, depending on their "function-ness", for example. Similar considerations apply to all cases in which function objects are to be bandied around rather than called (arguments to, and return values from, higher-order functions, etc, etc).
Non-functions can be called, too (if their classes define __call__, in the case of Python -- a special case of "operator overloading") so the "contextual distinction" isn't necessarily clear, either.
However, my "lisp-oid" experience is/was mostly with Scheme rather than Common Lisp, so I may be subconsciously biased by the familiarity with the uniform namespace that in the end comes from that experience.
The name of a function in Scheme is just a variable with the function as its value. Whether I do (define x (y) (z y)) or (let ((x (lambda (y) (z y)))), I'm defining a function that I can call. So the idea that "a variable name would rarely want to appear there" is kind of specious as far as Scheme is concerned.
Scheme is a characteristically functional language, so treating functions as data is one of its tenets. Having functions be a type of their own that's stored like all other data is a way of carrying on the idea.
The biggest downside I see, at least for Common Lisp, is understandability. We can all agree that it uses different namespaces for variables and functions, but how many does it have? In PAIP, Norvig showed that it has "at least seven" namespaces.
When one of the language's classic books, written by a highly respected programmer, can't even say for certain in a published book, I think there's a problem. I don't have a problem with multiple namespaces, but I wish the language was, at the least, simple enough that somebody could understand this aspect of it entirely.
I'm comfortable using the same symbol for a variable and for a function, but in the more obscure areas I resort to using different names out of fear (colliding namespaces can be really hard to debug!), and that really should never be the case.
There's good things to both approaches. However, I find that when it matters, I prefer having both a function LIST and a a variable LIST than having to spell one of them incorrectly.