crystal icon indicating copy to clipboard operation
crystal copied to clipboard

Covariance and contravariance

Open asterite opened this issue 8 years ago • 21 comments

Given:

class Foo
end

class Bar < Foo
end

And an array of Bar:

array = Array(Bar).new

We can ask the question: is array an Array(Foo)?

Two answers are possible:

  1. Yes: if we read from array we get a Bar, which is a Foo
  2. No: if we want to put an element into array, we can't put a Foo, only Bar and its subclasses

Right now the compiler will answer "Yes" for type restrictions:

def foo(x : Array(Foo))
end

foo(Array(Bar).new) # OK

But i will answer "No" for is_a?:

Array(Bar).new.is_a?(Array(Foo)) # => false

This is not intuitive and should be fixed somehow.

This also affects union types, aliases and recursive aliases.

asterite avatar Dec 30 '16 12:12 asterite