consider the kind of capturing when deciding variance
See original GitHub issueConsider:
class Foo<out T>(variable T t)
{
noop(Foo("hello").t);
}
I’d argue that the above should compile. Whether you are only setting, only getting, or both setting and getting the captured attribute should decide whether it is, respectively, contravariant, covariant, or invariant.
You might be wondering why one would mark the attribute as variable
if one is not going to set it. But the catch is: one may be setting this.t
, and not other.t
.
In my particular use‐case, I have an attribute that is identifiable, immutable, and potentially expensive to check for equality. I want to set this attribute to the comparee so that I can use identity equality instead of value equality next time around.
Here is a simplification of what I’m trying to do:
class Foo<out Expensive>(variable Expensive expensive)
given Expensive
satisfies Identifiable
{
hash => 0; // TODO
shared actual Boolean equals(Object that)
{
if(is Foo<Expensive> that)
{
if(expensive === that.expensive)
{
return(true);
}
else if(expensive == that.expensive)
{
expensive = that.expensive;
return(true);
}
else
{
return(false);
}
}
else
{
return(false);
}
}
}
Of course, this limitation can be worked around by having a second non‐variable attribute that delegates to the variable attribute and capturing that instead, but I think the compiler should be smart enough for the developer to not have to think and worry about that.
Issue Analytics
- State:
- Created 6 years ago
- Comments:6 (5 by maintainers)
Top GitHub Comments
The other option would be to get rid of the capture analysis and instead acknowledge an implied
in Nothing
(orout Anything
forin
TPs):OK, well, this seems to be working, and I’m very happy with the code improvements I made as a side-effect, so I have merged the branch. Closing.