Why can't you create a 1 statement function without curly braces? - java

So, in most programming language, if you are using a loop or an if, you can do it without curly braces if there is only a single statement in it, example:
if (true)
//Single statement;
for (int i = 0; i < 10; i++)
//Single Statement
while (true)
//Single statement
However, it doesn't work for functions, example:
void myFunction()
//Single Statement
So, my question, why doesn't it work for functions?

C++ needs it to disambiguate some constructs:
void Foo::bar() const int i = 5;
Now does the const belong to bar or i ?

Because language grammar forbids you to do that.
The Java grammar defines a method as following:
MethodDeclaration:
MethodHeader MethodBody
Methodbody as:
MethodBody:
Block
;
Which means either a Block (see below) or a single semicolon
Block:
{ BlockStatementsopt }
And a block as one or more statements within curly brackets.
However an if is defined as:
IfThenStatement:
if ( Expression ) Statement
Where no block is needed after the closing ) and therefore a single line is ok.
Why they chose to define it that way? One can only guess.
Grammar can be found here: http://docs.oracle.com/javase/specs/jls/se7/html/index.html

This is not a rule, in some languages you can (Python? Yes, I know that's really contrived example :)) ), in other you cannot.
You could very well extend your question for example to class and namespaces, for example, why not:
namespace Example
class Foo : public Bar
public: std::string myMethod()
return "Oh noes!";
right? At each level, that's just a single item, so why not skip the braces everywhere?
The answer is at the same time simple and complex.
In simple terms, it's about readability. Remember that you can layout your code as you like, since whitespaces are usually discarded by the compiler:
namespace Example class Foo : public Bar public: std::string myMethod() return "Oh noes!";
Well, that starts looking unreadable. Notice that if you add the braces back
namespace Example { class Foo : public Bar { public: std::string myMethod() {return "Oh noes!";}}}
then it, strangely, becomes somewhat comprehensible.
The actual problem is not readability (who cares anyways? I'm joking of course) but in the latter: comprehension. Not only you must be able to comprehend the code - the compiler must. And for the compiler there is no such thing as "oh, this looks like function". The compiler must be absolutely sure that it is a function. Also, it must be completely sure about where it starts, where it ends, and so on. And it must do that without looking at whitespaces too much, since C-family languages allow you to do add them in any quantities you like.
So, let's look again at the packed-up no-braces example
namespace Example class Foo : public Bar public : std::string myMethod() return "Oh noes!";
^ ^ ^^
I've marked some problematic symbols. Assuming you could define a grammar that handles it, please note how the meaning of ":" character changes. At one time it's denoting that you're specifying inheritance, at other point it's specifying access modifier to a method, at third place it's just namespace qualifier. Ok, the third one could be discarded if you were smart and noticed it's actually '::' symbol, not just a ':' character.
Also, meaning of keywords can change:
namespace Example class Foo : public Bar public : std::string myMethod() return "Oh noes!";
^^^^^^ ^^^^^^
At first place, it defines access modifier for inherited base class, at second place it defined access modifier for a method. What's more, at first place it's not meant to be followed by a ":" and at second place it's required to be followed by it!
So many rules, exceptions and corner cases, and we covered just 2 simple things: public and ':'. Now, imagine you are to specify the grammar for the whole language. You describe everything in the way you'd like to have. But, when you gather all the rules together, they at some point may start overlap and collide with each other. After adding Nth rule, it may happen that your 'compiler' would be unable to tell whether the 'public' actually marks inheritance, or starts a method:
namespace Example class Foo : public ::Bar public : std::string myMethod() return "Oh noes!";
^^^^^^^^ ^^^^^^^^
Note that I only changed the Bar to ::Bar. I only added a namespace qualifier, and now our rule of "public is followed by a colon" is trashed. As I now added a rule that "base class names may have namespace qualifiers", I also must add more rules to cover yet another corner cases - to remove the ambiguity of the meaning of "public" and ":" in this place.
To cut the long talk: the more rules, the more problem you have. The "compiler" grows, gets slower, eats more resources to work. This results in inability to handle large code files, or in frustration when the user must wait oh-so-long for that module to compile.
But what's worse for the user is, the more complex or ambiguous, the worse error messages are. Noone wants to use a compiler that is unable to parse some code and also unable to tell you what's wrong with it.
Remember in C++ what happens when you forget some ';' in a .h file? Or when you forget some }? Compiler reports you an error 30 or 300 lines farther. This is because the ';' and '{}' can be ommitted in many places, and for that 30 or 300 lines, the compiler simply does not yet know that's something wrong! Were the braces required everywhere, the point of error could be pinpointed faster.
The other way: making them optional at namespace, class, or function level, would remove the basic block-starts/block-ends markers and, at least:
could make the grammar ambiguous (and hence force to add more rules)
could hurt detecting (and reporting!) errors
any part of which noone really wants.
The C++ grammar is so complex, that it actually might be not possible to omit the braces at those places at all. For Java or plain C, I think it could be possible to make a grammar/compiler that would not require them, but would it would still hurt error reporting much. Especially in C which allows to use #include and macros. In early Java, the impact might be lesser, as the grammar is relatively simple, compared i.e. to current C++..
Probably the simplest, fastest, easiest to implement, and probably easiest to learn grammar would .. require braces (or any other delimiters) just about everywhere. Check LISP for example. But then, large part of your work would consist of constantly writing the same required markers, which many language-users simply does not like (i.e. I get nauseous when I need to work on some old code in VisualBasic with its "if then end if" yuck)
Now, if you look at brace-less language like Python - how does they solve it? They denote the block-starts/block-ends by .. intendation. In this language you must indent your code properly. If you don't indent it correctly, it will not compile at all, or it the loops/functions/etc will silently get their code messed up, because the compiler will not know what part does belong to which scope. No free lunch here again.

Basically a method(function) is a collection of statements that are grouped together to perform an operation. We group the statements for reusable. That is if you know that a set of instructions will used often in that case we create it as a separate function.
If you can perform the task in a single line of code, then why do you need to write a function?

Because the grammar of the language doesn't allow you to.
Here is the grammar for a function in C taken from the ISO/IEC 9899-1999 specification:
6.9.1 Function definitions
Syntax
1 function-definition:
declaration-specifiers declarator declaration-listopt compound-statement
The compound-statement part is the body of a function, and a compound statement is declared as
compound-statement:
{ block-item-listopt }
i.e. it starts and ends with braces.
An if, while or similar body can have a statement as its body.
(6.8.5) iteration-statement:
while ( expression ) statement
A statement can be one of several constructs.
statement:
labeled-statement
compound-statement
expression-statement
selection-statement
iteration-statement
jump-statement
of which only compound-statement requires the braces.

In c++ you need a compound statement to make a function body - which is actually surrounded with curly barces. It does not mean you need to have curly braces right immediately, following will compile just fine:
int foobar()
try {
return 1;
}
catch (...){return 0;}

You can't precisely say there are no one statement functions in C#. Anonymous methods could be one of them. Without single line statements we could not have Lambda expression in c#. The C# 3.0 wouldn't be exist.

There is no reason to add that extra parsing code in the compiler because the functionality is really useless, how many one line methods have you written that are not accessors or mutators? This has been dealt with in C# via properties but not yet in Java.
So the reason is, it's unlikely to be used considering most developers discourage leaving out optional bracket blocks anyway.

Related

Why variable names in Java cannot have same names as keywords?

In most programing languages that I know you cannot declare a variable with name that is also a key word.
For example in Java:
public class SomeClass
{
Class<?> clazz = Integer.class; // OK.
Class<?> class = Integer.class; // Compilation error.
}
But it's very easy to figure out what is what. Humans reading it will not confuse variable name with class declaration and compiler will most likely not confuse it too.
Same thing about variable names like 'for', 'extends', 'goto' or anything from Java key words if we are talking about Java programming language.
What is the reason that we have this limitation?
What is the reason that we have this limitation?
There are two reasons in general:
As you identified in your Question: it would be extremely confusing for the human reader. And a programming language that is confusing by design is not going to get significant traction as a practical programming language.
If identifiers can be the same as keywords, it makes it much more difficult to write a formal grammar for the language. (Certainly, a grammar like that with the rules for disambiguation cannot be expressed in BNF / EBNF or similar.) That means that writing a parser for such a language would be a lot more complicated.
Anyhow, while neither of these reasons is a total "show stopper", they would be sufficient to cause most people attempting a new programming language design / implementation to reject the idea.
And that of course is the real reason that you (almost) never see languages where keywords can be used as identifiers. Programming language designers nearly always reject the idea ...
(In the case of Java, there was a conscious effort to make the syntax accessible to people used to the C language. C doesn't support this. That would have been a 3rd reason ... if they were looking for one.)
There is one interesting (semi-) counter example in a mainstream programming language. In early versions of FORTRAN, spaces in identifiers were not significant. Thus
I J = 1
and
IJ = 1
meant the same thing. That is cool (depending on your "taste" ...). But compare these two:
DO 20 I = 10, 1, -2
versus
DO 20 I = 10
One is an assignment, but the other one is a "DO loop" statement. As a reader, would you notice this?
It allows the lexer to classify symbols without having to disambiguate context - this in turn allows the language to be parsed according to grammar rules without needing knowledge about other ("higher") parts of the compilation process, including analysis of types.
As an example of complications (and ambiguity) removing such a distinction adds to parsing, consider the following. Under standard Java rules it declares and assigns a variable - there is no ambiguity of how it will be parsed.
final Foo x = 2; // roughly: <keyword> <identifier> <identifier> = <value>
Now, in a hypothetical language without a strict keyword distinction, imagine the following, where final may be a declared type; there are now two possible readings. The first is when final is not a type and the standard reading exists:
final Foo = 2; // roughly: <keyword> <identifier> ?error? = <value>
But if final was a "final type", then the reading may be:
final Foo = 2; // hypothetical: <identifier> <identifier> = <value>
Which interpretation of the source is correct?
Java makes this question even harder to answer due to separate compilation. Should adding a new "final type" in (or accidentally importing) a namespace now change how the code is parsed? Reporting an unresolved symbol is one thing - changing how the grammar is parsed based on such resolution is another.
These sort of issues are simply bypassed with the clear distinction of reserved words.
Arguably, there could be special productions to change the recognition of keywords dynamically (some languages allow controllable operator precedence), but this is not done in mainstream languages and is most certainly not supported in Java. At the very least it requires additional syntax and adds complexity to the system for not-enough benefit.
The most "clean" approach I've seen to such a problem is in C#, which allows one prefix reserved words and remove special meaning such as class #class { float #int = 2; } - although such should be done rarely, and ick!
Now, some words in Java that are reserved could be "reserved only in context", such as extends. Such is seen in SQL all the time; there are reserved words (eg. OVER) and then words that only have special meaning in a given statement construct (eg. ROW_NUMBER). But it's easier to say reserved is reserved, go pick something else.
Except for a very simple-to-parse language like LISP dialects, which effectively treat every bareword as an identifier, keywords and the distinction from identifiers is very prevalent in language grammars.
You're not quite right there. A key word is a word that has meaning in the syntax of the language, and a reserved word is one that you're not allowed to use as an identifier. In Java mostly they are the same, but 'true' and 'goto' are reserved words and not key words ('true' is a literal and 'goto' is not used).
The main reason to make the key words in a language reserved words is to simplify parsing and avoid ambiguities. For example, what does this mean if return could be a method?
return(1);
In my opinion, Java has taken this too far. There are key words that are only meaningful in a particular context in which there could be no ambiguity. Perhaps there is benefit in avoiding confusion on the part of the reader, but I put it down to customary habit of compiler writers. There are other languages which have far fewer key words and/or reserved words and work just fine.

java just curly braces

I was reading a book and there were a few example with programs that has just curly braces
for example
public static void main(String args[]){
//what is the uses of curly braces here.
{
//some code
}
}
It's a code block. The variables declared in there are not visible in the upper block (method body outside of these curlies), i.e. they have a more limited scope.
Be careful, it is NOT ALWAYS an initialisation block as others have suggested. In your case it is a variable scoping mechanism called a Code Block or block.
If it is outside of a method, then it is!
Example
public class MyClass {
{
// this is an initialisation block
}
}
However, if it is inside a method, it is NOT!
In this case (which is the case in your example), it is a code block. Anything initialised inside the curly braces is not visible outside
Example
public static void main(String args[]){
{
String myString = "you can't see me!";
}
System.out.println(myString); // this will not compile because myString is not visible.
}
This idea of how to use curly braces as a coding construct is a debated issue in the Java world . There are several explanations people come up with when they see curly braces by themselves. So Im going to try to answer your question from a practical perspective.
The implied question in your post here is, really - when/why are these used ? Practically speaking, the following cases might result in a lone code block :
1) The programmer wanted additionally scoping to reuse variable names without fear of collisions for clarity (i.e. making several objects of the same type in a unit test or database insertion block).
other possible reasons :
2) Forgotten if/else/for/while loop code that is under development.
3) Remaining artifact of a removed if/else/for/while clause.
4) Autogenerated code uses scoping to simplify the creation of several similar components with identical variable names (i.e. consider a gui generator that needed to make code for 100 radio buttons - rather than incrementing variable names per button, it could use scoping).
5) As a tiny, reusable, pastable logical block with minimal side effects : the programmer felt like a block of code in a method was so obscure, its variables and internal side effects should have minimal visibility to the outside world. That is, the programmer has used a code block as a poor-man's anonymous lambda function (albeit, one without a return value). In this pattern one might do something akin to the below :
//lets say I want to make a primary key for a dogs name in a database.
String dogNameKey=null;
{
long time = System.currentTimeInMilliseconds();
String theName = "spot";
dogName=theName+"_"+time;
}
Clearly, the simple strategy for naming this record (dogNameKey) is not worthy of an external method - its too simple. But at the same time, the "time" variable should have no bearing or accessibility outside the logic for making this name up - i.e. it shouldn't even be relevant to the method which contains this tiny key generating block. So, by using braces, I've scoped it out . If a labmda were possible, than all of this scoping could be wrapped in a single, anonymous function.
Now - I could paste several of these blocks, and the variable names would be identical, so it would be easy to scan them by eye.
*Thus, when you see curly braces by themselves - they usually are pretty important - either they implement a specific custom-scoping, or they are an artifact of an error or potentially of autogenerated code. Scoping can also be used to "start" the refactoring of a method without actually writing a new method, by separating out its independant parts ... although IDEs are much better at this than humans. *
You can logically separate your code by this in some cases, and in fact there's one use case I apply very often: demo data. E.g., you have some demo data generation class that creates demo data entries and inserts into your database. You place each single item in such a block, and can do copy-paste without changing variable names.
It is called Block
A block is a sequence of statements, local class declarations and local variable declaration statements within braces.
Also See:
Documents

How to fix the following PMD violations

I am using PMD to analyze code and it produces a few high priority warnings which I do not know how to fix.
1) Avoid if(x!=y)..; else...; But what should I do if I need this logic? That is, I do need to check if x!=y? How can I refactor it?
2) Use explicit scoping instead of the default package private level. But the class is indeed used only within the package. What access modifier should I use?
3) Parameter is not assigned and could be declared final. Should I add final keyword to all the places which PMD pointed out with this warning?
Avoid negation: Instead of if( x!=y ) doThis() else doThat(), check for the positive case first, because people/humans tend to like positive things more than negative. It twists the brain to have to reverse the logic in mind when reading the source code. So instead, write:
if ( x!=y ) doThis() else doThat() // Bad - negation first
if ( x==y ) doThat() else doThis() // Good - positive first
Explicit scoping: According to PMD website, it's a controversial rule. You may hate it, someone else likes it. What you should do is make all the fields within your classes private. There seems to be a field or method (not a class) with a package visibility, e.g. something like this:
class Foo {
/* private missing */ Object bar;
}
Final parameters: Method parameters should be final to avoid accidental reassignment. That's just a good practice. If you're using Eclipse, the content assist even provides a quickfix called "Change modifiers to final where possible". Just select all code in the editor with Ctrl-a and then press Ctrl-1.
You don't need to enable all rules. Choose some of the rules you agree to and refactor your code until all warnings are cleared.
1 - Refactor it to a if (x == y) ... else ... logic. Just avoid negative conditions in if statments, they make code harder to understand
2 - I wouldn't enable that rule.
3 - A lot of people declare a lot of fields and variables final. Especially when they want to make sure or express that the value of a variable shall not be changed in the method. If you don't like that, disable that rule.
These all seem like minor warnings that could be turned off.
1) It wants you to flip the logic
if(x==y) {
//old else clause
} else {
//old if clause
}
2) If package is really the correct access you want, there is no access modifier to add. I am not familiar enough to know if there is a way to suppress that specific warning.
3) A style issue. Some people want final on everything it could be on. Others thinks it adds too much clutter for to little information. If you are in the latter camp, turn that warning off.
Regarding the first item (the inequality) there are two issues:
1) Readability of double negation.
Say you have:
if(x!=y) { false clause } else { true clause }
The second clause is executed if "not x is not equal to y".
This can be rewritten as:
if (x==y) {true clause } else {false clause}.
2) Correctness: if x and y are not-primitives, using if(!x.equals(y)) is safer.
This is the equivalent of using == instead of .equals() and can lead to very serious bugs.
You can also use // NOPMD at the end of any line where you don't want PMD rules to be checked.
For example for the above given code you can suppress PMD check by giving,
class Foo {
/* private missing */ Object bar; // NOPMD
}
Please be aware that the above comment may silently suppress other warnings in the same line.

Why does java/javascript/python force the use of () after a method name, even if it takes no arguments?

One of my most common bugs is that I can never remember whether something is a method or a property, so I'm constantly adding or removing parentheses.
So I was wondering if there was good logic behind making the difference between calling on an object's properties and methods explicit.
Obviously, it allows you to have properties and methods that share the same name, but I don't think that comes up much.
The only big benefit I can come up with is readability. Sometimes you might want to know whether something is a method or a property while you're looking at code, but I'm having trouble coming up with specific examples when that would be really helpful. But I am a n00b, so I probably just haven't encountered such a situation yet. I'd appreciate examples of such a situation.
Also, are there other languages where the difference isn't explicit?
Anyways, if you could answer, it will help me be less annoyed every time I make this mistake ^-^.
UPDATE:
Thanks everyone for the awesome answers so far! I only have about a week's worth of js, and 1 day of python, so I had no idea you could reference functions without calling them. That's awesome. I have a little more experience with java, so that's where I was mostly coming from... can anyone come up with an equally compelling argument for that to be the case in java, where you can't reference functions? Aside from it being a very explicit language, with all the benefits that entails :).
All modern languages require this because referencing a function and calling a function are separate actions.
For example,
def func():
print "hello"
return 10
a = func
a()
Clearly, a = func and a = func() have very different meanings.
Ruby--the most likely language you're thinking of in contrast--doesn't require the parentheses; it can do this because it doesn't support taking references to functions.
In languages like Python and JavaScript, functions are first–class objects. This means that you can pass functions around, just like you can pass around any other value. The parentheses after the function name (the () in myfunc()) actually constitute an operator, just like + or *. Instead of meaning "add this number to another number" (in the case of +), () means "execute the preceding function". This is necessary because it is possible to use a function without executing it. For example, you may wish to compare it to another function using ==, or you may wish to pass it into another function, such as in this JavaScript example:
function alertSomething(message) {
alert(message);
}
function myOtherFunction(someFunction, someArg) {
someFunction(someArg);
}
// here we are using the alertSomething function without calling it directly
myOtherFunction(alertSomething, "Hello, araneae!");
In short: it is important to be able to refer to a function without calling it — this is why the distinction is necessary.
At least in JS, its because you can pass functions around.
var func = new Function();
you can then so something like
var f = func
f()
so 'f' and 'func' are references to the function, and f() or func() is the invocation of the function.
which is not the same as
var val = f();
which assigns the result of the invocation to a var.
For Java, you cannot pass functions around, at least like you can in JS, so there is no reason the language needs to require a () to invoke a method. But it is what it is.
I can't speak at all for python.
But the main point is different languages might have reasons why syntax may be necessary, and sometimes syntax is just syntax.
I think you answered it yourself:
One of my most common bugs is that I can never remember whether something is a method or a property, so I'm constantly adding or removing parentheses.
Consider the following:
if (colorOfTheSky == 'blue')
vs:
if (colorOfTheSky() == 'blue')
We can tell just by looking that the first checks for a variable called colorOfTheSky, and we want to know if its value is blue. In the second, we know that colorOfTheSky() calls a function (method) and we want to know if its return value is blue.
If we didn't have this distinction it would be extremely ambiguous in situations like this.
To answer your last question, I don't know of any languages that don't have this distinction.
Also, you probably have a design problem if you can't tell the difference between your methods and your properties; as another answer points out, methods and properties have different roles to play. Furthermore it is good practice for your method names to be actions, e.g. getPageTitle, getUserId, etc., and for your properties to be nouns, e.g., pageTitle, userId. These should be easily decipherable in your code for both you and anyone who comes along later and reads your code.
If you're having troubles, distinguishing between your properties and methods, you're probably not naming them very well.
In general, your methods should have a verb in them: i.e. write, print, echo, open, close, get, set, and property names should be nouns or adjectives: name, color, filled, loaded.
It's very important to use meaningful method and property names, without it, you'll find that you'll have difficulty reading your own code.
In Java, I can think of two reasons why the () is required:
1) Java had a specific design goal to have a "C/C++ like" syntax, to make it easy for C and C++ programmers to learn the language. Both C and C++ require the parentheses.
2) The Java syntax specifically requires the parentheses to disambiguate a reference to an attribute or local from a call to a method. This is because method names and attribute / local names are declared in different namespaces. So the following is legal Java:
public class SomeClass {
private int name;
private int name() { ... }
...
int norm = name; // this one
}
If the () was not required for a method call, the compiler would not be able to tell if the labeled statement ("this one") was assigning the value of the name attribute or the result of calling the name() method.
The difference isn't always explicit in VBA. This is a call to a Sub (i.e. a method with no return value) which takes no parameters (all examples are from Excel):
Worksheets("Sheet1").UsedRange.Columns.AutoFit
whereas this is accessing an attribute then passing it as a parameter:
MsgBox Application.Creator
As in the previous example, parentheses are also optional around parameters if there is no need to deal with the return value:
Application.Goto Worksheets("Sheet2").Range("A1")
but are needed if the return value is used:
iRows = Len("hello world")
Because referencing and calling a method are two different things. Consider X.method being the method of class X and x being an instance of X, so x.method == 'blue' would'nt ever be able to be true because methods are not strings.
You can try this: print a method of an object:
>>> class X(object):
... def a(self):
... print 'a'
...
>>> x=X()
>>> print x.a
<bound method X.a of <__main__.X object at 0x0235A910>>
Typically properties are accessors, and methods perform some sort of action. Going on this assumption, it's cheap to use a property, expensive to use a method.
Foo.Bar, for example, would indicate to me that it would return a value, like a string, without lots of overhead.
Foo.Bar() (or more likely, Foo.GetBar()), on the other hand, implies needing to retrieve the value for "Bar", perhaps from a database.
Properties and methods have different purposes and different implications, so they should be differentiated in code as well.
By the way, in all languages I know of the difference in syntax is explicit, but behind the scenes properties are often treated as simply special method calls.

Naming convention for a variable that works like a constant

I have a variable that I'm using like a constant (it will never change). I can't declare it as a constant because the value gets added at runtime.
Would you capitalize the variable name to help yourself understand that data's meaning?
Or would you not because this defies convention and make things more confusing?
The larger question:
Do you follow conventions even if the scenario isn't typical of the convention, but close enough that it might help you, personally, to understand things?
If it will aid you (and everybody else) in understanding your code six months down the line, do it. If it won't, don't. It's really that simple.
Personally, I would capitalise it. This is the convention in Java, where constants are always allocated at runtime due to its object-oriented nature. I'd be much more comfortable knowing that if I accidentally assigned to it, I'd definitely notice the next time I scanned through that chunk of code.
I don't consider my personals need to be paramount here -- if I've written the code, I'm already better placed to retrace it in the future if and when that's needed, than anybody else; so it's the "anybody else" I put first and foremost -- a present or future teammate that will need to understand the code (ideally) as thoroughly as I do.
Besides, with mandatory code reviews as a prereq to committing ANYthing to the codebase (an excellent practice, and the unfailing rule at my present employer), I'm likely to be called up on it should I ever let my attention slip (it does happen -- which is why I LOVE those mandatory code reviews, as applied to myself as well as everybody else!-).
A "variable set only once at startup" is a special-enough case that may be worth adding to your team's guidelines -- treating it as "closer to a constant than a variable" may make a lot of sense, but that only helps if the same rule/guideline is used consistently across the codebase. If the rule is not there I would check if there's consensus about adding it; otherwise, I would NOT break the guidelines for the sake of my personal tastes... that's the root of "egoless programming" and "team ownership of the codebase", two principles I serve with burning ardor.
BTW, were I on a single-person team in terms of coding guidelines (it happens, though it's not an optimal situation;), I think I'd have no trouble gaining unanimous consensus by myself that treating "set-once at startup" variables as constants in terms of naming conventions!-). But with a larger team, that's more work, and it could go either way.
Encapsulate it.
#include <iostream>
class ParamFoo
{
public:
static void initializeAtStartup(double x);
static double getFoo();
private:
static double foo_;
};
double ParamFoo::foo_;
void ParamFoo::initializeAtStartup(double x)
{
foo_ = x;
}
double ParamFoo::getFoo()
{
return foo_;
}
int main(void)
{
ParamFoo::initializeAtStartup(0.4);
std::cout << ParamFoo::getFoo() << std::endl;
}
This should make it pretty clear that you shouldn't be setting this value anywhere else but at the startup of the application. If you want added protection, you can add some private guard boolean variable to throw an exception if initializeAtStartup is called more than once.
I would name it as a variable, I prefer to keep my naming very consistent.
As Rob already suggested, what about readonly (available in C# at least).
Or a property with no setter.
My immediate impression is that something that you "set at runtime, then never change" is a constant, only so far as the business rules are constant. Also, you should be using mutators/accessors, since using ALL CAPS can hardly guarantee "constness".
public class BadClass
{
public static final double PI = 3.1;
// PI is very constant. Not according to the business roles modeled by my
// application, but by nature. I don't have a problem making this publicly
// accessible--except that [Math] already does, with much better precision)
public static /*final*/ int FOO = null;
// FOO is constant only by convention. I cannot even enforce its "constness".
// Making it public means that my enemies (overtime, for example) can change
// the value (late night programming), without telling me.
}
Instead,
public class BetterClass
{
public static final double PI = 3.1;
private /*final*/ Integer foo = null;
public int getFoo() {
return this.foo.intValue();
}
public void setFoo(int value) {
// The business rules say that foo can be set only once.
// If the business rules change, we can remove this condition
// without breaking old code.
if ( null == this.foo ) {
this.foo = value;
} else {
throw new IllegalStateException("Foo can be set only once.");
}
}
}
If you always use the mutator to set the value, even within [BetterClass] itself, you know that the foo's "constness" will not be violated. Of course, if someone is going to set the value of foo directly (I need to quit working before 2:00 am!), there are still no guarantees. But something like that should be pointed out at code review.
So my recommendation is to treat foo as a normal member variable--there doesn't need to be a special naming convention for something that is almost const.
However, use mutators/accessors, even on private variables. These are typically very fast, and you can enforce business rules inside of them. This should be you convention.
(If you are writing code for embedded medical devices, pretend that you never saw this posting).
is it possible to mark it as readonly? Then conventions are not as important.
Do you follow conventions even if the
scenario isn't typical of the
convention, but close enough that it
might help you, personally, to
understand things?
Following a convention when the scenario is atypical might confuse or slow down others (or even you, after a while.) I would avoid giving a variable the guise of something that it isn't.
Also, the fact that you have this atypical scenario could be an indication that perhaps some other, more typical paradigm could be followed. Though, I don't have any immediate suggestions for a alternative.
I would make it capitalized (since it's more constant than variable from a design perspective) and add a comment around it stating its uniqueness to the application.
FWIW my own convention is to use all caps for #defines and for enums. For const variables I either use no particular convention, or when I do it's to prefix the name with a 'k' (for 'konstant' - not 'c' which is already over used for things like 'count' or 'char').
I'm finding that I like the 'k' convention and will probably use it more often, and may even use it for enums, reserving the screaming, all-caps identifiers for the dreaded preprocessor macros.
Conventions are just that, conventions. They are there to help the code understandable. They usually do if they are not too badly chosen and if they are applied consistently. The last point is probably the most important thing about them: they should be applied consistently.
One thing which prevent some conventions to make code more readable even when they are applied consistently -- at least for new comers and people switching between code base -- is when they are conflicting with other conventions. In C and C++, I'm aware of two common conventions about the use of names in ALL_CAPS:
reserve them for the preprocessor; that one has my preference as the preprocessor identifier are special: they don't obey usual scoping rule and preventing clashes with them is important
use them for constant (macro and enumerators).
Two problems comes in addition to the unfamiliarity if you use them for logically constant things which are in fact variable:
they aren't usable in places (like array size) where the language expect constant expression
my experience teach me that maintenance will tend to make them even less constant that they are now.
Create a wrapper class with a single private static field. Create an initField(..) and a getField(..) static method. initField throws/asserts/otherwise errors if the static field is not null. (For primitives, you may have to use a primitive and a boolean to track initialization.)
In java, I prefer to pass these types of variables in as system properties. A static class can then do something like:
public final int MY_INT = Integer.getInteger("a.property.name");
You could also use a property file (see java.util.Properties) instead of using -D to specify it. Then you get:
public class Foo {
public static final int MY_INT;
static {
Properties p = new Properties();
try{
p.load( new FileInputStream("app.props"):
} catch(IOException e) {
//SWALLOW or RETHROW AS ERROR
}
MY_INT=Integer.parseInt( p.getProperty("my.int","17") ); //17 is default if you swallo IOException
}
...
}
First of all, follow your project's coding standards. You should be coding for other people reading the code, not yourself. Your personal preferences should not take precedence over project-wide rules and conventions, etc.
In the absence of a project coding standard you should follow "best practice" for the language you are dealing with.
In Java, best practice is that you should declare a pseudo-constant with a camel case identifier. That's what the Sun Java coding standard says, and that is what the vast majority of professional Java developers use.
In C and C++ the (classical) convention is that all-caps is used for constants defined as preprocessor symbols. So since this is not a preprocessor symbol, you should use whatever your coding standard says is appropriate for a variable.
The fact that the pseudo-constant is not supposed to change won't stop someone from modifying the code so that it actually changes, accidentally or deliberately. If you use / abuse a coding convention that makes the identifier look like a real constaint, you will be part of the problem:
Someone trying to read / debug your code will first assume the identifier is a real constant and not investigate the possibility thatit is not.
Then when they do lookat the declaration, there will be alot of shouting and threats of
defenestration.
Actually, a better way to deal with a pseudo-constant is to encapsulate it. In Java, you would declare it as private member and provide a getter and setter. The setter should do something to prevent the pseudo-constant from being changed after it has been set the first time. Any decent Java JIT compiler will inline a simple getter, so this should not affect runtime performance.
Giving wrong information is generally not best practise.
Implicitly claiming something is a constant, when it is merely currently not changed, is giving out wrong information.
I'm not sure if this is legal in your language of choice, but in C++, this would work for your purpose:
#include <iostream>
int main()
{
int i = 0;
std::cin >> i;
const int CONST = i;
std::cout << CONST; //displays i
system("PAUSE");
return 0;
}
I'm not sure if this is a moral thing to do, but this does solve your problem (unless you really need your memory).
Just like anything else - scope and context are required to know in what way something is constant. So - there's no way to to satisfy everyone.
Follow the style used in your language of choice - 80% of the time, that will be clear enough. The alternative is a highly over-though nameing system that sacrifices productivity for ideal technical correctness (which few people will even really appreaciate if you can ever achieve it.)
one question would be: what kind of variable?
in the case of static variables, that don't change after what i'd call "boot-time" for the lack of a better term, i use ALL_CAPS ... same thing for global variables (if the language supports them at all) ...
communicating semantics is actually the point of naming conventions, and seeing an ALL_CAPS clearly states, that a) i will not write to it b) i can cache it (to a local variable for example, or in AS3 even an instance variable makes sense, since static access is very slow) ...
whether it's a "real constant" or not does not really matter ... that's more of an implementation detail, that should be hidden away (reliably! information hiding is good, and important, but it is crucial, that the information that is shared, can be trusted!) ... it can really be exchanged ... for example, i often start building apps vs. some hardcoded config, containing some static constants ... later, i decide that i don't want this to be hardcoded, but rather coming from some config file, so i load it, and during boot process, i init all the pseudo-constants ... the actuall app still treats them as constants, because after booting, that is what these values are ... this seems perfectly valid to me ...
at instance level, i am not 100% sure, if i ever ran into a case, where i could be very certain, that some field would never change ... usually, this makes the class unflexible ...
other than that, you can usually declare readonly properties, to have compile time errors, which is also a good thing to have ...

Categories

Resources