In my opinion, the most consistent approach is to disallow any autothreading of the argument to .ACCEPTS, such that 3.ACCEPTS(any(3,4)) simply returns False. I suspect the only thing that returns True for that sort of argument is Junction.ACCEPTS(any(3,4)) and such. And we can't autothread that, or it would falsely return False. So I think treating the unrecognized $other as a raw Mu returning False (rather than a threadable Any returning a junction) is the most consistent, if not always in line with everyone's expections, which are not consistent. :)
All those other smartmatches are sugar for .ACCEPTS, and should not introduce special cases either. If you want to make use of a junction like that, you must write when 3 ~~ $_ {...} or when 3 == $_ {...} or so. This is enough to tell the optimizer not to make a jump table. (Though conceivably spesh could still do that for cases where $_ is provably an integer, I guess.) Larry On Mon, May 31, 2021 at 08:09:05PM -0400, yary wrote: : Thanks for the explanation, I think the docs (and Roast) also can be more : explicit on the difference between : $left ~~ $right : and : $right.ACCEPTS($left) : and : given ($left) { when $right { ... } } : and : ... when $right; : : ralph-if you are reading this, last week you went into detail about the : tradeoffs of special-casing Junction handling, how do you view these cases : where the topic "$left" is a Junction? : : Larry the second thing I did on reading your answer (first being re-reading : and thinking about it) was to try the underlying ACCEPTS- do you think : ACCEPTS should return False here, or is it `~~` and `when` that should : coerce Junctions into something that fails against the right side? : : > 3.ACCEPTS(any(3,4)) : any(True, False) : : > ? (3.ACCEPTS(any(3,4))) : True : : -y : : : On Mon, May 31, 2021 at 6:38 PM Larry Wall <la...@wall.org> wrote: : : > On Sun, May 30, 2021 at 10:18:13PM -0400, yary wrote: : > : This came up in today's Raku study group (my own golfing-) : > : : > : > ? (any(4,3) ~~ 3) : > : True : > : > ? (3 ~~ any(4,3)) : > : True : > : > given any(4,3) { when 3 {say '3'}; say 'nope'} : > : nope : > : > given 3 { when any(4,3) {say '3'}; say 'nope'} : > : 3 : > : > given any(4,3) { say .raku } : > : any(4, 3) : > : : > : why does Raku say 'nope' for the example *"**given any(4,3) { when 3 {say : > : '3'}; say 'nope'}*" : > : : > : Since this expression is true *? (any(4,3) ~~ 3)* : > : I expected the "*given 4|3*" to also match "*when 3*" : > : > I think both of these should be returning False. In general, the left : > side of ~~ should : > not be auto-threading, or we revert to the suboptimal Perl semantics of : > smartmatching. : > The reason we broke the symmetry of smartmatch is so that we can optimize : > based on : > the type of the right-hand argument, and allowing auto-threading of the : > other argument : > prevents that. Note that in the switch structure above, "when 3" is : > supposed to be : > optimizable to a jump table, but how do you calculate a jump from a : > junction? So we : > biased smartmatching in the direction of coercion-first semantics rather : > early on : > (though, alas, not early enough to prevent Perl adoption of the earlier : > design). : > : > In any case, the documentation says ~~ is defined underlyingly by : > .ACCEPTS, and : > for a Numeric pattern, that says: : > : > multi method ACCEPTS(Numeric:D: $other) : > : > Returns True if $other can be coerced to Numeric and is numerically : > equal to the invocant : > (or both evaluate to NaN). : > : > And I'd be awfully surprised if any(4,3) can be coerced to Numeric in any : > meaningful way... : > : > Perhaps this should be documented as a trap for people coming from Perl, : > if it isn't already. : > : > Larry : >