Liz (>):
> Feels like this in essence is the same as .clone not being able to
> clone a typed hash.

Yes, at least for some of the simpler cases.

After I submitted the ticket, this relevant discussion took place:

<masak> pmichaud: hm. question is, if I %h1 >>+<< $h2, and the hashes 
are typed with different constraints, what the result ends up being. 
same question for <<+>>, really.
<masak> (typed hashes and hyperoperators! yay, I found a new corner 
case!)
<pmichaud> masak: yes, that's a legitimate question.
<masak> pmichaud: I guess the type-theoretical answer is that in one 
case you'll get the join of the types, and in the other case you'll get 
the meet of the types :P
<pmichaud> masak: I'm thinking the practical answer may be DIHWIDT for a 
while :)

To make this concrete, consider this code:

class Left {}
class Right {}
class Both is Left is Right {}

my $l = Left.new;
my $r = Right.new;
my $b = Both.new;

my %l{Left} = $l => 1, $b => 1;
my %r{Right} = $r => 1, $b => 1;

say (%l <<+>> $r).elems;    # 1, because intersection (S03:4377)
say (%l >>+<< $r).elems;    # 3, because union
say (%l >>+<< $r){$b};      # 2. 1 from each operand

So far so good, but if the hyper-op result of a typed hash is to be a 
typed hash, then what are the *types* of the <<+>> and >>+<< results 
above? Again, the type-theoretical answer seems to be this:

(%l <<+>> $r) has keytype (Left & Right)
(%l >>+<< $r) has keytype (Left | Right)

We've distanced ourselves from thinking in terms of junctional types 
like that. But that seems to be what falls out of this. I'm not sure if 
that's good or not. For example, would (Left & Right) be completely 
compatible with Both? I doubt it.

Wishing I had more ideas how to create solid semantics for this corner 
case.

Reply via email to