Raku / old-issue-tracker

Tickets from RT
https://github.com/Raku/old-issue-tracker/issues
2 stars 1 forks source link

An unambiguous case of dispatch treated as an ambiguous one #928

Closed p6rt closed 15 years ago

p6rt commented 15 years ago

Migrated from rt.perl.org#64922 (status was 'resolved')

Searchable as RT64922$

p6rt commented 15 years ago

From @masak

This might be in RT already, but I didn't find it, so...

\ rakudo​: multi foo (@​a) { 1 }; multi foo ($a, %h?) { 2 }; say foo(\<1 2 3>); \ rakudo 69b318​: OUTPUT«Ambiguous dispatch to multi 'foo'. Ambiguous candidates had signatures​:␤​:(Positional.new() @​a)␤​:(Any $a, Associative.new() %h?) [...] * masak submits rakudobug

As for arity, both methods can match. But the first candidate has a type constraint Positional on its first parameter, so it should be narrower than the second one, which doesn't. Therefore, the dispatch shouldn't be ambiguous, and the first candidate should be called.

p6rt commented 15 years ago

From @jnthn

Carl Mäsak (via RT) wrote​:

# New Ticket Created by "Carl Mäsak" # Please include the string​: [perl #​64922] # in the subject line of all future correspondence about this issue. # \<URL​: http://rt.perl.org/rt3/Ticket/Display.html?id=64922 >

This might be in RT already, but I didn't find it, so...

\ rakudo​: multi foo (@​a) { 1 }; multi foo ($a, %h?) { 2 }; say foo(\<1 2 3>); \ rakudo 69b318​: OUTPUT«Ambiguous dispatch to multi 'foo'. Ambiguous candidates had signatures​:␤​:(Positional.new() @​a)␤​:(Any $a, Associative.new() %h?) [...] * masak submits rakudobug

As for arity, both methods can match. But the first candidate has a type constraint Positional on its first parameter, so it should be narrower than the second one, which doesn't. It's not so clear cut that this is a bug. Positional is a role, and is done by some things (like List, Array, etc), but doesn't have a relationship with Any in any way. The default parameter type is Any. Thus if you try Positional ~~ Any, you'll get false (and vice versa - they are tied types so far as the dispatcher is concerned).

Anyway, the dispatcher is behaving as I would have expected in terms of considering those candidates tied. I do agree it isn't very dwim-y, but nothing occurs to me right away that we could do in order to make it dwim more...

Jonathan

p6rt commented 15 years ago

The RT System itself - Status changed from 'new' to 'open'

p6rt commented 15 years ago

From @masak

Jonathan (>), Carl (>>)​:

This might be in RT already, but I didn't find it, so...

\ rakudo​: multi foo (@​a) { 1 }; multi foo ($a, %h?) { 2 }; say foo(\<1 2 3>); \ rakudo 69b318​: OUTPUT«Ambiguous dispatch to multi 'foo'. Ambiguous candidates had signatures​:␤​:(Positional.new() @​a)␤​:(Any $a, Associative.new() %h?) [...] * masak submits rakudobug

As for arity, both methods can match. But the first candidate has a type constraint Positional on its first parameter, so it should be narrower than the second one, which doesn't. It's not so clear cut that this is a bug. Positional is a role, and is done by some things (like List, Array, etc), but doesn't have a relationship with Any in any way. The default parameter type is Any. Thus if you try Positional ~~ Any, you'll get false (and vice versa - they are tied types so far as the dispatcher is concerned).

Anyway, the dispatcher is behaving as I would have expected in terms of considering those candidates tied. I do agree it isn't very dwim-y, but nothing occurs to me right away that we could do in order to make it dwim more...

I see. In short, there's a tie because Positional isn't narrower than Any. I get it now, and agree on a formal level.

...the problem is just that the sigils '@​' and '%' _feel_ like they should be narrower than '$', because the latter can contain anything. The question is probably whether it's possible to reflect that intuition in the MMDer without breaking something important.

p6rt commented 15 years ago

From [Unknown Contact. See original ticket]

Jonathan (>), Carl (>>)​:

This might be in RT already, but I didn't find it, so...

\ rakudo​: multi foo (@​a) { 1 }; multi foo ($a, %h?) { 2 }; say foo(\<1 2 3>); \ rakudo 69b318​: OUTPUT«Ambiguous dispatch to multi 'foo'. Ambiguous candidates had signatures​:␤​:(Positional.new() @​a)␤​:(Any $a, Associative.new() %h?) [...] * masak submits rakudobug

As for arity, both methods can match. But the first candidate has a type constraint Positional on its first parameter, so it should be narrower than the second one, which doesn't. It's not so clear cut that this is a bug. Positional is a role, and is done by some things (like List, Array, etc), but doesn't have a relationship with Any in any way. The default parameter type is Any. Thus if you try Positional ~~ Any, you'll get false (and vice versa - they are tied types so far as the dispatcher is concerned).

Anyway, the dispatcher is behaving as I would have expected in terms of considering those candidates tied. I do agree it isn't very dwim-y, but nothing occurs to me right away that we could do in order to make it dwim more...

I see. In short, there's a tie because Positional isn't narrower than Any. I get it now, and agree on a formal level.

...the problem is just that the sigils '@​' and '%' _feel_ like they should be narrower than '$', because the latter can contain anything. The question is probably whether it's possible to reflect that intuition in the MMDer without breaking something important.

p6rt commented 15 years ago

From @moritz

Jonathan Worthington wrote​:

Carl Mäsak (via RT) wrote​:

# New Ticket Created by "Carl Mäsak" # Please include the string​: [perl #​64922] # in the subject line of all future correspondence about this issue. # \<URL​: http://rt.perl.org/rt3/Ticket/Display.html?id=64922 >

This might be in RT already, but I didn't find it, so...

\ rakudo​: multi foo (@​a) { 1 }; multi foo ($a, %h?) { 2 }; say foo(\<1 2 3>); \ rakudo 69b318​: OUTPUT«Ambiguous dispatch to multi 'foo'. Ambiguous candidates had signatures​:␤​:(Positional.new() @​a)␤​:(Any $a, Associative.new() %h?) [...] * masak submits rakudobug

As for arity, both methods can match. But the first candidate has a type constraint Positional on its first parameter, so it should be narrower than the second one, which doesn't. It's not so clear cut that this is a bug. Positional is a role, and is done by some things (like List, Array, etc), but doesn't have a relationship with Any in any way.

I thought all types match Any, except for Object and junction?

The default parameter type is Any. Thus if you try Positional ~~ Any, you'll get false (and vice versa - they are tied types so far as the dispatcher is concerned).

Not in my copy of Rakudo, Positional ~~ Any is True there.

And if Positional !~~ Any, shouldn't it be a type check failure to bind an array to $a?

Cheers, Moritz

p6rt commented 15 years ago

From @masak

\ rakudo​: say Positional[Int] ~~ Any \ rakudo e8f624​: OUTPUT«1␤» \ oh hmm \ rakudo​: say Any ~~ Positional[Int] \ rakudo e8f624​: OUTPUT«0␤» \ But it kinda surprises me... \ (I thought this was why Positional and Any were sorting to same precedence level.) \ rakudo​: multi f($x) { 1 }; multi f(@​x) { 2 }; say f(1); say f([1,2]) \ rakudo e8f624​: OUTPUT«1␤2␤» \ oh hmm \ strange that the above case resolves, but not the one in the RT thread. \ So the RT ticket I responded to actually brings up an issue that's nothing to do with sigil based dispatch... \ masak​: Yeah. \<moritz_> jnthn​: I think it's something else \ rakudo​: multi f($x, %h?) { 1 }; multi f(@​x) { 2 }; say f(1); say f([1,2]) \ rakudo 5c8015​: OUTPUT«1␤Ambiguous dispatch to multi 'f'. Ambiguous candidates had signatures​:␤​:(Any $x, Associative.new() %h?)␤​:(Positional.new() @​x) [...] \<moritz_> not matching the sigil-implied type is one malus \<moritz_> and not filling up an optional parameter is also one malus \ Ah, something to do with optional parameters...

p6rt commented 15 years ago

From [Unknown Contact. See original ticket]

\ rakudo​: say Positional[Int] ~~ Any \ rakudo e8f624​: OUTPUT«1␤» \ oh hmm \ rakudo​: say Any ~~ Positional[Int] \ rakudo e8f624​: OUTPUT«0␤» \ But it kinda surprises me... \ (I thought this was why Positional and Any were sorting to same precedence level.) \ rakudo​: multi f($x) { 1 }; multi f(@​x) { 2 }; say f(1); say f([1,2]) \ rakudo e8f624​: OUTPUT«1␤2␤» \ oh hmm \ strange that the above case resolves, but not the one in the RT thread. \ So the RT ticket I responded to actually brings up an issue that's nothing to do with sigil based dispatch... \ masak​: Yeah. \<moritz_> jnthn​: I think it's something else \ rakudo​: multi f($x, %h?) { 1 }; multi f(@​x) { 2 }; say f(1); say f([1,2]) \ rakudo 5c8015​: OUTPUT«1␤Ambiguous dispatch to multi 'f'. Ambiguous candidates had signatures​:␤​:(Any $x, Associative.new() %h?)␤​:(Positional.new() @​x) [...] \<moritz_> not matching the sigil-implied type is one malus \<moritz_> and not filling up an optional parameter is also one malus \ Ah, something to do with optional parameters...

p6rt commented 15 years ago

From @jnthn

On Tue Apr 21 03​:50​:19 2009, masak wrote​:

This might be in RT already, but I didn't find it, so...

\ rakudo​: multi foo (@​a) { 1 }; multi foo ($a, %h?) { 2 }; say foo(\<1 2 3>); \ rakudo 69b318​: OUTPUT«Ambiguous dispatch to multi 'foo'. Ambiguous candidates had signatures​:␤​:(Positional.new() @​a)␤​:(Any $a, Associative.new() %h?) [...] * masak submits rakudobug

As for arity, both methods can match. But the first candidate has a type constraint Positional on its first parameter, so it should be narrower than the second one, which doesn't. Therefore, the dispatch shouldn't be ambiguous, and the first candidate should be called.

The issue (as we saw elsewhere in this ticket's discussion) turned out to be the optional parameter fooing up the narrowness analysis. The sorter is a little smarter now and doesn't just say "oh noes, different parameter count = tied" but instead tries to dis-ambiguate based upon the number of parameters they both have available to compare between them. This resolves the issue. Added this as a spectest, and the patch went in as git 2731d20.

Thanks,

Jonathan

p6rt commented 15 years ago

@jnthn - Status changed from 'open' to 'resolved'