 |
A Case Against Uppercase
Posted by evanx on September 28, 2006 at 07:13 AM | Comments (19)
Consider the following code.
public class Car {
private static final int SPEED_LIMIT = 120;
private int speed;
...
public boolean isLegal() {
if (speed > SPEED_LIMIT) return false;
return true;
}
}
OK, in C our constants were #define macros, and we put them in uppercase.
Because macros are quite distinctive animals, compared to domesticated code.
In Java by convention we put them in uppercase as well. They are
distinguished from other class attributes
by being static and final. Since other attributes might also be static,
and others might also be final, semantically this distinction is weak.
Let's say we decide to make the above class more customisable where
the SPEED_LIMIT is configuable, eg. for different countries.
So we make it not final.
public class Car {
private static int SPEED_LIMIT = 120;
private int speed;
...
public static void setSpeedLimit(int newSpeedLimit) {
SPEED_LIMIT = newSpeedLimit;
}
}
Of course as soon as we take away the final modifier, we should rename it speedLimit.
The argument i'm trying to illustrate is that we should drop this legacy hangover
of uppercase and underscores for "constants." Because they aren't macros anymore.
They are class attributes with a final modifier, and in my book that's not enough for any special
treatment, such as breaking the clean Java camel-cap naming convention.
To summarise, LOUD UPPERCASE WORDS AND _UNDERSCORES_ SHOULD BE BANISHED, as relics of a bygone era,
don't you think!?
Bookmark blog post: del.icio.us Digg DZone Furl Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment
-
I disagree. It's one of those conventions that is applied universally and thus is very reliable as a guide when reading the code. Patrick
Posted by: pdoubleya on September 28, 2006 at 08:26 AM
-
I agree. It's a form of hungarian notation. It's a convention sure, but it can be violated easily by humans. So there's opportunity to deceive.
Posted by: demian0311 on September 28, 2006 at 08:40 AM
-
The new feature of the current era are IDEs, text editors, and refactoring. In NetBeans you can ctrl-shift-R when underneath one of the decelerations and it will rename it to whatever you want it to, wherever it is! But another vestige from a bygone era is ctrl-H, search and replace.
Posted by: shemnon on September 28, 2006 at 09:05 AM
-
Hi Evan,
Sorry man, but I think your case is too weak and would be easily beaten on any court. IANAJL (I'm not a Java lawyer :-), but I can quote a couple of arguments against it:
- 'backward' compatibility: as Patrick mentioned, it's already universally used, and make code easier to read
- to worse item 1, you can (although you should not) acccess static variables through instance references. So, you could have
Car car;
int a = car.speed;
int b = car.speedLimit;
Which one is static and which is an attribute?
- to make the previous example worse, we could use import static:
import static Car.*;
int x = 3*speedLimit;
- they are not only class attributes with a final modifer; they could be enums as well (I know the final result in the bytecode would be the same, but not for someone reading the code).
- references to constants can be inlined and then eliminated from the bytecode. That can cause confusion afterwards, as the identifier wouldn't be present(say in a debug session or after decompiling the code).
- the semantic of these constants is that they can only be change on compile-time. Your example does not make sense in this aspect - if the speed limit changes according to the country, it should not be a compile-time constant, but a proper attribute (or object or even a resource in a bundle).
-- Felipe
Posted by: felipeal on September 28, 2006 at 09:09 AM
-
I can't help it I have never liked UPPER_CASE constants,
I just don't like the way they SHOUT_AT_YOU when you're reading code.
Although I have to admit that the convention argument and
the fact that it makes the code clearer are good points.
So all I can say is:-
I_USED_TO_BE_CONFUSED
butNowImNotSoSure.
Posted by: panaseam on September 28, 2006 at 12:28 PM
-
non constant constants, i love it :)
i hear you buddy, in that special case one might use Car.getSpeedLimit();
Posted by: liquid on September 28, 2006 at 10:52 PM
-
I totally agree !
I stopped used MAJ_CONSTANT some times ago, because it's unreadable and too for the case you expose.
I found more and more open-source code that agree with us, so please everyone stop this MAJ_CONSTANT that haven't any sense !
In my IDE (Eclipse) constant are "italic" so why put in in caps ??
There is no-sense...
Thanks to spread the work guy,
Posted by: alois on September 28, 2006 at 11:09 PM
-
-1
Posted by: ge0ffrey on September 29, 2006 at 12:57 AM
-
Thanks for all your comments :) Another consideration is that all public class attributes are typically constants, so all attributes we expose in our API are uppercase - in which having them in uppercase doesn't distinguish them from other (non-constant) public attributes, because there aren't any!
Posted by: evanx on September 29, 2006 at 02:18 AM
-
This should be handled in modern times with a proper IDE-- for example with a different color for static final immutable members.
Eclipse now does a great job of making members standout from regular variables, now there is no need for distracting prefixes like "this.", "m_" or "my".
I bolded immutable because you didn't mention it, and it's also a requirement to upper case a name.
Posted by: firefight on September 29, 2006 at 07:45 AM
-
Since javac (in my opinion confusingly) optimizes many static finals by inlining them, they somewhat still are macros. And I agree that non-final statics are usually evil. Also that it's an almost universal convention still in Java. But the IDE point is a good one, too. The IDE knows it, so just believe it. Who knows? Maybe it will change with time.
Posted by: tompalmer on September 29, 2006 at 07:51 AM
-
GoodForTwoWordsButNearlyUnreadableThereafterCamelCase is more readable than UPPERCASE constants? Give me a break.
At least UPPERCASE shouts in your face to remind you of it's CONSTANT nature. What does the hallowed CamelCase tell me about? How is it better than the more readable convention of using _ to separate words, besides saving some keystrokes (debatable in the days of autocompletion). It's more natural in (at least) English language to join words using - (hypen) as in oh-so-hackeneyed-argument, I haven't seen anyone writing 'OhSoHackenyedArgument' without getting sued for unreadability. Underscores are the second-best substitute for Hypens (as they're already takes as minus operator).
Fault is not with the constants but , unfortunately, with the language. Java has no clean 'n simple way of defining a constant ( lacks 'const' keyword). Requiring dual declarations -Final Static is a more of a hack than a feature -- which ironically -- neccessiates UPPERCASE convention. Otherwise, how do you distinguish between Final Statics and Non-Final Statics from the readability/human understanding perspective?
Ditto for the _instance_variable, another hack forced on me by the language which allows function arguments/local variables to shadow instance variables. I find better comfort in the less verbose _ convention, instead of the fascist this.some_var = some_var.
I know Compiler will spit an error, Eclipse will show a red-cross , show in italics etc. I am talking here about ,us, humans understanding the code and it's intent. 'My IDE doesn't need me to do' that isn't a good enough answer to a language that gets coded in multiple IDEs and many times using Programmers Text Editors like vim, emacs, jedit etc. As a developer who has used and is using multiple IDEs and text editors, it's plain annoying to depend on IDEs to figure things out ( italics, color-coding etc.).
These things are better handled at the language and convention level (you can switch IDEs with less pain). Personally, I like the Ruby way @ for instance variables, @@ for class variables and, yes, UPPERCASE for constants.
Posted by: vivekbp on September 29, 2006 at 09:21 AM
-
I don't see any reason for non-static fields to even exist, given that immutable objects lead to less bugs, i.e., you can throw away an object when you want to change it, and create a new one instead (removing problems with shared objects). So where do you put the data? Let Java create the fields implicitly - use anonymous classes.
I also don't see any reason for non-final static fields to exist, because they are global variables.
So all fields left from this cutting analysis are static and final.
Most finals in Java are not constants, nor are they anything like constants. Consider a simple Complex class ;) (and ignore my rules above):
class Complex
{
final double real;
final double imag;
Complex(double real,double imag)
{
this.real=real;
this.imag=imag;
}
}
Here, real and imag are not anything like constants, because they vary per-instance. Making them uppercase would make them look like constants, and would be confusing.
Similarly:
public static final Image image=new ImageIcon("images/bill.png");
image is not very much like a constant - why name it as IMAGE? Its value is not determined at compile time.
The only time I would use upper case is when I have a constant, e.g.,
public static final int MAX_VALUE=100;
Note that public static final int RANDOM_VALUE=(int)(Math.random()*100); is also misleading, its value is not determined at compile time.
Cheers.
Posted by: ricky_clarkson on September 29, 2006 at 12:00 PM
-
Concerning vivekbp's comments, Ruby's consistency is nice, although it's not pervasive (methods and locals look the same, for instance). Also, just the first char in Ruby matters for constants as in Uppercase. Which also means that Classes and Constants look the same. And that also means that Classes usually are Constants. And they're values, too, so maybe that's okay that they aren't completely distinguished.
Posted by: tompalmer on September 29, 2006 at 03:18 PM
-
I think that getBlah() is the best way to go. I have seen lots of code where constants are used for text. Making these i18n becomes very difficult as you have to re-code.
Encapsulate.
Posted by: rob005 on September 30, 2006 at 05:34 AM
-
vivekbp: I really take issue with the idea that because people might be using a different IDE you should code to the lowest common denominator. This idea keeps dragging coding into the 80's.
On every development project I've been we've standarized on one IDE. Text editors are another matter, but you want something with at least intellisense when coding.
Think about this: we are still living in a era where we have to manually maintain our comments at 80/chars line even though MS Word had this figured out in 1983.
Posted by: firefight on September 30, 2006 at 07:50 AM
-
@toppalmer : You are right about only first Char for a const needs to be uppercase in Ruby. But using all Uppercase will allow to distinguish consts from classnames.
As regards distinguishing locals from method calls, can you show me any language that allows you to do it? Ruby may not do it 100%, but it's handled nicely than in most other languages (I know)
@fireright : There's a huge difference in using IDE features and in depending on them. I didn't mean use LCD available. My objection was to depending on IDE features like italicsfor statics (for e.g.)
I use autocompletion and intelli-sense. They do assist me in coding faster. But at the same time, they've also reduced the number of people who read Javadocs before calling the methods. I find it dangerous that programmers call methods offered by auto-completion without understanding it's pre- and post-conditions. Even if IDE allows you to read javadocs as a tooltip, It isn't the same as reading it in a web-page with white background. Also, Class-level javadocs seldom get read ( which sometimes contain valuable info. regarding methods too).
On auto-imports, well, Eclipse once imported a JSF class into my Swing Code.I typed Radio and it got me RadioRenderer, I deleted the wrong class, but the import remained and was hidden by folding, until another developer got a compilation error in Ant compilation.
98% of Eclipse warnings (which now stand at 1000s) are due to friendly Import-on-copy feature, which doesn't delete them if class references get deleted later. ( Yes, this can be fixed by 'Order Imports'. I know that. But needs developer to do this extra-step - voluntarily - everytime before Check-in). My point - friendly features sometimes tend to be painful too.
Yes, even in my projects also IDE is standardized per project. But I am concurrently working on 3 different projects. One uses NetBeans, second uses IRAD(Eclipse)/Websphere 6.0, third one is on WebLogic 8.0/Weblogic Workshop 8.0 ( custom BEA IDE). To make it more poignant we have a home-grown library which we use in all three projects.
I use TextEditors like JEdit, TextPad etc. for quick-fixes ( instead of waiting 10 minutes for the IDE to launch). Again, I use different editors - not because I like to use many - but they differ in features. Some do certain tasks better than others.
Posted by: vivekbp on September 30, 2006 at 10:43 AM
-
I agree with you in principle, but this convention is so firmly established now that I think we're stuck with it. It's better to stick with the anachronism of uppercase constants just for the sake of consistency.
Posted by: quelgar on October 05, 2006 at 09:49 PM
-
There will always be inconsistencies across APIs like naming conventions and such. But the language, libraries, and conventions should evolve. Personally i abandoned uppercase in my libraries.
Maybe Java needs a macro system like C had, in order to support both backwards compatibility and evolution, which includes fixing bugs, since that can break backwards compatibility too.
Posted by: evanx on October 06, 2006 at 03:04 AM
|