Method parameters and mutable variables


#1

Is there any way to declare a method parameter as mutable?

fun party(x: Int) {   var x = x // shadowed var warning   x++ }

fun party(x: Int) {
  var xVar = x // awkward
  xVar++
}


#2

Mutable parameters are not supported.


#3

And I hope will never be, because in my experience there is 30% chance to introduce a bug when using mutable parameters. Well, may be not 30%, but really high :)


#4

I do like that the default is read only, I just think it feels a little clumsy reassigning the variable in the case that you do want it to be mutable


#5

After using Kotlin for a long time (M4?!?) I have found that we rarely use `var` and it is typically solved in some other way.  As mentioned above, you introduce a high chance of bugs when using mutable variables, especially as function parameters.  The same we find that almost all our collections are only mutable during building, and immutable after and when passed around.


#6

(yes Jayson, I know this thread is stale, but sometimes I drink and respond to old forum posts, deal with it)

I completely agree with you in general. In fact, I would love for an easier way to mark something as read-only rather than to separate the read and write APIs by interface. E.g. List vs MutableList.
Right now it feels like there’s a constant tension point in my code when dealing with purity of an API and performance. When creating games in particular, depending on the platform and whether or not the object is short term, allocation is a huge concern, so there is a lot of recycling objects, so having data classes be immutable isn’t realistic.

The way it is in Kotlin currently, and most languages for that matter, it’s not trivial to mark something as read only. For example:

interface Measurable {
   val size: Vector
}
data class Vector(var x: Float, var y: Float)

Now, if I wanted that to be pure, I’d have to write an interface for just the read portion of Vector, separating Vector and MutableVector, and expose size only through the read-only version. (I don’t really care that someone could unsafely cast the read-only version, the compiler warns them for me)
It would be nice to be able to say something like:

interface Measurable {
   val size: readonly Vector2 // Exposes all component vars as vals
}

I understand that val x: Float could have side-effects, but I’m thinking it could possibly be something special for a data class to have an auto-generated read-only interface.

All that being said, I think my original complaint about method parameters really comes down to that I just don’t like being clever with variable names…

fun layout(width: Float) {
   val w = clamp(width, minWidth, maxWidth) // Now I have width and w... Or maybe I should have named it 'clampedWidth'? Next I want to reduce it by the padding, paddedClampedWidth? Naming is hard...
}

// Or....
fun layout(var width: Float) {
   width = clamp(width, minWidth, maxWidth)
}

I think I picked the most pointless thing to drink and ramble about… I do, however, think it would be nice to be able to auto-create a read-only interface for my data classes. Same with Arrays (without converting them to Lists)


#7

Your question is interesting and it is well covered in C++ language.
Unfortunately in Java may generate confusion, readonly keyword doesn’t fit well all use case, ie:

data class MutableInteger(var value : Int = 0) {
 fun incAndGet() = value++
}

Auto generate a read-only interface is an hard work and the automagic interface may be hard to expect/understand.

On other hand C++ provides a const keyword, this fits really well you use case, it is explicitly provided by programmer but require more attention (like open keyword").