News for hackers. Stuff that matters.
Re:Understanding contravariance by ufo on Friday June 22, 2018 @01:52PM (#17375907)
In a system with subtyping {x:int, y:int} is a subtype of {x:int}. You can have a function that receives {x:int} and you can pass a {x:int, y:int} to it. The subtype can be freely used whenever the supertype is expected.

With row typing instead of subtyping you have "row variables". That function that would receive a {x:int} is typed as "forall p. {x:int; p}". You can pass the function a {x:int, y:int} because it unifies p with {y:int}. But you cannot freely convert a {x:int, y:int} to a {x:int}, it is all based around parametric polymorphism.

This system with row variables works much better with hindley-milner type inference but it is a bit more restrictive. For example, you cannot use subtype polymorphism to have a heterogeneous list of objects. If you have a function that receieves a "forall p. [{x:int; p}]" you can have a list of {x:int} or a list of {x:int, y:int} but every element of the list must have the same type.

Re:Understanding contravariance by willtim on Friday June 22, 2018 @03:46PM (#17376787)
> you cannot use subtype polymorphism to have a heterogeneous list of objects

You can by using an existential type parameter, which 'forgets' the types in much the same way as an upcast.

[exists p. {x:int; p}]