opDispatch, duck typing, and error messages

spir denis.spir at gmail.com
Fri Apr 22 02:23:35 PDT 2011


On 04/22/2011 12:24 AM, Adam D. Ruppe wrote:
> I just made an innocent little change to one of my programs, hit
> compile, and got this vomit:
>
> /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(97): Error: template
> std.conv.toImpl(T,S) if (!implicitlyConverts!(S,
> T)&&  isSomeString!(T)&&  isInputRange!(Unqual!(S))&&
> isSomeChar!(ElementType!(S))) toImpl(T,S) if (!implicitlyConverts!(S
> ,T)&&  isSomeString!(T)&&  isInputRange!(Unqual!(S))&&
> isSomeChar!(ElementType!(S))) matches more than one template declar
> ation, /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(185):toImpl(T,S)
> if (isSomeString!(T)&&  !isSomeChar!(ElementT
> ype!(S))&&  (isInputRange!(S) || isInputRange!(Unqual!(S)))) and
> /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(289)
> :toImpl(T,S) if (is(S : Object)&&  isSomeString!(T))
>
>
>
> Whooooo... took a bit to figure out what it was saying. The bottom
> line: one of my classes matched both Object and isInputRange because
> it offers an unrestricted opDispatch.
>
>[...]
>
> Things I think would help:
>
> [...]
>
> Or, there's a whole new approach:
>
> e) Duck typing for ranges in to!() might be a bad idea. Again, remember,
> a class might legitimately offer a range interface, so it would
> trigger this message without opDispatch.

Maybe we could replace template constraints, esp. 'is' stuff, by (structural) 
interfaces. The difference in my views is structural interface is a 
compile-time / static feature, while duck typing is runtime/dynamic.

> If ranges are meant to be structs, maybe isInputRange should check
> is(T == struct)? This doesn't sit right with me though. The real
> problem is to!() - other range functions probably don't overload
> on classes separately than ranges, so it won't matter there.
>
>
> I think the best thing to do is simply to prefer Object over range.
>
> toImpl(T) if (isInputRange!(T)&&  (!is(T : Object)))
>
> Or something along those lines. Why? If the object has it's own
> toString/writeTo methods, it seems fairly obvious to me anyway that
> to!string ought to simply call them, regardless or what else there is.

Sure. I hit and discussed a similar issue (maybe the same one in fact). The 
problem was with template formatValue which constraints:
(1) for structs, ignore programmer-defined toString in favor of standard format 
for ranges
(2) for classes, simply fail because of conflict (double match)
There's a bug report (search for 'formatValue').

Denis
-- 
_________________
vita es estrany
spir.wikidot.com



More information about the Digitalmars-d mailing list