Walter Bright wrote:
Especially the array literal type inference is really naive.
How should it be done?
You shouldn't use the type of the first given element when
constructing the type of the array. If you have [ e_1, ..., e_n ], the
type of the literal is
unify(type_of_e_1, ..., type_of_e_n) + "[]". For instance:
=> typeof([ [], [1,2,3] ])
=> unify( typeof([]), typeof([1,2,3]) ) + "[]"
=> unify( "a[]", unify(typeof(1),typeof(2),typeof(3)) + "[]" ) + "[]"
=> unify( "a[]", unify("int","int","int") + "[]" ) + "[]"
=> unify( "a[]", "int" + "[]" ) + "[]"
=> unify( "a[]", "int[]" ) + "[]" // a is a local type var, subst =
{ a -> int }
=> "int[]" + "[]"
=> "int[][]"
Ok.
Walter: I told you :o).
I'd already defined the unify meta-function, it's called CommonType, see
http://www.digitalmars.com/d/2.0/phobos/std_traits.html#CommonType
You pass any number of types and it will figure out the type that all
types can be converted to. Using that, it is trivial to define functions
that infer array types properly. At a point I had an array() function
that took any number of arguments and returned a correctly-typed array.
Then I dropped that and defined array() in std with a different meaning
(transform a range into an array).
Andrei