Type inference and overloaded functions

Namespace rswhite4 at googlemail.com
Tue Dec 10 00:00:22 PST 2013


On Tuesday, 10 December 2013 at 07:46:25 UTC, Jonathan M Davis 
wrote:
> 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´
I use this implict converting to static arrays very often and if 
we deprecate it, we really need something to declare static array 
literals.
Since [1, 2, 3] is always dynamic we need something like C's {1, 
2, 3} (But that would maybe conflict with struct literals).

@Kenji
But eben if [1, 2, 3] is implicit converted to int[3], it is 
still allocated on the heap, right?


More information about the Digitalmars-d-learn mailing list