Warn when delegating to vars

Today I got bitten by something like:

class MyClass(var x: Stack<Int>): Stack<Int> by x

I expected the class to delegate to the content of variable x, not to its initial value.

Suggestion: put up a warning when delegation to a var happens, otherwise I predict confusion will ensue (aka I’m not the only dumb).

It would be nice to add a way to delegate to the content of a var instead of its initial value however.

2 Likes

Thanks for pointing this out! I wasn’t aware of that. One could argue that there are two possible views:

  1. x is the delegate that this class forwards to. There could be scenarios where one would like to change the delegate that the class forwards to. Thus, changing the value of var x should forward all calls to that new instance.

  2. The delegate is fixed (maybe because of the internal implementation of the delegation mechanism, or because Andrey says so, or…). Thus, it should only be possible to declare it as val. Declaring it as var would be a compiler error.

The current behavior that delegation forwards to the initial value leads to unexpected behavior. Has anybody a good example where the current implementation makes more sense that #1 or #2?

While we’re at it: which methods are not automatically forwarded? It seems that instances of MyStack use toString() of MyStack and not of Stack. Is it correct that methods of Any are not forwarded to the delegate? Are there others as well?

Definitely second that! Been meaning to post about it here for a while.

1 Like

My assumption is that anything you don’t implement must be forwarded.

When reporting a warning, it’s highly desirable that it may be fixed by changing the code in a reasonable way. In this case I’m not sure whah such a fix might be like.

Easy:

class MyClass(var x: Stack<Int>): Stack<Int> by x

to

class MyClass(x: Stack<Int>): Stack<Int> by x { var x = x }

which is imho a bit more explicit: the var hasn’t been introduced yet, so you understand that it will delegate to the parameter. It might be made even clearer by using a different name for the parameter and the var (but naming things is hard so meh).

Good point, thanks