New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inconsistent variance in generics #1294
Comments
You are right. And thanks for the detailed explanation! Before fixing this I'd like to sit down and define this behaviour once and for all, because we can't fix it until we understand what we want. One thing we definitely don't want is to deal with covariance, contravariance and other complications. So, even though in your example the type passes the type restriction, the code eventually doesn't compile. This is simpler than having to deal with extra type annotations for covariance. I also would try not to rely to much on type checking and try to program using duck typing. Of course, all of the above doesn't mean we shouldn't tackle this issue. As a side note: what are your real generic types in your program? |
I think it's too soon to assert how we want to deal with covariance and contravariance. I would like to them in the future. All the formality around type system is important. Actually 52b06ff is one case of how return types can be changed in subclasses :-). How it is implemented right now is a bit too far from classical subtyping rules, and is fine. Another place where covariance is needed, but a workaround with record exists is, #357 . I support the idea of not rushing to implement a whole formal system without having a use case. Trying first with how types/methods/macros are expanded and see if that, maybe, is enough. But I think the formal implementation of covariance and contravariance will be needed. |
I was able to fix this. This line: puts (ChildWrapper.new(GrandParent.new).is_a?(Wrapper(Parent))) should definitely be And: say_hello(ChildWrapper.new(GrandParent.new)) should definitely not match. The discussion about covariance/contravariance is something that we should definitely keep in mind, and solve. I opened #1297 to keep the discussion there. |
That was fast :) |
Introduction
I have started to play with the language and found something that looks inconsistent to me.
Let's create class hierarchy:
and a method
When I call this method passing instance of Parent or Child everything works as expected:
If I try to call
say_hello(GrandParent.new)
Compiler returns an error:
Now let's add types hierarchy with generic parameter:
and another method:
Now I can call:
As expected I cannot compile any of following
as compiler returns something like:
Issue
What is inconsistent for me however is that when I try:
I get completely different error:
Looks like method signature was 'updated' to
say_hello(ChildWrapper(GrandParent+))
but then call tohello
failed as it was called onGrandParent
.Checking further, the following compiles:
and prints
while
print_type Wrapper.new(GrandParent.new)
does not compile:
Summary
From the above it seems that contradiction exists:
This looks like a bug to me.
The text was updated successfully, but these errors were encountered: