This question is a result of the answers to this question that I just asked.
It was claimed that this code is "ugly" because it initializes a variable to a value that will never be read:
String tempName = null;
try{
tempName = buildFileName();
}
catch(Exception e){
...
System.exit(1);
}
FILE_NAME = tempName;
Is this indeed bad practice? Should one avoid initializing variables to dummy values that will never actually be used?
(EDIT -
And what about initializing a String variable to "" before a loop that will concatenate values to the String...? Or is this in a separate category?
e.g.
String whatever = "";
for(String str : someCollection){
whatever += str;
}
)
I think there's no point in initializing variables to values that won't be used unless required by the language.
For example, in C#, the default value for a declared string variable is null, so you're not even gaining anything by explicitly writing it out. It's mostly a style choice, but since strings are immutable, initializing it to something else would actually allocate an extra string in memory that you'd just throw away anyway. Other languages may impose other considerations.
Regarding the string loop, if you change it to a StringBuilder instead you don't even have to think about it.
Edit: removed bits better answered by others.
As a practice, I tend to avoid setting variables to arbitrary values, and instead initialize them to a default value.
i.e.
int x = 0;
string name = "";
bool done = false;
Person randomGuy = null; //or = new Person();
I like this method best because it brings a sense of uniformity to your code while not forcing the next guy that comes along to deal with stuff like: string name = "luke skywalker";
This is all more of a personal preference, so it will vary between programmers.
At the very lest, you should be following the standards that your project as set. You'll have an idea of how the legacy code handles these things, and it's probably best to conform to that so the overall coding style is the same throughout the system.
It depends on the compiler. C# compiler requires that the variable be initialized before using. But the CLR does not have this requirement. At run time the CLR verifies if the variable is initialized or no. If not it will throw a nullreference exception.
In my opinion, it might be more accurate to refer to it as a "code smell" - in the Martin Fowler sense of the word.
I don't think you can change your default initialisation in isolation - it would need to be made in conjunction with other refactoring methods. It is also assuming that you have refactored your code so that you don't need temp variables:
try{
FILE_NAME = buildFileName();
//Do other stuff with file name
}
catch(Exception e){
...
System.exit(1);
}
It also then makes the assumtion that this code segment is only code in the method in which it is contained - i.e. the method only does one thing
When I'm coding I would be concerned that I am using dummy values with temp variables but I would only change when I am finished coding that section and it solves the problem as intended - and only in conjunction with other refactoring steps.
Related
There are some ways to fulfill a null-checking in Kotlin:
1.
if(myVar != null) {
foo(myVar)
}
2.
myVar?.let {
foo(it)
}
3.
myVar?.run {
foo(this)
}
What are the difference between these ways?
Are there any reasons (performance, best practice, code style etc.) why I should prefer on way over the other?
!! is to tell the compiler that I am sure the value of the variable is not null, and if it is null throw a null pointer exception (NPE) where as ?. is to tell the compiler that I am not sure if the value of the variable is null or not, if it is null do not throw any null pointer.
Another way of using a nullable property is safe call operator ?.
This calls the method if the property is not null or returns null if that property is null without throwing an NPE (null pointer exception).
nullableVariable?.someMethodCall()
All three code are behave same null check in operation-wise.
?. is used for chain operations.
bob?.department?.head?.name // if any of the properties in it is null it returns null
To perform a chain operation only for non-null values, you can use the safe call operator together with let
myVar?.let {
foo(it)
}
the above code is good for code style and performance
more details refer Null Safety
The ways 2 and 3 are more idiomatic for Kotlin. Both functions are quite similar. There is little difference with argument passing.
For example, we have a nullable variable:
var canBeNull: String? = null
When you working with T.run you work with extension function calling and you pass this in the closure.
canBeNull?.run {
println(length) // `this` could be omitted
}
When you call T.let you can use it like lambda argument it.
canBeNull?.let {
myString -> println(myString.length) // You could convert `it` to some other name
}
A good article about Kotlin standard functions.
All three are roughly equivalent.
The if case is more like most other languages, and so many developers may find it easier to read.
However, one difference is that the if case will read the value of myVar twice: once for the check, and again when passing it to foo(). That makes a difference, because if myVar is a property (i.e. something that could potentially be changed by another thread), then the compiler will warn that it could have been set to null after the check. If that's a problem (e.g. because foo() expects a non-null parameter), then you'll need to use one of the other cases.
For that reason, the let case has become fairly common practice in Kotlin. (The run case does just about the same thing, but for some reason isn't as popular for this sort of thing. I don't know why.)
Another way around it is to assign myVar to a temporary value, test that, and then use that. That's also more like other languages, but it's more verbose; many people prefer the conciseness of the let case — especially when myVar is actually a complicated expression.
The examples in your question don't show the true reason to decide.
First of all, since you're not using the return value of foo, you should use neither let nor run. Your choice is between also and apply.
Second, since you already have the result you want to null-check in a variable, the difference fades. This is a better motivating example:
complexCall(calculateArg1(), calculateArg2())?.also {
results.add(it)
}
as opposed to
val result = complexCall(calculateArg1(), calculateArg2())
if (result != null) {
results.add(result)
}
The second example declares an identifier, result, which is now available to the rest of the lexical scope, even though you're done with it in just one line.
The first example, on the other hand, keeps everything self-contained and when you go on reading the rest of the code, you are 100% confident that you don't have to keep in mind the meaning of result.
Kotlin have new features with NullPoint-Exception as Compare to Java.
Basically When we do Coding in Java , then we have to Check with !! in every Flied.
But in Kotlin, it is Easy way to Implement First
as Like,
Suppose, in Kotlin
var response:Json?=Null
response:Json?.let {
this part will handle automatic if response is Not Null....then this Block start Executing }?.run {
This is Nullable But, where we Can put Warring } So, I am Suggest you Guys to Start Work in Kotlin with this Features Provided by Kotlin.
(Flied)?.let { Not Null Value Comes Under }?.run{ Null Value Code }
This will Handle to NullPoint Exception or Protect You App for Crash
What you want to achieve
What you want to achieve is that the Kotlin compiler does a smart cast on the variable you are working with.
In all of your three examples, the compiler can do that.
Example:
if(myVar != null) {
foo(myVar) // smart cast: the compiler knows, that myVar can never be null here
}
The choice
Which one of the options to use, is really a matter of style. What you should not do is mix it up to often. Use one and stick to it.
You don't need to worry about performance since let and run are inlined (see inline function). This means that their code (body) is copied to the call site at compile time so there is no runtime overhead.
For example:
... some code
int sizeOfSomeObject = someObject.length();
... some code, sizeOfSomeObject is not need anymore
now I need other int variable for other action(for example, for position in some object), and i have the dilemma: create a new variable or use sizeOfSomeObject for this. In the first case I will keep readability, but lose performance. In the second case - on the contrary. What usually do programmers in this situation?
In the first case I will keep readability, but lose performance. In the second case - on the contrary.
So did you benchmark it? I suspect no, you didn't. Most modern compilers do a lot of agressive analysis during register allocation, so if the optimizer perceives that there's a variable that's not used anymore, but there's a new variable of the same type, it will just merge the two variables to the same memory region or processor register. No need to worry about performance penalties.
And anyway, don't do premature optimization (which this is). In 90% of the cases, readability is more important than "performance".
All in all, go ahead and create a new variable with an appropriate, different, descriptive name. And just for fun, compile this version and the version in which you used the same variable name, and look at the generated assembly (or bytecode, or...) - and find out that they're identical.
I would use different named variables for different things.
In terms of something like this, I don't think just one variable would cause a massive performance hit. In most languages you have the option to clear variables from memory in some way when they are no longer in use, so I would recommend doing that so that the code means something to you or others when read at a later date.
In C++, you can use blocks for objects to be destroyed as soon as they are not needed anymore:
void some_function () {
{
MyClass c;
// ... here we use c ...
}
// now c has been destroyed
{
MyClass d;
// ... here we use d ...
}
// now d has been destroyed
}
In your example (with int variables), there is no reason to worry about performance. The worst thing that could probably happen is memory for two variables being used instead of one, but (i) that's negligible and (ii) int's will probably live in a CPU register, anyway. If you really worry, use the block approach for your int example.
It depends how often such an int would be initialized. If it's not in some hugely nested for loop, most (all) programmers will go for the first. Besides, most modern programming languages have a garbage collector, which cleans up left over objects.
Decent compiler will optimize out your second variable, so that shouldn't be an issue.
That said, there are situations where variable reuse makes sense. E.g., you might have some variable that holds a generic output populated from call to some external API. According to the context and parameters passed to the API you'll process the data differently but it's probably better (more readable etc.) to reuse the same data variable.
For example, something like this:
void* data = getSomeData(params);
//process data
//change params
data = getSomeData(params);
//process data
//change params
data = getSomeData(params);
I often come to this question when coding.
Which of the following examples is a better practice? I am aware that other factors will influence whether one or the other one is better. But in general, what are the advantages of one over the other.
if(object.getA().Value != null) {
return object.getA().Value;
}
return null;
Vs.
string x = string.null;
x = object.getA().Value;
return (x != null) ? x : null;
Here is another similar example:
var a = object.method(x).Value;
var b = object.method(x).Key;
Vs.
var y = object,method(x);
var a = y.Value;
var b = y.Key;
In other words my question is:
Is it better to call a method twice and have one less variable?
or
Is it better to save it into a variable and call the method twice?
Of course if the method results in a lot of processing it might be smart to call it once, but for general cases where the method is not too demanding and the space of the variable is not too big, which one is better and why? or which are the advantages of one or the other?
The difference between them might not make a big difference but I am trying to find better practices and will like to hear the input of some experienced programmers.
Many thanks
Caching the value in a variable is a basic optimization (related to memoizing).
When it becomes truly necessary is if the second call to the function is on the stack a significant percent of the time.
For example, if that second call is on the stack 10% or 20% of the time, then that's how much overall time you can save by caching the first result.
You can keep doing things like that, until the code is as fast as possible.
If I can give an example, ages ago I worked on an app that had code like this:
if (!Done()){
do some stuff
}
....
if (!Done()){
do some other stuff
}
Since Done() was such a short, clean, and simple function to call, it got called a lot.
Never mind that it did a lot including querying a ton of stuff from a DB and throwing most of it away.
Stackshots found the problem instantly.
It depends if you want to be thread safe and if the function could change between calls.
e.g. with
if(object.getA().Value != null) {
return object.getA().Value;
}
return null;
if the implementation of the property getter Value returned a null on the second call you would have a different answer. It could return null on the second call either by implementation of the method or if another thread casused an update between the if and the return statement that made the result of the property null.
This test is actually redundant because you are returning null if it is null. I'm guessing that you meant if (object.getA() != null). Then the previous paragraph still applies but to getA() instead of Value but the if body would throw an null reference exception if getA() returned null on the second call.
So its all down to whether you are worried about the values changing between calls.
General rule: Avoid extra variables (needlessly introduces states).
(Break the rule if calling the function twice adds too much overhead)
Which one of the following do you do:
var = true;
if (...) var = false;
Or
if (...) var = false;
else var = true;
Is there a reason you pick on or the other?
I'm working on the premise that nothing else is happening to var. The next line of code might be something like:
if (var) { ... }
How about var = { ... } directly since it's a boolean?
I prefer the second in Java, doing something like this:
int x;
if (cond) {
x = 1;
} else {
x = 5;
}
because if something is changed later (for example, I turn the else block into an else if), the compiler will tell me that the variable has failed to be initialized, which I might miss if I used your first strategy.
You could also use a ternary operator if your language supports it :)
I would generally only do the first one if there was a chance the IF could fail and the variable must have a default value if it does.
If you set the default, then you reset it again later to something else, although it's a very small amount, its still a waste of resources. So, most of the time, for most of the code, a balanced if/else or even a (?:) syntax, are clearer and more appropriate, except:
Sometimes, if what you doing is building fall-through code (or a decision function), where you start with a specific condition, and then test a whole bunch of other conditions to see if that changes, then you want to definitely set the default first:
int final = 27;
if ( some condition ) final = 86;
if ( another condition ) {
final = 98;
return final;
}
if ( some state ) {
final += 2;
}
return final;
Or something similar to that.
BTW: in your example, if you set 'var', then the next line just tests 'var', you don't really need 'var' do you? If the condition is so ugly that using 'var' helps make it readable, then your probably best to move the condition into it's own function, accepting that the extra function call is there to help readability. In general, you can waste resources, if and only if you get something significant, such as readability, in return.
Paul.
Depends on the context. I would use the second option when it is clear that 'var' needs to be true when IF fails.
I use the first type unless the value to set requires significant computation.
Always the first as many people have said. However it's worth emphasising why, and that's because it makes the program more resistant to future bugs caused by incorrect maintenance.
For example, it's quite common for some additional business condition to arise and a maintenance coder add some extra condition or two inside the if to include more business logic and incorrectly amend the code - for example
if (a==b) {
if (a==c) {
[new logic]
var=false
}
}
else {
var = false
}
On the face of it it looks unlikely, but it happens alarmingly often (in fairness often the situation arises after the original if has got a lot more complex). Putting the initialisation first prevents this.
Do you prefer code that is short and compact, or code that is easier to read?
If you prefer code that is short and compact use
var x = true;
if (...) x = false;
But this can even be "improved". Most languages give initial values, and usually for the boolean type the default is false. So, you could write
var x;
if (...) x = true;
If you prefer code that is easy to read use
if (...) var x = false;
else var x = true;
because it makes your intentions clear.
The performance of both is the same.
Depends on the language. In C++, I would highly recommend setting it to a default as quickly as possible otherwise you risk getting garbage results.
In most other languages, you can be a bit more flexible. In fact, I would argue that it's more readable to explicitly define the conditions than to set a default.
Since the variable is not written to later, for general values I would write the following in Java:
final Type var;
if (cond)
{
var = value1;
}
else
{
var = value2;
}
The Java compiler will catch the error that var is not assigned a value before it is used.
The final keyword expresses the fact that the variable is constant after the conditional.
In your exact case with booleans I would use
final boolean var = !cond;
Using a conditional in this case indicates you are afflicted by "booleanophobia".
In C I would initialize the variable at its declaration.
I generally set the "default" value and use if statements to modify it.
If no default exists then only the if statements.
int timeout = 100;
if (moreTime) timeout = 1000;
int searchOption = null;
if (sometest1) searchOption = 1;
if (sometest2) searchOption = 2;
// then later..
if (searchOption != null)
.....
If the initialization is complex enough that a direct expression can't be cleanly written, I sometimes find it useful to handle this case as
boolean isFoo = determineWhetherFoo(...);
where determineWhetherFoo takes whatever arguments are necessary to make the determination and returns the appropriate boolean result. This makes it very clear what the variable means and what it depends on. Initializing a variable to a possibly-wrong value, followed by a wad of code that may change its value, can sometimes obscure what's being expressed.
Wherever you write an if() also write the else - even if it's empty.
The compiler will optimise it away but it forces you (and any programmers after you) to think about when the if () isn't triggered, what are the consequences?
A colleague of mine refactored this code:
private void btnGeneral_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)e.OriginalSource;
Type type = this.GetType();
Assembly assembly = type.Assembly;
string userControlFullName = String.Format("{0}.{1}", type.Namespace, button.Name);
UserControl userControl = (UserControl)assembly.CreateInstance(userControlFullName);
}
to this code:
private void btnGeneral_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)e.OriginalSource;
Type type = this.GetType();
Assembly assembly = type.Assembly;
UserControl userControl = (UserControl)assembly.CreateInstance(String.Format("{0}.{1}", type.Namespace, button.Name));
}
saying that you don't need to create a variable if it is only going to be used once.
My response was that making once-used variables is good practice since it:
functions as and reduces comments (it is clear what "userControlFullName" is)
makes code easier to read, i.e. more of your code "reads like English"
avoids super-long statements by replacing parts of them with clear variable names
easier to debug since you can mouse over the variable name, and in the cases of e.g. PHP programming without debuggers, it is easier to echo out these variable names to get their values
The arguments against this way "more lines of code", "unnecessary variables" are arguments to make life easier for the compiler but with no significant speed or resource savings.
Can anyone think of any situations in which one should not create once-used variable names?
I'm with your opinion in this case. Readability is key. I'm sure that the compiler produces the same executable in both cases, with the compilers as intelligent as they are today.
But I wouldn't claim "always use once-used variables" either. Example:
String name = "John";
person.setName(name);
is unnecessary, because
person.setName("John");
reads equally well - if not even better. But, of course, not all cases are as clear cut. "Readability" is a subjective term, after all.
All your reasons seem valid to me.
There are occasions where you effectively have to avoid using intermediate variables, where you need a single expression (e.g. for member variable initialization in Java/C#) but introducing an extra variable for clarity is absolutely fine where it's applicable. Obviously don't do it for every argument to every method, but in moderation it can help a lot.
The debugging argument is particularly strong - it's also really nice to be able to step over the lines which "prepare" the arguments to a method, and step straight into the method itself, having seen the arguments easily in the debugger.
Your colleague doesn't seem to be consistent.
The consistent solution looks like this:
private void btnGeneral_Click(object sender, RoutedEventArgs e)
{
UserControl userControl = ((UserControl)type.Assembly).CreateInstance(String.Format("{0}.{1}", this.GetType().Namespace, ((Button)e.OriginalSource).Name));
}
I'm completely with you on this one.
I especially use this if a method takes a lot of booleans, ie
public void OpenDocument(string filename, bool asReadonly, bool copyLocal, bool somethingElse)
To me this is a lot more readable:
bool asReadonly = true;
bool copyLocal = false;
bool somethingElse = true;
OpenDocument("somefile.txt", asReadonly, copyLocal, somethingElse);
..than:
OpenDocument("somefile.txt", true, false, true);
Since the programming languages I use generally do not tell me what was null in an exception stacktrace I generally try to use variables so that no more than one item per line can be null. I actually find this to be the most significant limiter of how many statements I want to put on a single line.
If you get a nullpointerexception in this statement from your production logs you're really in trouble:
getCustomer().getOrders().iterator().next().getItems().iterator().next().getProduct().getName()
Although I agree with your thoughts, adding an extra variable can introduce an extra concept in the method and this concept may not always be relevant to the overall goal of the method. So excessive adding of variables can also increase method complexity and reduce legibility. Note the usage of excessive here.
I guess in some cases where it could have an effect on performance. In particular in this example:
for (int i1 = 0; i1 < BIG_NR; i1++)
{
for (int i2 = 0; i2 < BIG_NR; i2++)
{
for (int i3 = 0; i3 < BIG_NR; i3++)
{
for (int i4 = 0; i4 < BIG_NR; i4++)
{
int amount = a + b;
someVar[i1][i2][i3][i4] = amount;
}
}
}
}
... the extra assignment might have a too big impact on performance.
But in general, your arguments are 100% correct.
The both codes are exactly the same. Of course, yours is more readable, maintenable and debuggable, but, if that was the point of your colleague, his code is NOT memory less consumer.
I think it's a judgement call based on how tidy you want you code to be. I also think that both you and your colleague are correct.
In this instance I would side with you colleague based on the code you presented (for performance reasons), however as I said before it does depend on the context in which it will be used and I think your position is perfectly acceptable.
I would point out that creating variables for once used parameters can be pointless, unless they are const variables or things that you need to use in many places.
I would argue that declaring a once used variable could possible create more confusion when you are debugging if there are lots and lots of these, but one here and there is probably fine.
Creating a new variable means one more concept for the reader to keep track of. (Consider the extreme case: int b=a;c=b;) If a method is so complex - in such need of breaking up - that the extra concept is a price worth paying, then you ought to go the whole hog and split it into two methods. This way you get both the meaningful name and the smaller size. (Smaller for your original method: if it's like you say, then people won't typically need to read the auxiliary method.)
That's a generalisation, particularly in a language with a lot of boilerplate for adding new methods, but you're not going to disagree with the generalisation often enough to make it worth leaving out of your style guide.
I'm completely with your colleague in principle, but not in this case.
The problem with throwaway variables is that they introduce state, and more state means the code is harder to understand since you don't know what effects it could have on the program's flow. Functional programming has no variables at all, exactly for this reason. So the fewer variables there are, the better. Eliminating variables is good.
However, in this particular case, where the method ends right after the variable's only use, the disadvantages of having it are minimal, and the advantages you mention are probably more substantial.
Trying hard to come up with an argument against introducing new variables I'd say that when you read the code (for the first time, at least), you don't know if the variable is being used more than once. So immediately you will let your eyes scan down through the code to see if it is used in more places. The longer the function the more will you have to look to see if you can find it.
Thats's the best argument against that I can come up with! :-)
That's how I used to code. Nowadays I tried to minimize intermediate variables. The use of intermediate variables is perfectly fine if it's immutable.
I'm in agreement with the majority here, code readability is key.
It's a rare line count crusader that actually writes highly readable, highly maintainable code.
Additionally, it all gets compiled to MSIL anyway and the compiler will optimise a lot for you.
In the following example, the compiler will optimise the code anyway:
List<string> someStrings = new List<string>();
for (int i = 0; i < 1000; i++)
{
string localString = string.Format("prefix{0}", i);
someStrings.Add(localString);
}
Rather than:
List<string> someStrings = new List<string>();
string localString = string.Empty;
for (int i = 0; i < 1000; i++)
{
localString = string.Format("prefix{0}", i);
someStrings.Add(localString);
}
So there's really no performance reason not to go with it in many cases.
Agreed
"makes code easier to read, i.e. more of your code "reads like English"
I think this is the most important factor as there is no difference in performance or functionality on most moder managed languages
After all we all know code is harder to read than it is to write.
Karl