LJC Lambdas Hackday
David Conrad
drconrad at gmail.com
Mon Jun 4 09:35:03 PDT 2012
On Mon, Jun 4, 2012 at 10:51 AM, Brian Goetz <brian.goetz at oracle.com> wrote:
> > Okay, so there are two ways to fix this. One is to use more powerful,
> > global type inference, but that has undesirable effects.
>
> Right.
>
> > Okay, now go open up Iterable.java and count the number of into
> > methods. :) (Forgive me for being overly cute; couldn't resist.)
>
> Duh. We've of course considered this. (Forgive me for being overly
> dismissive; couldn't resist :)
>
>
I think I earned that. :)
> But the problem is, it is a hack that doesn't really get you very far, and
> pretty soon we're having the exact same conversation -- because the
> underlying "gah, why doesn't the compiler know this, it is obvious" hasn't
> really been addressed, its just been moved around. It is brittle (as soon
> as you add an overloading, it reduces to the same problem), irregular, and
> would likely cause problems down the road if we wanted to extend inference
> further in more sane ways. If there was some reason to believe that
> overloadings in cases like this would never come up, we might be more
> inclined to think about it, but we have no reason to believe that the lack
> of overloadings here is not just an accident.
>
> The problem with hacking type inference is that it is an endless loop of:
>
> - Someone finds a case where type inference fails, but the right answer
> is "obvious"
> - Endless machinations and distortions ensue to try and make that case
> "go away"
> - Go to step 1
>
> > Obviously you know better than I whether this can work, but it
> > would make ::into a whole lot nicer without requiring much more
> > smarts from type inferencing. In particular, it doesn't require any
> > global inferencing, only knowledge about the receiver, which it
> > must have to even begin overload resolution.
>
> It would most definitely work. But we would much rather find a better
> solution.
>
>
You're right. (As usual. I continue to be impressed by how hard the Oracle
folks
have clearly thought about these problems.)
Okay, let me try again. Suppose we have several overloads of ::into:
<A extends Fillable<? super T>> A into(A target);
<A extends List<? super T>> A into(A target);
<A extends Collection<? super T>> A into(A target);
(Or some more exotic versions no one has thought of yet.)
We're trying to compile:
sequence.filter(Some::filter).into(new ArrayList<>());
The compiler has the following information: sequence is a
List<Car>, filter takes a Predicate<? super Car> and
returns Iterable<Car> which is what into receives. We're
trying to decide among its overloads, and can't tell if we're
going to have a Fillable<? super Car> or a List<? super Car>
or a Collection<? super Car>, but no matter which one we
end up with, we will have a X<? super Car>.
Can we represent the type as a union type as we dig down
into the arguments, or does that just get us back to the
global type inference that you're hesitant to go to already?
What about extracting just the common portion of the type
information, rather than full-fledged union types? So overload
resolution proceeds knowing just that it wants a type variable
T == ? super Car.
This would work for n overloads, but only so long as they
shared common generic types.
(The type exists in a superposition of states until the
overload resolution collapses the wave function.)
At this point, I would be surprised if you hadn't considered
and rejected this, too, but I had to try. :)
Cheers,
David
More information about the lambda-dev
mailing list