Function parameters are "val" not "var"?


#1

package testFunPass fun main(args : Array<String>){   println("in main")   test("a string")

}
fun test(in : String) {
  in = in + " here"
}

in is implicity declared as val according to the compiler in test()

How can I modify a parameter inside of the test function. I don’t want to modify them in the outter scope (unless I return it as a value) but I do want to change parameters inside of functions.
How do I pass them as var?

Thanks
Eric


Mutable Function Parameters
#2

package testFunPass

fun main(args : Array<String>){

  println(“in main”)

  test(“a string”)

}

fun test(x : String) {

  x = x + " here"

}

I realized I had used a keyword "in" but even with "x" the x is implied val

Eric


#3

I believe this is a recent change. Parameters are now always val and cannot be modified. I believe the thinking is to reduce confusion, in case anyone things that the original passed value is changed.


#4

It's a recent change indeed, details here: http://blog.jetbrains.com/kotlin/2013/02/kotlin-m5-1/


Kotlin Function Parameters As val
#5

As of M5.1, all parameters are val and cannot be modified. If you want a mutable, you have to declare it explicitly in the body of the function.

Unfortunately, there’s no such thing as “passing parameters as var”. The only way of passing parameters on the JVM/JS is by value (when you pass an object reference the value of the reference is passed).
Theoretically, we could implement C#-liek out-parameters by boxing values, but this is costly and largely pointless. Use data classes to return multiple values from a function.


#6

Thanks everyone.  I cut my teeth on FORTRAN in the late 60's and I guess I just think impertively and my native mode.

To take this to the next step, Objects passed into standalong functions are mutable and passed by ref.  I think that is good but I want to ask is that what is intended?


package testFunPass
class classy{
  public var a : Int = 1
}
fun main(args : Array<String>){
  var c = classy()
  println(“before test() {c.a}") &nbsp;&nbsp;test(c) &nbsp;&nbsp;println("after test() {c.a}”)
}
fun test(c : classy) {
  c.a = 2
  println(“inside test() ${c.a}”)
}


#7

This is as it should be because you modify a member of the referenced object.

``

before test() 1
inside test() 2
after test() 2


#8

This is intended.Only the reference itself is passed by value.


#9

There is a difference between passing a variable by value versus reference, and with modifying a parameter within a function. The concept does not need to be so highly coupled.

Getting right to the point, I would have opted for default behavior to be immutable function parameters with an optional ability to re-assign the parameter/variable within the body of the function (not allowing or expecting the changed value to be seen by the caller). val (default) and var could have served that purpose.

The primary reasoning is that it is very common and shows greater clarity (my opinion) when a parameter also serves as a count-down variable in a very short function. Introducing an extra local variable in such cases reduces clarity.

Swift 2.2 had a similar feature to what I describe, but deprecated it in 3. But in their case, they also had an inout decoration as the source of the potential coding misunderstandings and therefore the rationale for deprecating re-assignment of parameters.


#10

I too came over the same problem. The only break through is that the we need to pass the value of the arguments to the variables that’re declared inside the function, so that we can use them with other operations or apply operations on them.