Why choosing `unwrap_or_else` over `unwrap_or`? [duplicate] - performance

This question already has answers here:
Why should I prefer `Option::ok_or_else` instead of `Option::ok_or`?
(3 answers)
Closed 3 years ago.
fn main() {
let _one = None.unwrap_or("one".to_string());
let _two = None.unwrap_or_else(|| "two".to_string());
}
Any particular reason why people should prefer unwrap_or_else over unwrap_or?
I have seen comments that unwrap_or is eager (this as an example). Does that mean the values in unwrap_or are always evaluated before program execution? And the FnOnce values in unwrap_or_else is called only when the program execute up to that line?

Both are evaluated during the program's execution and can be arbitrary values. The difference is that:
With unwrap_or the fallback value is evaluated just before unwrap_or is called, and therefore is evaluated whether it's needed or not (because Rust is an eager language).
With unwrap_or_else the fallback value is evaluated only when unwrap_or_else triggers it (by invoking the function you pass), and therefore is evaluated only if it's needed.

Related

Unable to update Kotlin method parameter's value [duplicate]

This question already has answers here:
Kotlin function parameter: Val cannot be reassigned
(4 answers)
Closed 5 years ago.
I've following Kotlin method
fun getpower(base:Int,power:Int):Int
{
var result = 1
while(power > 0){
result = result * base
power-- // <---- error in this line
}
return result
}
Kotlin compiler gives following error
Error:(6, 8) Val cannot be reassigned
What's wrong with updating the variable?
What's wrong with updating the variable?
The others answer the question by effectively saying "because Kotlin function parameters are immutable." Of course, that is a(the) correct answer.
But given the fact so many languages, including Java, allow you to re-assign function parameters, it might be valid to interpret your question as "why does Kotlin disallow re-assigning function parameters?"
My Answer: Kotlin and Swift have many features in common, so I went to Swift 3 to see why they decided to deprecate function parameter re-assignment and found this motivation.
Using var annotations on function parameters have limited utility, optimizing for a line of code at the cost of confusion with inout , which has the semantics most people expect. To emphasize the fact these values are unique copies and don't have the write-back semantics of inout , we should not allow var here.
In summary, the problems that motivate this change are:
• var is often confused with inout in function parameters.
• var is often confused to make value types have reference semantics.
•Function parameters are not refutable patterns like in if-, while-, guard-, for-in-, and case statements.
Of course, Kotlin has no inout decoration. But the writers could have chosen to allow val and var, with val being the default. Then they would have had behavior consistent with many other languages. Instead, they opted for code clarity.
The OPs example code shows a valid example of when parameter re-assignment is clear and natural. Having to add one more line to a very short function (to get a local variable to do what the parameter variable could have done) IMHO reduces clarity. Again, IMHO, I would have preferred optionally being able to declare my parameters as var.
A function's parameters inside the function are read-only (like variables created with val), therefore they cannot be reassigned.
You can see discussions about this design decision here and here.
In Kotlin, method parameter's are val(non-mutable) type not var(mutable) type. Similar as java final.
That's why i cant mutate(change) that .
The error you saw has more to do with scoping. A function's parameter by design is immutable or more accurately, read-only and that is what the val keyword stands for that is why you see that error.

How does precedence apply on an expression with an assignment and a conditional? [duplicate]

This question already has an answer here:
How is a local variable created even when IF condition evaluates to false in Ruby? [duplicate]
(1 answer)
Closed 6 years ago.
I have the following simple snippet:
var = 1 if false
I would expect this to evaluate as:
(var = 1) if false
so var would be undefined. However, var gets defined and receives a nil as its value.
What am I missing here?
Ruby recognizes local variables during parsing. So, in your case, even thouogh it's not set to 1 (because the precedence of this expression is like you wrote), ruby knows that it's local variable and doesn't raise NameError.
Ruby parser defines var when it sees it on the lefthand side of an expression (even though its inside of a conditional that doesn’t run). So nil looks an appropriate value.

Three possible java8 Optional values - how do I cleanly return whichever is present? [duplicate]

This question already has answers here:
Chaining Optionals in Java 8
(10 answers)
Closed 6 years ago.
I have three java8 Optionals, and want to return whichever one is actually present in a preferred order. It seems like there should be an easy way to chain them like so:
return optionalA.orElseIfPresent(optionalB).orElseIfPresent(optionalC);
if all three are empty, then an Optional.empty() ought to be returned.
the existing orElse and orElseGet are not really up to the task - they must return an actual value, so it's not possible for the remaining fallbacks to be Optionals themselves.
In the worst case I can have a long list of ifPresent() checks, but there just seems like there's a better way to go about it?
return Stream.of(optional1, optional2, optional3)
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst();
I like JB Nizet's answer (upvoted as well). Alternatively, using only Optional (for whatever reason):
Optional.ofNullable(
optionalA.orElse(
optionalB.orElse(
optionalC.orElse(null))
)
);
which falls into indentation/parenthesis madness and I personally do not like.

Random values in F# [duplicate]

This question already has answers here:
F# Functions vs. Values
(4 answers)
Closed 7 years ago.
I have F# code something like this:
let ran = new System.Random()
let makeVal = ran.NextDouble()
Why when I use makeVal do I get the same random number on every call within one run of the app session (i.e. it's not a seed issue).
Values in F# are immutable by default. So makeVal will not change after the first binding. To get different random values you should call ran.NextDouble() again.
For example use the function:
let makeVal() = ran.NextDouble()

Why do we call functions as arguments in other functions? [duplicate]

This question already has answers here:
Should a function have only one return statement?
(50 answers)
Is good to call function in other function parameter?
(3 answers)
Closed 9 years ago.
I've got a style question. It's something I've been doing since forever, but I can't figure out why, exactly.
In most languages I've used, you can call a method that returns a value as an argument to another method:
foo(bar())
which is equal to
var bar=bar()
foo(bar)
For some reason, the latter seems unsavory. Why is that? Is the first more readable, efficient, or clean?
It's not necessarily equal.
foo(bar());
means "call bar and pipe its arguments to foo"
var retBar = bar();
foo(retBar);
means "initalize retBar, then call bar, store whatever it returns to retBar, and then call foo with retBar as its argumnet."
Depending on how expensive variables are to declare, the latter may have a larger memory footprint or slower runtime.
Really, though, it's an entire extra statement -- two extra statements, actually, depending on language -- and it leaves your code less clean. The only time I do method #2 is when I have some reason to use bar()'s value, even if only to peek at it in a debugger.
I feel its a blend of all what you said. The former construct is favorable since
a. It prevent the declaration of an additional variable to achieve the same result.
b. Its more cleaner since its more easier to read/ understand
var accountBalance = sum ( principalAmount + calculateInterest() )
than
var varCalculateInterest = calculateInterest();
var accountBalance = sum ( principalAmount + calculateInterest() )
c. If you use features like recursion, you obviously will try the former. You will need a lot of temp variables to store the intermediate results. Please see an example below.
return concatenate(quicksort(less), pivot', quicksort(greater))

Resources