Are function types a requirement?
Reinier Zwitserloot
reinier at zwitserloot.com
Thu Feb 18 15:56:50 PST 2010
Sure, alex, varargs being generified is a superior solution on the face of
it compared to my somewhat hacky 'disallow anything that would lose dynamic
type safety', but, it's pragmatic. I've made the following assumptions:
1. Changing varargs to become List (well, generics, could be anything) based
is very very unlikely as there's no way to do it without breaking backwards
compatibility.
2. While my rules may seem arbitrary when you don't know why they are being
applied, the enjoy the advantage that 99.99999% of all actual usage of
varargs out there already adheres to them; in my experience the only thing
anyone ever does with varargs params is check them against null
occasionally, and other than that loop through them either via .length /
array acces, or foreach. In the exceedingly rare cases where my rules are
broken, the warning is definitely warranted, and should probably be reworded
in more stern language, treating a vargs parameter as a standard array and
doing dynamic type modifications on it _really_ is going to bite you in the
behind.
Perhaps the proposal can be reframed to say that the compiler assumes the
varargs parameter is in fact like <? extends X> generics, and when treating
it that way leads to type errors, the warning is generated. If it doesn't,
no warning is needed. That may help keep the size of the JLS change
managable.
Either way, it solves the varargs problem for the *vast majority* of
real-world varargs use in a totally transparent way, and it can be
implemented without any worry about backwards compatibility. That's gotta
worth some points.
--Reinier Zwitserloot
On Thu, Feb 18, 2010 at 9:16 PM, Alex Buckley <Alex.Buckley at sun.com> wrote:
> Reinier Zwitserloot wrote:
> > On a different note, generified varargs are legal. You just get a
> warning.
>
> This is effectively incorrect.
>
> A varargs formal parameter that is parameterized ought to be illegal.
> (At least where varargs are implemented with arrays.)
>
> It breaks the property that static type correctness implies dynamic type
> safety. We allow such a parameter only for convenience. A warning
> indicates that you are being allowed to hang yourself for your own
> convenience. The word "just" has no place here.
>
> What you propose below (and it's really very clever) is to strengthen
> the static type system in the body of a varargs method. Your rules are
> so strong that if the body is statically type correct, then it will be
> dynamically type safe. You have achieved this by basically banning any
> language construct whose static typechecking involves subtype rules. For
> example, aliasing the varargs formal parameter through an Object[] - the
> usual way to lose dynamic type safety - is banned in your static type
> system, and code that did it would cause a warning.
>
> I discussed restrictions of this kind extensively with Josh Bloch and
> Bob Lee before Bob's Coin proposal. The summary is that I'm not a fan,
> which is why the proposal doesn't change the static type system and thus
> requires a very strong programmer declaration that the method body will
> be dynamically type safe promise promise promise.
>
> (Strictly speaking, I'm not a fan of building this alternative static
> type system *on top of array-based varargs*. You get your strong static
> typechecking for free with covariant generics. That is, if a varargs
> formal parameter of type Foo<String>... was translated to List<? extends
> Foo<String>>, the method body would be suitably restricted. Redefining
> varargs in this way is not in scope for Project Lambda.)
>
> All the above applies whether the varargs formal parameter is a
> parameterized type or a function type. Neither kind of type is going to
> be reified in the near future.
>
> Alex
>
> > However, that warning is moving to the target method (it's one of project
> > coin's features). I proposed at the time that this warning too can be
> > eliminated if the following holds:
> >
> > The array variable is only read from, iterated over (foreach), or a
> > method/field access (.length, .toString()) done on it.
> >
> > Or, to be more specific:
> >
> > 1. The array variable is not used in any expression, even as a primitive
> > (Object o = varargsParam;), except for:
> >
> > 1A. LHS of a method invocation, so, varargsParam.toString() is
> acceptable
> > (not much use in doing it, but it won't cause the warning).
> >
> > 1B. LHS of a field access, so, varargsParam.length is okay.
> >
> > 1C. Used as a primitive expression as the iterable in a foreach, so, for
> (T
> > x : varargsParam) is okay.
> >
> > 2. array assignment to the varargsParam does not occur. So,
> > varargsParam[expr] = whatever; means the warning appears.
> >
> >
> > If the varargs method adheres to all these rules, then the warning is not
> > shown. None of this seems prohibitive to scan for (none of it requires
> type
> > resolution, for example), it's sufficient for type failures due to lack
> of
> > reification to be impossible, and (guesstimating) it'll cover 99%+ of all
> > uses of varargs out there.
>
>
More information about the lambda-dev
mailing list