I'd say this is NOTABUG via the DIHWIDT category. If your where clause
has side-effects, you're bound to get in trouble.

If you're fine with relying on internals, you can just put True into the
one-out-of-ten three times at the end and the program will run through
to 100.


    test 90
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    test 100
    100
    timo@schmand ~> cat /tmp/inconsistent.p6
        my \one-out-of-ten =
(|(False,False,False,False,False,False,False,False,False,True,True,True)
xx *).iterator;
   
        multi sub rarely ( $_ where one-out-of-ten.pull-one ){ say "test
$_"; nextsame}
        multi sub rarely ( $_ ) { .say }
   
        (1..100).map: &rarely;

We rely on binding a signature to give the same result multiple times in
a row to make signature binding code a whole bunch faster. We have a
"slow binder" and a "fast binder". The fast one can only produce a "it
worked" or "it didn't work" result, so after a "it didn't work" result
was encountered we run the slow one over the same values to produce an
actual error message. Normally if your where clauses behave in an impure
manner, you'd get "Internal error: inconsistent bind result" (that's
when the fast binder says "failed" and the slow binder can't reproduce
the failure).

I'm not entirely sure why it gives you "Constraint type check failed for
parameter '$_'". My best guess is that because it first tries to figure
out which candidate to invoke and then actually calls into the candidate
(which starts with code generated by the fast binder) it hits a bind
failure as if you had directly invoked that candidate yourself but with
non-matching arguments.

Zoffix wrote a bit of code on IRC that demonstrates "inconsistent bind
result", btw:

    perl6 -e 'my $val; multi foo($ where {$val++ %% 2 ?? 1 !! 0}) { say
"here" }; multi foo($) { say "♥" }; foo(42) for ^20'
    Internal error: inconsistent bind result
      in sub foo at <tmp> line 1
      in block <unit> at <tmp> line 1

Hope that clears things up!
  - Timo

BTW, for a fun time, put a "say 'here'" into a where clause and count
how often it gets invoked.

Reply via email to