Robert Sedlacek wrote: > Do you have any specific use-case for bidirectional overload acceptance? No. Just a lot of (bad) experience with both OO code and code that extends existing behaviours. The point here is simply that, when we allow new types (represented by objects) to be included in the smartmatching system, then it should be up to those new types to *fully* determine how they interact with that system. In other words, if you build a class, and if that class overloads ~~, then it's important that the overloading predictably take control of *every* smartmatch involving objects of the class. Because only the class itself can know what smartmatching semantics make sense for its objects (regardless of which side of the smartmatch they appear), and hence determine how smartmatching should be implemented when one of its objects is involved. > I can see how this would be useful for some object types. But it also > might make certain other cases impossible. I don't believe it would make any cases impossible. If you're overloading ~~ for the class, you handle every case in the overloading. If you're not overloading ~~ for the class, the issue doesn't arise is the first place, since smartmatching falls back on the rest of the table. > Say I have an object representing a type itself: > > 23 ~~ $IntType > $IntType ~~ 23 > > I'd find it odd if that would work, but won't if I represent the type > check as a code reference. But it *would*: you'd just write the ~~-overloading method for your TypeObj class in such a way that it handles coderefs the way you want. If you want the standard smartmatching behaviour (i.e. pass the TypeObj to the sub) you'd implement it like so: package TypeObj; use overload '~~' => sub { my ($type_object, $comparand, $reversed) = @_; # What are we smartmatching against... my $comparand_type = ref $comparand; # If it's a subref, pass the typeobj to the sub... if ($comparand_type eq 'CODE') { return $comparand->($type_object); } else { return $comparand_type eq $type_object->type; } }; But if you want it to match against a code ref the same way it matches against a number (i.e. is this other operand of the correct type?), you'd implement it like this instead: package TypeObj; use overload '~~' => sub { my ($type_object, $comparand, $reversed) = @_; return ref($comparand_type) eq $type_object->type; }; That's the entire point: if you overload ~~, then you get to (and have to) decide the behaviour for all cases involving that class. > Also, I wouldn't be able to match the object > itself, right? For example: > > $IntType ~~ sub { ... } > > would ask the object on the left to match, but not the code reference No. It would call the overloaded ~~ on the Type object, which would then decide how to handle that smartmatch (as in the examples above). > This also means that an externally passed object could, unintentionally, > change the meaning of my given/when constructs. Yes. But that is *always* the case, for any operation involving objects with overloaded operators. > Is it maybe possible to have separate overloads for 'smartmatcher' and > 'smartmatchee' (couldn't find better terms right now)? You *can* have that: you just implement the overloading so as to check whether it was passed the extra 'reversed' argument, and then do whatever you want in either branch: package TypeObj; use overload '~~' => sub { my ($object, $other_operand, $reversed) = @_; if (!reversed) { # Do this if object is smartmatcher... } else { # Do this if object is smartmatchee... } }; >> The when construct >> ================== >> >> Form Meaning >> ================== ================================== >> when (EXPR) {...} if ($_ ~~ (EXPR)) {...; break} >> when {BLOCK} {...} if ($_ ~~ sub{BLOCK}) {...; break} > > I do wonder if `when {...}` could (internally) be an `if (do {...})` > instead of `if ($_ ~~ sub { ... })` for performance reasons, I'd certainly like the better performance too, but I'd *hate* the fact that it would eliminate the implicit ~~, and hence would by-pass overloading if $_ contains an object. :-( DamianThread Previous | Thread Next