Type inference and overloaded functions

Jonathan M Davis jmdavisProg at gmx.com
Mon Dec 9 23:46:14 PST 2013


On Tuesday, December 10, 2013 08:29:02 Kenji Hara wrote:
> On Tuesday, 10 December 2013 at 07:15:43 UTC, Jonathan M Davis
> 
> wrote:
> > On Monday, December 09, 2013 22:59:49 Ali Çehreli wrote:
> >> On 12/09/2013 10:52 PM, Jonathan M Davis wrote:
> >> > On Tuesday, December 10, 2013 07:47:38 FreeSlave wrote:
> >> >> I just found weird D behavior about inference of array
> >> >> types.
> >> >> 
> >> >> Let's suppose we have these overloaded functions:
> >> >> 
> >> >> import std.stdio;
> >> >> 
> >> >> void bar(const(int[3]) arr)
> >> >> {
> >> >> 
> >> >>       writeln("static array");
> >> >> 
> >> >> }
> >> >> 
> >> >> void bar(const(int[]) arr)
> >> >> {
> >> >> 
> >> >>       writeln("array slice");
> >> >> 
> >> >> }
> >> >> 
> >> >> // In main we have something like that:
> >> >> int main(string[] args)
> >> >> {
> >> >> 
> >> >>       bar([1,2,3]);
> >> >>       writeln(typeof([1,2,3]).stringof);
> >> >>       return 0;
> >> >> 
> >> >> }
> >> >> 
> >> >> Weird thing is that the static array version of bar is
> >> >> called,
> >> >> but typeof().stringof is int[], not int[3].
> >> > 
> >> > Array literals are always dynamic arrays. int[3] is a static
> >> > array.
> >> > 
> >> > - Jonathan M Davis
> >> 
> >> The original question is valid then: [1,2,3] goes to the
> >> static array
> >> overload.
> > 
> > Then AFAIK, that's a bug. The type of array literals is always
> > a dynamic
> > array, so they should match dynamic array overloads rather than
> > static array
> > overloads, or if they match both due to an implicit conversion,
> > there should
> > be an ambiguity error. Choosing the static array overload over
> > the dynamic one
> > is just plain wrong.
> 
> This is an intended behavior. An array literal has dynamic array
> type *by default*.
> But all of literals in D behave as polymorphic.
> 
> char c = 'A';   // character literal has char type by default
> dchar d = 'A';  // but it may be implicitly typed as wchar/dchar
> 
> string str = "hello";
> dstring dstr = "hello";  // string literal is implicitly typed as
> dstring
> 
> int[] darr = [1,2,3];
> int[3] darr = [1,2,3];   // implicitly typed as int[3]
> 
> So, an array literal [1,2,3] is implicitly convertible both to
> int[] and int[3].
> And, int[3] is more specialized than int[], so overload
> resolution will choose the first 'bar'.

I'd argue that it would be far better to give an ambiguity error rather than 
silently pick one over the other. In general, having a literal of any kind 
pick a particular overload when it can match multiple is just begging for 
trouble.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list