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
: >

Reply via email to