On Wed, Apr 30, 2014 at 9:57 AM, Oliver Woodford
<oliver.woodf...@gmail.com>wrote:

> Stefan
>
> Firstly, thank you for taking the time to write such a lengthy response. I
> think it comes closest to addressing the particular question I had. Sadly
> I'm an Engineer, not a Computer Scientist, so it's taking me a while to get
> my head round. I've put a few comments inline.
>

No problem. I do think one of the benefits that Julia provides is bringing
some of the computer science goodness that languages like Haskell and ML
have to the computational sciences in a practical way, so it's perfectly
understandable that there are many here who aren't big language nerds :-)


> On Tuesday, April 29, 2014 4:51:52 PM UTC+1, Stefan Karpinski wrote:
>>
>>
>> Julia has chosen the simple approach of invariance everywhere. This
>> simplifies the subtyping rules, but there is no free lunch – variance
>> issues still do crop up. But at least Julia's rules are simple if
>> occasionally a bit inconvenient. Basically, this is the situation:
>>
>>    - *covariance:* *P{A} <: P{B} ⟺ A <: B* – correct for read, incorrect
>>    for write.
>>    - *contravariance:* *P{A} <: P{B} ⟺ B <: A* – correct for write,
>>    incorrect for read.
>>    - *invariance:* *P{A} <: P{B} ⟺ A = B* – correct for both read and
>>    write.
>>
>> I'm not sure what you mean by "correct for read, incorrect for write" etc.
>

If you ask for a Basket{Fruit} and I (covariantly) give you a
Basket{Apple}, it's fine if you only take things out of the basket – you
will always get a Fruit since Apples are Fruit. But if you try to put an
Orange, which is also a Fruit, into the basket, then there's a problem
because an Orange is not an Apple. On the other hand, if you ask for a
Basket{Fruit} and I (contravariantly) give you a Basket{Food}, it's fine if
you put things into the basket – since anything you put in will be Fruit
and all Fruit is Food (let's say), it will be ok. If you start taking
things out of the basket, expecting Fruit, however, you may get a Sausage
or a Cheese, which is not what you were expecting.

frob{A<:B}(x::P{A})
>>
>>
>> This is effectively a covariant signature, applying to P{A} for any A <:
>> B. It seems like you would be happier if parametric types were covariant
>> and you were allowed to write this as:
>>
>> frob(x::P{B})
>>
>>
>> where the method implicitly also applies to x::P{A} for every A <: B.
>> This would certainly be less of an eyesore.
>>
>
> Yes, I guess I am saying this, but only for a particular type, which would
> instantiate homogeneous arrays. I will call this Array, and the type for
> heterogeneous arrays I will call Cell.
>

Types don't live in isolation – you can't just make one parametric type
covariant while all others are invariant. You have to add covariant types
to the type system and make everything still work together. It's not
impossible, but it's a very complex, interconnected system.

As to the rest of what you write (omitted for brevity), it seems like what
you really want is the ability to declare parametric types whose type
parameters can only be concrete. That's an interesting notion, but I'm not
sure it could (or should) be made to fit into the rest of the type system
coherently. I'll have to think about it a bit more. I'm also not sure *why*
you would want to do this. As I mentioned in another email, we've gone to
great lengths to make sure that there's no semantic difference between what
you call a heterogeneous array and a homogeneous array.

Reply via email to