Remove temp variable in code with switch-block - variables

Have such code in project:
Cookie CookieCreate(CookiesTypes type)
{
Cookie user_cookie = null;
switch (type)
{
case CookiesTypes.SessionId:
user_cookie = new Cookie("session_id", Convert.ToBase64String(Guid.NewGuid().ToByteArray()));
break;
case CookiesTypes.ClientIp:
HttpListenerContext context = listener.GetContext();
user_cookie = new Cookie("client_ip", context.Request.RemoteEndPoint.ToString());
break;
}
return user_cookie;
}
I understand, that temp variable user_cookie is bad syntax... I've tried to use return in switch-block both in two cases, but I've got an compiler erros, when I tried so:
Pseudo-Code:
case ... :
//some action
return var;

Having a temporary that is set in a case of a switch statement to be returned at the end is not a bad syntax, it is also the only choice if you need to do something on user_cookie for all cases before returning it.
The only problem is see in your code is the lack of a default case which is indeed useful because:
either you can require a default case (so that you do something in that situation)
either the switch should never reach a default case (so you should manage that situation in a special way, for example by throwing an exception)
If you blindly remove temporary variable and return the value directly like you are trying to do, then it gives you a compiler error probably because not all your branches do return something (because you are lacking a default clause or lacking a return after the switch).

Despite the fact that there's nothing inherently wrong with temporary variables, if you really want to avoid it you just need to ensure that all code paths return something.
That means (for example) changing your current return to:
return null;
and having both cases contain:
return new Cookie (whatever);
instead of the assignment.

Related

Using Kotlin's scope functions in not exhaustive with / when

I'm pretty new with Kotlin and I'm trying to figure out Kotlin's scope functions.
My code looks like this:
with(something) {
when {
equals("test") -> var1 = "test123"
startsWith("test2") -> var2 = "test456"
contains("test3") -> myNullableVar?.let { it.var3 = "test789" }
}
}
So before I entered the third check with the .let function my with function does not need to be exhaustive (I'm not returning something, I'm only doing assignments). In my third check I'm using .let as a null-check ... but only for an assignment of it.var3 (if it is not null). I don't need to return anything while I know that Kotlin's .let function returns the result of the body by standard.
Nevertheless now my with/when needs to be exhaustive otherwise it won't compile anymore.
This got me thinking and trying out different things. I found these ways to solve this issue:
I can add an else to my with/when so it becomes exhaustive but actually I don't need an else and I don't want to use it in this case.
I can add another .let, so it looks like this: myNullableVar?.let { it.var3 = "test789" }.let{} .... but this looks kinda hacky to me. Is it supposed to work like this?
Use If(xy==null){...}else{...} stuff but I thought I can solve this with Kotlin differently
Because I'm new with Kotlin I'm not really sure how to handle this case properly. I would probably just go with my second idea because "it works". Or should I don't use .let for null-checks? Add another empty .let{}? Or did I not get the null-safety concept at all? I feel a little bit lost here. Thanks for any help.
This seems to be an unfortunate combination of features…
A when can be non-exhaustive only when it doesn't return a value.  The problem is that the with() function does return a value.  And since the when is at the bottom, its value is what gets returned, so in this case it must be exhaustive.
So why doesn't it insist on an else branch even if you omit the "test3" branch?  That's because assignments don't yield a value.  (They evaluate to Unit, which is Kotlin's special type for functions that don't return a useful value.)  If every branch gives Unit, then Kotlin seems* to be happy to infer a default branch also giving Unit.
But the "test3" branch returns something else — the type of myNullableVar.  So what type does the when infer?  The nearest common supertype of that type and Unit, which is the top type Any?.  And now it needs an explicit else branch!
So what to do?
You've found a few options, none of which is ideal.  So here are a few more, ditto!
You could return an explicit Unit from that branch:
contains("test3") -> { myNullableVar?.let { it.var3 = "test789" }; Unit }
You could return an explicit Unit from the with():
contains("test3") -> myNullableVar?.let { it.var3 = "test789" }
}
Unit
}
You could give an explicit type for the with(). (It has two type parameters, so you'd need to give both, starting with the type of its parameter):
with<String, Unit>("abc") {
I haven't found a single obvious best answer, I'm afraid…
And to answer your last question: yes, ?.let{ is perfectly idiomatic and common for null checks.  In this particular case, replacing it with an if happens to solve the type problem:
contains("test3") -> { if (myNullableVar != null) myNullableVar.var3 = "test789" }
But as well as being long-winded, if myNullableVar is a property and not a local variable, then it opens up a race condition (what if another thread sets it to null in between the test and the assignment?) so the compiler would complain — which is exactly why people use let instead!
(* I can't find a reference for this behaviour.  Is there an official word on it?)

How to do a fail fast in Kotlin properly?

I want to fail fast if a specific function is returning null. I have no case where default value would make processing meaningful.
This is the snippet:
val entityAttributes = entity.optJSONObject("Attributes") ?: run {
LOG.error("Could not find 'Attribute' entry in Entity object")
return
}
So if entity.optJSONObject("Attributes") returns null (which it does desipite the opt*) I want to escape from the function scope.
Is the way I did it the proper one? I am fairly new to Kotlin and want to get used to the proper ways of doing these things as early as possible.
You can return from the function early like you do above. If your function returns something besides Unit, then you'd have to return some default value.
Throwing an exception allows you to exit a function without returning anything, but the exception will crash the program if you don't catch it somewhere. Sometimes this is exactly what you want to happen if the error is something that should never happen, because then you'll catch it during testing and be able to fix it before releasing your application.
Use the global error(cause: Any) function and it will immediately throw an IllegalStateException.

Code contracts - Assume vs Requires

What's the diference between these two statements ?
Contract.Requires(string.IsNullOrWhiteSpace(userName));
Contract.Assume(string.IsNullOrWhiteSpace(userName));
Imagine you have a method like this:
bool ContainsAnX(string s)
{
return s.Contains("X");
}
Now, this method will always fail if you pass null to it, so you want to ensure this never happens. This is what Contract.Requires is for. It sets a precondition for the method, which must be true in order for the method to run correctly. In this case we would have:
bool ContainsAnX(string s)
{
Contract.Requires(s != null);
return s.Contains("X");
}
(Note: Requires and Ensures must always be at the start of a method, as they are information about the method as a whole. Assume is used in the code itself, as it is information about that point in the code.)
Now, in your code that calls the method "ContainsAnX", you must ensure that the string is not null. Your method might look like this:
void DoSomething()
{
var example = "hello world";
if (ContainsAnX(example))
Console.WriteLine("The string contains an 'X'.");
else
Console.WriteLine("The string does not contain an 'X'.");
}
This will work fine, and the static checker can prove that example is not null.
However, you might be calling into external libraries, which don't have any information about the values they return (i.e. they don't use Code Contracts). Let's change the example:
void DoSomething()
{
var example = OtherLibrary.FetchString();
if (ContainsAnX(example))
Console.WriteLine("The string contains an 'X'.");
else
Console.WriteLine("The string does not contain an 'X'.");
}
If the OtherLibrary doesn't use Code Contracts, the static checker will complain that example might be null.
Maybe their documentation for the library says that the method will never return null (or should never!). In this case, we know more than the static checker does, so we can tell it to Assume that the variable will never be null:
void DoSomething()
{
var example = OtherLibrary.FetchString();
Contract.Assume(example != null);
if (ContainsAnX(example))
Console.WriteLine("The string contains an 'X'.");
else
Console.WriteLine("The string does not contain an 'X'.");
}
Now this will be okay with the static checker. If you have runtime contracts enabled, the Assume will also be checked at run time.
Another case where you might need Assume is when your preconditions are very complex and the static checker is having a hard time proving them. In this case you can give it a bit of a nudge to help it along :)
In terms of runtime behavior there won't be much difference between using Assume and Requires. However, results with the static checker will differ greatly. The meaning of each is different as well, in terms of who is responsible for the error in case of failure:
Requires means that the code which calls this method must ensure the condition holds.
Assume means that this method is making an assumption which should always hold true.
It only differs design-time/static-analysis-time
Contract.Assume:
"Instructs code analysis tools to assume that the specified condition is true, even if it cannot be statically proven to always be true"
And:
At run time, using this method is equivalent to using the Assert(Boolean) method.
Contract.Requires will guarantee that the given predicate is true and static code analyzers might raise an error if they can't 'prove' that is not the case. On Contract.Assume the static analyzer will continue/issue a warning/whatever the tool will decide.
According to official documentation: pages 7 (preconditions) and 11 (assumes).
Requires:
Is a precondition ("preconditions are extressed by using Contract.Requires");
As a precondition will be executed on method invoke;
Assumes:
Not a precondition, not a postcondition, not an invariant;
Is executed at the point where it is specified;
p. 11 "Exist in a build only when the full-contract symbol or DEBUG symbol is defined";

How to return often occurring error in object oriented environment?

assume you have a function that polls some kind of queue and blocks for a certain amount of time. If this time has passed without something showing up on the queue, some indication of the timeout should be delivered to the caller, otherwise the something that showed up should be returned.
Now you could write something like:
class Queue
{
Thing GetThing();
}
and throw an exception in case of a timeout. Or you
write
class Queue
{
int GetThing(Thing& t);
}
and return an error code for success and timeout.
However, drawback of solution 1 is that the on a not so busy queue timeout is not an exceptional case, but rather common. And solution 2 uses return values for errors and ugly syntax, since you can end up with a Thing that contains nothing.
Is there another (smart) solution for that problem? What is the preferred solution in an object oriented environment?
I would use exceptions only when the error is serious enough to stop the execution of the application, or of any big-enough application's component. But I wouldn't use exceptions for common cases, after which we continue the normal execution or execute the same function again. This would be just using exceptions for flow control, which is wrong.
So, I suggest you to either use the second solution that you proposed, or to do the following:
class Queue
{
bool GetThing(Thing& t); // true on success, false on failure
string GetLastError();
};
Of course you can stick with an int for an error code, instead of a string for the full error message. Or even better, just define class Error and have GetLastError() return it.
Why not just return null from GetThing in your first solution, changing it to return a Thing *? It seems to fit the bill, at least from the information you've given so far.
In the first, and second case, you can't do anything but throw an exception. When you return a Thing, or a Thing&, you don't have the option of not returning a Thing.
If you want to fail without using an exception then you need:
class Queue
{
// Either something like this. GetThing retuns NULL on an error,
// GetError returns a specific error code
Thing* GetThing();
int GetError();
// This kind of pattern is common. Return a result code
// and set ppOut to a valid thing or NULL.
int GetThing(Thing** ppOut);
};

Do you usually set the default value before or set it in the else?

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?