Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

index() error message incorrect for third parameter?

sub count-a {
    my $word = "banana";
    my $count = 0;
    my $foo;      #  Source of error: $foo intentionally not given a value.
                 #  The value ought to be zero.

    while True {
      $foo = index $word, "a", $foo;
      last unless $foo.defined;
      $foo++;
      $count++
  }
  return $count;
}

say count-a;

Is this error message wrong?

Cannot resolve caller index(Str: Str, Any); none of these signatures match:
  (Str:D $: Cool:D $needle, *%_)
  (Str:D $: Str:D $needle, *%_)
  (Str:D $: Cool:D $needle, Cool:D $pos, *%_)
  (Str:D $: Str:D $needle, Int:D $pos, *%_)
in sub count-a at scrap.p6 line 11
in block <unit> at scrap.p6 line 18

The error message says index() will accept a third parameter of 'Any', which is what it was given when I verify with $foo.WHAT.

like image 839
Clint Avatar asked May 04 '18 16:05

Clint


3 Answers

The third parameter of index is defined as an Int that is actually coerced to Cool (Cool being a class that can represent either a number or a string in Perl 6). But the way you have defined it my $foo (whose type will be "Any") it can't be recognized as any of them. As soon as you give it a value, either "0" or 0, that will work.

my $foo = 0;  

since the type will be recognized correctly by index's signature.

like image 189
jjmerelo Avatar answered Nov 12 '22 16:11

jjmerelo


So, just to clarify, the error is saying

caller [of subroutine] index [passing params of type] (Str: Str, Any)

cannot be resolved [because it does not match any of] The available index() definitions:

index(Str:D $: Cool:D $needle, *%_)
index(Str:D $: Str:D $needle, *%_)
index(Str:D $: Cool:D $needle, Cool:D $pos, *%_)
index(Str:D $: Str:D $needle, Int:D $pos, *%_)

==========

imho, this error wording will be harder to understand esp. for newbies where it occurs on built-in subroutines due to the thorough use of signature tools such as high order types (e.g. Cool), smilies, $:(whatever that is) and parser internal names such as $needle

maybe could do some magic such as “likely 3rd param caused error as defns require it to be Int:D or Cool:D”

like image 42
p6steve Avatar answered Nov 12 '22 15:11

p6steve


I discuss how we might improve the error message in the second half of this answer. But first:

Is this error message wrong?

Well, you've misunderstood it, so it's wrong in that sense.

The error message says index() will accept

To be more precise, the message begins:

Cannot resolve caller 

which refers to the index() call, i.e. not "what index() will accept" but rather what the code actually asked for which was:

index $word, "a", $foo;

a third parameter of Any, which is what it was given when I verify with $foo.WHAT.

Yes, Any is the type of the third value of "what it was given", but that refers to the value of the third argument of a call to index(), not the third parameter of an index() definition.

The available index() definitions are:

index(Str:D $: Cool:D $needle, *%_)
index(Str:D $: Str:D $needle, *%_)
index(Str:D $: Cool:D $needle, Cool:D $pos, *%_)
index(Str:D $: Str:D $needle, Int:D $pos, *%_)

None of these four definitions, which have distinct signatures, include a third parameter that will accept the given corresponding third argument in the call, as stored in the call's capture.

Ideas about how to improve the error message

Perl 6 culture includes an "awesome error messages" focus, and arguably related confusion has come up before (eg the exchange that led to this comment I made on an earlier SO).

So let's dissect this a little bit further so we can see if we come up with any good ideas for clearly improving the message, or some doc, or whatever.

I think your misunderstanding was rooted in lack of clarity about the distinction between arguments (and calls/captures) and parameters (and definitions/signatures), and particularly your interpretation of this bit of the error message:

index(Str: Str, Any)

The bit after index looks just like a signature, i.e. it looks like a list of, well, thingies (let's call it the types of "pargs") that would be acceptable to an index() definition if used in an index() call.

But it's not a signature, part of an index() definition. Instead it's actually a list of types corresponding to the list of arguments in an index() call.

I think this capture analysis and display is specifically constructed to make it easier for the reader of the error message to figure out what went wrong in the attempt to bind the capture to a matching signature.

Unfortunately, while it may now serve that purpose for you if you've understood this answer, we're still left with the problem that your initial interpretation led you to think the error message was just plain wrong -- and others may make the same mistake.

Anyhow, I think that's enough discussion in my answer. If you wish to pursue this please add comments to this answer and/or your question. Does what I've written so far make sense to you? Got any ideas?

like image 32
raiph Avatar answered Nov 12 '22 15:11

raiph