10.2.3 Considerations for naming slots and other objects
A binding is an association between a name and an object. For example, there is a binding that associates the name of a constant and the value of the constant. The names of functions, module variables, local variables, and classes are also bindings. There is a potential problem that can occur if you use short names. If a client module uses other modules that also define and export bindings with short names, there is a significant chance that name clashes will occur, with different bindings with the same name being imported from different modules.
If you use the Dylan naming conventions, then a variable will not have the same name as a class, a function, or a constant. The naming conventions avoid name clashes between different kinds of objects.
A slot is identified by the name of its getter. The getter is visible to all client modules. There is no problem if two getters with the same name are defined by unrelated classes, because the appropriate getter is selected through method dispatch. There is a problem if a getter has the same name as a generic function with an incompatible parameter list or values declaration. (See Section 12.2.5, page 176.) When such a problem occurs, the only way to resolve it is to use options to define module to exclude or rename some of the problem bindings. This solution is undesirable, because it requires work on the part of the author of the client module, who must spot and resolve such clashes, and then use an interface that no longer matches its documentation.
Therefore, for getters that you intend to export, it makes sense prevent clashes by considering the name of the slot carefully. One technique is to prefix the name of the property with the name of the class. For example, you might define a <person> class with a slot person-name, instead of the shorter possibility, name. One drawback of this technique is that it might expose too much information about the implementation — that is, the name betrays the class that happens to implement the slot at a particular time, and you have to remember which superclass introduces a property if you are to access that property.
There is a compromise between using short names and using the class name as a prefix — you can choose a prefix for a whole group of classes beneath a given class. For example, you might use the prefix person- for slots of many classes that inherit from the <person> class, including <employee>, <consultant>, and so on.
define class <person> (<object>) slot person-name; slot person-age; end class <person>; define class <employee> (<person>) slot person-number; slot person-salary; end class <employee>; define class <consultant> (<employee>) slot person-perks; slot person-parking-lot; end class <consultant>;
Now, in a method on <consultant>, all accesses are consistent, and we do not have to remember where the slots actually originate:
// Method 1
define method person-status (p :: <consultant>) => (status :: <integer>)
(p.person-perks.evaluation + p.person-salary.evaluation)
/ p.person-age;
end method person-status;
If we had defined the classes differently, such that we prefixed each getter with the name of the class that defined it, the method would look like this:
// Method 2
define method person-status (p :: <consultant>) => (status :: <integer>)
(p.consultant-perks.evaluation + p.employee-salary.evaluation)
/ p.person-age;
end method person-status;
Method 2 is more difficult to write and read than is Method 1, and is more fragile. If, at some point, all employees are allocated perks, then the use of the consultant-perks getter becomes a problem.




