Visibility of constructor parameters

In the following class the constructor parameter s isn't visible in the foo function. I need to add "val" to make the class compile. Is that a bug? I'm curious becuase this is different from the behaviour in Scala where constructor parameters are effectively private member variables.
class C(s: String) {   fun foo(): String = s }

Chris

THis is not a bug. If you want something to be stored in your object, you need to explicitly make it a val.

Doesn't the Scala behaviour make more sense? You almost always want your constructor arguments available to all the code in the class. Would this be the idiomatic way to make a private member variable from a constructor parameter?

class C(private val s: String)

That seems like a lot of boilerplate for something you want to do for almost every constructor parameter.

I also think it’s surprising that s isn’t available in the foo function given the structure of the class. In Kotlin the entire class body is effectively the constructor so it seems logical that constructor parameters should be visible to everything in the class body. This behaviour isn’t surprising in Java because the constructor parameters are declared in the scope of the constructor which is separate from the rest of the class.

class C(s: String) {   // foo is in the block that declares s, looks like s should be visible   fun foo(): String = s }

The tradeoff here is control over how much memory my objects occupy nad the concer you bring up. Both look valid. We should think about it.

1 Like

The compiler could optimise away creating the field if its not referenced in the code?

Yes, but this is not the point. The point is: how a human knows what's stored and what's not. IDE will give you highlighting, but what if I'm using github?

If you need an argument to construct an instance of your class but you don't want to store it as a field you could write a factory method. If you are dropping secondary constructors in Kotlin then factory methods are going to be much more common than in Java.

Another option would be to retain constructor arguments by default but provide an annotation for parameters you don't want to retain.

Although I prefer the idea of always retaining arguments and using factory methods to call your constructor if you don’t want to retain an argument.