Overload resolution simplification

Ali Ebrahimi ali.ebrahimi1781 at gmail.com
Wed Aug 21 02:14:50 PDT 2013


ops.
I mean correct. just typo.


On Wed, Aug 21, 2013 at 1:40 PM, Ali Ebrahimi <ali.ebrahimi1781 at gmail.com>wrote:

> Hi,
>
>
> On Wed, Aug 21, 2013 at 10:39 AM, Howard Lovatt <howard.lovatt at gmail.com>wrote:
>
>> Possible type inference algorithm using type checking of Lambdas (with
>> examples below to show that it works well):
>>
>> I. Start with the outer-most method call, declaration, or assignment and
>> work inwards and then left to right.
>> II. For methods select a set of candidate methods based on known types,
>> method name, and number of arguments and note the lambda candidate types.
>> For declared types note the type. For assignments note the destination
>> type.
>> III. For each candidate type signature check the lambda including the
>> return type against the candidate types and if the type check fails
>> eliminate that candidate. This step whilst primarily eliminating
>> candidates
>> may add candidates because there may be multiple candidates for a given
>> method/declaration/assignment based on multiple super-types of signatures.
>> This stage, III., and the next, IV., may be usefully combined to make the
>> process quicker. The process may also be carried out in parallel.
>> IV. Choose from the remaining candidates the candidate method that is the
>> best fit (least number of conversions - sum of conversion required for
>> argument types and return type).
>> V. If there are methods that are equally good fit issue an error giving
>> the
>> possible methods.
>>
>> The above algorithm is simple and doesn't involve complicated speculation
>> about types, i.e. it works in a forward direction form signatures through
>> lambda argument types to the lambda's return type. As shown below through
>> a
>> series of examples the algorithm works well and doesn't produce any
>> surprises.
>>
>> In all cases below the unkown type of a single lambda argument, a, is A
>> and
>> for multiple arguments, a1, a2, ..., the types are A1, A2, ..., similarly
>> an unknown return type is R and multiple are R1, R2, ...
>>
>> Maurizio's Examples (Lambda Experts Group email)
>> ================================================
>> class Mappers<T> {
>>   IntSream map(IntFunction<T> if) {...}
>>   <Z> Stream<Z> map(Function<T, Z> f) {...}
>>   <U> IntStream map(Stream<U> s, IntFunction<U> if) {...}
>>   <U, V> Stream<V> map(Stream<U> s, Function<U, V> f) {...}
>> }
>>
>> Mappers<String> ms = ...;
>> ms.map(a->1);                  // Ex. 1
>> ms.map(a->'A');                // Ex. 2
>> Stream<String> ss = ...;
>> Mappers.map(ss, a->1);   // Ex. 3
>> Mappers.map(ss, a->'A'); // Ex. 4
>>
>> Ex. 1: ms.map(a->1)
>> -------------------
>> 1. From the scope, function name, and number of arguments there are two
>> possible functions map(IntFunction<String>) and map(Function<String, Z)
>> and
>> in both cases A = String and therefore A must be String.
>> 2. Therefore (String a)->1 is either i. an IntFunction<String> (R = int)
>> or
>> ii. a Function<String, Z> (R = Object).
>> 3. Type check option i., R = int, and this is OK since 1 is an int.
>> 4. Type check option ii., R = Object, and this is OK since 1 could be
>> autoboxed to an Integer.
>> 5. Choose option i. because it doesn't require boxing.
>>
>> Ex. 2: ms.map(a->'A')
>> ---------------------
>> 1. From the scope, function name, and number of arguments there are two
>> possible functions map(IntFunction<String>) and map(Function<String, Z)
>> and
>> in both cases A = String and therefore A must be String.
>> 2. Therefore (String a)->'A' is either i. an IntFunction<String> (R = int)
>> or ii. a Function<String, Z> (R = Object).
>> 3. Type check option i., R = int, and this fails since 'A' is not
>> automatically convertible to int.
>>
> This is not current. java can widen chars into ints from early days.
>
>
> 4. Type check option ii., R = Object, and that is OK since 'A' could be
>> autoboxed to a Character.
>> 5. Therefore ii.
>>
> Widening wins over Boxing and Unboxing. So answer would be i.
>
>
>
>> Ex. 3: Mappers.map(ss, a->1)
>> ----------------------------
>> 1. From the scope, function name, and number of arguments there are two
>> possible functions map(Stream<String>, IntFunction<String>) and
>> map(Stream<String>, Function<String, Z) and in both cases U = A = String
>> and therefore both U and A must be String.
>> 2. Therefore (String a)->1 is either i. an IntFunction<String> (R = int)
>> or
>> ii. a Function<String, Z> (R = Object).
>> 3. Type check option i, R = int, and this is OK since 1 is an int.
>> 4. Type check option ii, R = Object, and this is OK since 1 could be
>> autoboxed to an Integer.
>> 5. Choose option i. because it doesn't require boxing.
>>
>> Ex. 4: Mappers.map(ss, a->'A')
>> ------------------------------
>> 1. From the scope, function name, and number of arguments there are two
>> possible functions map(Stream<String>, IntFunction<String>) and
>> map(Stream<String>, Function<String, Z) and in both cases U = A = String
>> and therefore U and A must be String.
>> 2. Therefore (String a)->'A' is either i. an IntFunction<String> (R = int)
>> or ii. a Function<String, Z> (R = Object).
>> 3. Type check option i., R = int, and this fails since 'A' is not
>> automatically convertible to int.
>>
> So this is also not currect. See above.
>
> 4. Type check option ii., R = Object, and that is OK since 'A' could be
>> autoboxed to a Character.
>> 5. Therefore ii.
>>
> Answer: i ->  See above.
>
> May be you can read my proposal.
>
> http://mail.openjdk.java.net/pipermail/lambda-spec-observers/2013-August/000489.html
>
>
> Ali Ebrahimi
>
>


More information about the lambda-spec-observers mailing list