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

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.

Related

What are common "Go-tchas" that someone learning Golang should watch out for? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
For example, the "Effective Go" documentation has the following entries:
Like C, Go's formal grammar uses semicolons to terminate statements, but unlike in C, those semicolons do not appear in the source. Instead the lexer uses a simple rule to insert semicolons automatically as it scans, so the input text is mostly free of them.
Cut off some parts for brevity.
Write them like this
if i < f() {
g()
}
not like this
if i < f() // wrong!
{ // wrong!
g()
}
The wrong version when executed produces the following error messages:
/tmp/test.go:6: missing condition in if statement
/tmp/test.go:6: true evaluated but not used
IMO, both messages don't give the coder a clue about misplaced curly braces. Had I failed to read the documentation above, I would have probably written some Go code in the future using the wrong version (I usually use the 1st version in writing code that uses curly braces), then banged my head as to why I'm missing an "if" condition when one is clearly present.
Are there other "gotchas" in Golang that I should be aware of?
This could've been just a comment, but posted as an answer to lay more emphasis on it, because I do believe the linked article is really good, useful even for non-starters and it is still unknown.
This is the best and most complete I've seen:
50 Shades of Go: Traps, Gotchas, and Common Mistakes for New Golang Devs
It has topics ranging from total beginner (like "Opening Brace Can't Be Placed on a Separate Line" or "Unused Imports") to advanced beginner (like "nil" Interfaces and "nil" Interfaces Values or "Preemptive Scheduling").
So a nice summary of the common pitfalls or "gotchas" is basically their table of contents, all of which you can read more about there:
Total Beginner:
Opening Brace Can't Be Placed on a Separate Line
Unused Variables
Unused Imports
Short Variable Declarations Can Be Used Only Inside Functions
Redeclaring Variables Using Short Variable Declarations
Accidental Variable Shadowing
Can't Use "nil" to Initialize a Variable Without an Explicit Type
Using "nil" Slices and Maps
Map Capacity
Strings Can't Be "nil"
Array Function Arguments
Unexpected Values in Slice and Array "range" Clauses
Slices and Arrays Are One-Dimensional
Accessing Non-Existing Map Keys
Strings Are Immutable
Conversions Between Strings and Byte Slices
Strings and Index Operator
Strings Are Not Always UTF8 Text
String Length
Missing Comma In Multi-Line Slice/Array/Map Literals
log.Fatal and log.Panic Do More Than Log
Built-in Data Structure Operations Are Not Synchronized
Iteration Values For Strings in "range" Clauses
Iterating Through a Map Using a "for range" Clause
Fallthrough Behavior in "switch" Statements
Increments and Decrements
Bitwise NOT Operator
Operator Precedence Differences
Unexported Structure Fields Are Not Encoded
App Exits With Active Goroutines
Sending to an Unbuffered Channel Returns As Soon As the Target Receiver Is Ready
Sending to an Closed Channel Causes a Panic
Using "nil" Channels
Methods with Value Receivers Can't Change the Original Value
Intermediate Beginner:
Closing HTTP Response Body
Closing HTTP Connections
Unmarshalling JSON Numbers into Interface Values
Comparing Structs, Arrays, Slices, and Maps
Recovering From a Panic
Updating and Referencing Item Values in Slice, Array, and Map "for range" Clauses
"Hidden" Data in Slices
Slice Data Corruption
"Stale" Slices
Type Declarations and Methods
Breaking Out of "for switch" and "for select" Code Blocks
Iteration Variables and Closures in "for" Statements
Deferred Function Call Argument Evaluation
Deferred Function Call Execution
Failed Type Assertions
Blocked Goroutines and Resource Leaks
Advanced Beginner:
Using Pointer Receiver Methods On Value Instances
Updating Map Value Fields
"nil" Interfaces and "nil" Interfaces Values
Stack and Heap Variables
GOMAXPROCS, Concurrency, and Parallelism
Read and Write Operation Reordering
Preemptive Scheduling

Performance of thenComparing vs thenComparingInt - which to use?

I have a question, if I'm comparing ints, is there a performance difference in calling thenComparingInt(My::intMethod) vs thenComparing(My::intMethod), in other words, if I'm comparing differemt types, both reference and primitive, e.g. String, int, etc. Part of me just wants to say comparing().thenComparing().thenComparing() etc, but should I do comparing.thenComparing().thenComparingInt() if the 3rd call was comparing an int or Integer value?
I am assuming that comparing() and thenComparing() use the compareTo method to compare any given type behind the scenes or possibly for ints, the Integer.compare? I'm also assuming the answer to my original question may involve performance in that thenComparingInt would know an int is being passed in, whereas, thenComparing would have to autobox int to Integer then maybe cast to Object?
Also, another question whilst I think of it - is there a way of chaining method references, e.g. Song::getArtist::length where getArtist returns a string? Reason is I wanted to do something like this:
songlist.sort(
Comparator.comparing((Song s) -> s.getArtist().length()));
songlist.sort(
Comparator.comparing(Song::getArtist,
Comparator.comparingInt(String::length)));
songlist.sort(
Comparator.comparing(Song::getArtist, String::length));
Of the 3 examples, the top two compile but the bottom seems to throw a compilation error in Eclipse, I would have thought the 2nd argument of String::length was valid? But maybe not as it's expecting a Comparator not a function?
Question 1
I would think thenComparingInt(My::intMethod) might be better since it should avoid boxing, but you would have to try out both versions to see if it really makes a difference.
Question 2
songlist.sort(
Comparator.comparing(Song::getArtist, String::length));
Is invalid because the 2nd parameter should be a Comparator not a method that returns int.

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))

On signature polymorphic methods in Java-7

As far as I can tell, with the introduction of MethodHandle in Java 7 came the introduction of compiler-generated method overloads.
The javadoc for MethodHandle states (I've trimmed the examples):
Here are some examples of usage:
Object x, y; String s; int i;
mh = ...
// (Ljava/lang/String;CC)Ljava/lang/String;
// (String, char, char) -> String
s = (String) mh.invokeExact("daddy",'d','n');
// (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
// (Object, Object, Object) -> Object
x = mh.invokeExact((Object)1, (Object)2, (Object)3);
// (Ljava/util/List;)I
// (List) -> int
i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));
// (Ljava/io/PrintStream;Ljava/lang/String;)V
// (PrintStream, String) -> void
mh.invokeExact(System.out, "Hello, world.");
Each of the above calls generates a single invokevirtual instruction
with the name invoke and the type descriptors indicated in the
comments. The argument types are taken directly from the actual
arguments, while the return type is taken from the cast immediately
applied to the call. This cast may be to a primitive. If it is
missing, the type defaults to Object if the call occurs in a context
which uses the return value. If the call occurs as a statement, a cast
is impossible, and there is no return type; the call is void.
In effect, invokeExact and friends behave as if there is an overload for every possible combination of paramaters and return type.
I've heard that MethodHandles are preparing for features in Java 8 like lambdas. (I know they are already useful for scripting languages.)
[/introduction]
So, are there more of these compiler-generated overloads hiding around in Java? Are there hints there will be more of them in the future (say, with extension methods)? Why is it necessary in the first place? Merely speed? How does it help lambdas out (I thought lambdas would compile to an anonymous inner class)?
In short, what's the rationale; why are they (generated overloads) useful now and in the future?
UPDATE: What I call compiler-generated overloads here, the Oracle guys call signature polymophic.
I just came across an Hotspot internals wiki on MethodHandles and invokedynamic
It makes a few interesting points that answer these questions (and a few more).
What is called compiler-generated overloads in the question, the java guys call signature polymorphic.
MethodHandle.invokeExact and friends are unique, being the only signature polymorphic methods.
On the HotSpot VM, the invokevirtual bytecode for MethodHandle.invoke* is secretly converted to an invokehandle instruction.
invokehandle is like invokedynamic; a few internals are different, and where each invokedynamic instruction must point to it's own Constant Pool Cache Entry (CPCE), invokehandles can share CPCEs.
invokedynamic uses the non-public MethodHandle.invokeBasic on the HotSpot VM
MethodHandle.invokeBasic is like invokeExact but more loose; for one it does not check the types of at the call-site with those of the callee.
Hot method handles (including invokedynamic) can be JIT-compiled
Additionally, lambda expressions will be implemented via invokedynamic. (Got that from Edwin Dalorzo's answer.) This means lambda expressions
will indirectly use MethodHandle.invokeBasic on the HotSpot VM (see above), and
are eligible to be JIT-compiled
These two links may not answer all your questions, but they might be a good starting point:
Translation of Lambda Expressions
From Lambdas to Bytecode
This is reference material comming from the expert group currently working in the JDK 8: Project Lambda. With luck you can find some explanations there, above all about your missconception of lambda expressions as inner classes.

Using function arguments as local variables

Something like this (yes, this doesn't deal with some edge cases - that's not the point):
int CountDigits(int num) {
int count = 1;
while (num >= 10) {
count++;
num /= 10;
}
return count;
}
What's your opinion about this? That is, using function arguments as local variables.
Both are placed on the stack, and pretty much identical performance wise, I'm wondering about the best-practices aspects of this.
I feel like an idiot when I add an additional and quite redundant line to that function consisting of int numCopy = num, however it does bug me.
What do you think? Should this be avoided?
As a general rule, I wouldn't use a function parameter as a local processing variable, i.e. I treat function parameters as read-only.
In my mind, intuitively understandabie code is paramount for maintainability, and modifying a function parameter to use as a local processing variable tends to run counter to that goal. I have come to expect that a parameter will have the same value in the middle and bottom of a method as it does at the top. Plus, an aptly-named local processing variable may improve understandability.
Still, as #Stewart says, this rule is more or less important depending on the length and complexity of the function. For short simple functions like the one you show, simply using the parameter itself may be easier to understand than introducing a new local variable (very subjective).
Nevertheless, if I were to write something as simple as countDigits(), I'd tend to use a remainingBalance local processing variable in lieu of modifying the num parameter as part of local processing - just seems clearer to me.
Sometimes, I will modify a local parameter at the beginning of a method to normalize the parameter:
void saveName(String name) {
name = (name != null ? name.trim() : "");
...
}
I rationalize that this is okay because:
a. it is easy to see at the top of the method,
b. the parameter maintains its the original conceptual intent, and
c. the parameter is stable for the rest of the method
Then again, half the time, I'm just as apt to use a local variable anyway, just to get a couple of extra finals in there (okay, that's a bad reason, but I like final):
void saveName(final String name) {
final String normalizedName = (name != null ? name.trim() : "");
...
}
If, 99% of the time, the code leaves function parameters unmodified (i.e. mutating parameters are unintuitive or unexpected for this code base) , then, during that other 1% of the time, dropping a quick comment about a mutating parameter at the top of a long/complex function could be a big boon to understandability:
int CountDigits(int num) {
// num is consumed
int count = 1;
while (num >= 10) {
count++;
num /= 10;
}
return count;
}
P.S. :-)
parameters vs arguments
http://en.wikipedia.org/wiki/Parameter_(computer_science)#Parameters_and_arguments
These two terms are sometimes loosely used interchangeably; in particular, "argument" is sometimes used in place of "parameter". Nevertheless, there is a difference. Properly, parameters appear in procedure definitions; arguments appear in procedure calls.
So,
int foo(int bar)
bar is a parameter.
int x = 5
int y = foo(x)
The value of x is the argument for the bar parameter.
It always feels a little funny to me when I do this, but that's not really a good reason to avoid it.
One reason you might potentially want to avoid it is for debugging purposes. Being able to tell the difference between "scratchpad" variables and the input to the function can be very useful when you're halfway through debugging.
I can't say it's something that comes up very often in my experience - and often you can find that it's worth introducing another variable just for the sake of having a different name, but if the code which is otherwise cleanest ends up changing the value of the variable, then so be it.
One situation where this can come up and be entirely reasonable is where you've got some value meaning "use the default" (typically a null reference in a language like Java or C#). In that case I think it's entirely reasonable to modify the value of the parameter to the "real" default value. This is particularly useful in C# 4 where you can have optional parameters, but the default value has to be a constant:
For example:
public static void WriteText(string file, string text, Encoding encoding = null)
{
// Null means "use the default" which we would document to be UTF-8
encoding = encoding ?? Encoding.UTF8;
// Rest of code here
}
About C and C++:
My opinion is that using the parameter as a local variable of the function is fine because it is a local variable already. Why then not use it as such?
I feel silly too when copying the parameter into a new local variable just to have a modifiable variable to work with.
But I think this is pretty much a personal opinion. Do it as you like. If you feel sill copying the parameter just because of this, it indicates your personality doesn't like it and then you shouldn't do it.
If I don't need a copy of the original value, I don't declare a new variable.
IMO I don't think mutating the parameter values is a bad practice in general,
it depends on how you're going to use it in your code.
My team coding standard recommends against this because it can get out of hand. To my mind for a function like the one you show, it doesn't hurt because everyone can see what is going on. The problem is that with time functions get longer, and they get bug fixes in them. As soon as a function is more than one screen full of code, this starts to get confusing which is why our coding standard bans it.
The compiler ought to be able to get rid of the redundant variable quite easily, so it has no efficiency impact. It is probably just between you and your code reviewer whether this is OK or not.
I would generally not change the parameter value within the function. If at some point later in the function you need to refer to the original value, you still have it. in your simple case, there is no problem, but if you add more code later, you may refer to 'num' without realizing it has been changed.
The code needs to be as self sufficient as possible. What I mean by that is you now have a dependency on what is being passed in as part of your algorithm. If another member of your team decides to change this to a pass by reference then you might have big problems.
The best practice is definitely to copy the inbound parameters if you expect them to be immutable.
I typically don't modify function parameters, unless they're pointers, in which case I might alter the value that's pointed to.
I think the best-practices of this varies by language. For example, in Perl you can localize any variable or even part of a variable to a local scope, so that changing it in that scope will not have any affect outside of it:
sub my_function
{
my ($arg1, $arg2) = #_; # get the local variables off the stack
local $arg1; # changing $arg1 here will not be visible outside this scope
$arg1++;
local $arg2->{key1}; # only the key1 portion of the hashref referenced by $arg2 is localized
$arg2->{key1}->{key2} = 'foo'; # this change is not visible outside the function
}
Occasionally I have been bitten by forgetting to localize a data structure that was passed by reference to a function, that I changed inside the function. Conversely, I have also returned a data structure as a function result that was shared among multiple systems and the caller then proceeded to change the data by mistake, affecting these other systems in a difficult-to-trace problem usually called action at a distance. The best thing to do here would be to make a clone of the data before returning it*, or make it read-only**.
* In Perl, see the function dclone() in the built-in Storable module.
** In Perl, see lock_hash() or lock_hash_ref() in the built-in Hash::Util module).

Resources