Curiosity about parameters

I am a very curious person and I always try to find an explanation for all the things that happen to me. I noticed for the first time (developing with kotlin only 2 days) that if I try to change a value previously transferred by parameter, I will be returned an error saying that I can not change a val. This happens even if the value that I step into the function is initially declared as var and I do not understand why I have to subsequently re-declare the parameter just passed as var also in the secondary functionPreformatted text

In general it is good practice to never reasign a function parameter because it can easily lead to bugs, especially when changing functions. For that reason function arguments are always val in kotlin. You can imagine that instead of writing

fun foo(bar: Int) = TODO()

you acutally write

fun foo(val bar: Int) = TODO()   // this is invalid kotlin

If you really need to reasing a parameter you can do that be declaring a new variable with the same name as the parameter.

fun foo(bar: Int) {
    val bar = bar + 5
}

This will lead to a warning “Name shadowed: bar” which you can suppress by adding @Suppress("NAME_SHADOWING").

The argument you pass to a function has nothing to do with the parameter inside of the function in this regard. The function does not know that you call it with a var, val or constant and it does not care about this. This sounds like you are trying to change the calling variable from within a function. This is not possible. You can change the properties of that variable foo.bar but not the variable itself. If you want to learn more about that I suggest you look into “call by value” vs “call by reference”.Kotlin uses the later(see next answer).

2 Likes

Your answer is correct, except this last paragraph. Kotlin uses call by value. And because of this, it cannot mutate the passed variable.

Java also uses call by value for all kinds of arguments. Many sources get this wrong because Java/Kotlin has reference types. But even variables that hold references are not passed by reference. You can never mutate the passed variable in Kotlin/Java. You can surely mutate a passed object, but mutating the passed object is not the same as mutating the passed variable.

Mutating the passed variable is only possible in languages that support call by reference. C-like languages generally can do this. C and C++ support this with pointers. Even C# supports this with it’s “out” parameters.

2 Likes

Thanks for the answers now I better understand how the switch in the kotlin parameter works. I the only other language I’ve ever used is javaScript and even in the parameters it always remained a var :grinning: