Java Language Specification - Generics

E

E11

Hi,

In section 4.5 of the Java Language Specification, there is such a
paragraph:

A parameterized type consists of a class or interface name C and an
actual type argument list <T1 , ... , Tn>. It is a compile time error
if C is not the name of a generic class or interface, or if the number
of type arguments in the actual type argument list differs from the
number of declared type parameters of C. In the following, whenever we
speak of a class or interface type, we include the generic version as
well, unless explicitly excluded. Throughout this section, let A1 , ...
, An be the formal type parameters of C, and let be Bi be the declared
bound of Ai. The notation [Ai := Ti] denotes substitution of the type
variable Ai with the type Ti, for 1=i=n, and is used throughout
this specification.

Let P = G<T1, ..., Tn> be a parameterized type. It must be the case
that, after P is subjected to capture conversion (§5.1.10) resulting
in the type G<X1, ..., Xn>, for each actual type argument Xi,
1=i=n, Xi <: Bi[A1 := X1, ..., An := Xn] (§4.10), or a compile
time error occurs.

There are a few things that i don't quite understand.

1. What is the meaning of "Xi <: Bi[A1 := X1, ..., An := Xn]"? i know
that Xi <: Bi means that Xi is a sub-class of Bi, but what does it mean
to have all that stuff in square parentheses after Bi?

2. What is capture conversion? It is explained in §5.1.10, but i don't
quite understand the explanation. Anyone able to do it in more layman
terms?



Thanks in Advance,
Edwin
 
J

John C. Bollinger

E11 said:
Hi,

In section 4.5 of the Java Language Specification, there is such a
paragraph:

A parameterized type consists of a class or interface name C and an
actual type argument list <T1 , ... , Tn>. It is a compile time error
if C is not the name of a generic class or interface, or if the number
of type arguments in the actual type argument list differs from the
number of declared type parameters of C. In the following, whenever we
speak of a class or interface type, we include the generic version as
well, unless explicitly excluded. Throughout this section, let A1 , ...
, An be the formal type parameters of C, and let be Bi be the declared
bound of Ai. The notation [Ai := Ti] denotes substitution of the type
variable Ai with the type Ti, for 1=i=n, and is used throughout
this specification.

Let P = G<T1, ..., Tn> be a parameterized type. It must be the case
that, after P is subjected to capture conversion (§5.1.10) resulting
in the type G<X1, ..., Xn>, for each actual type argument Xi,
1=i=n, Xi <: Bi[A1 := X1, ..., An := Xn] (§4.10), or a compile
time error occurs.

There are a few things that i don't quite understand.

1. What is the meaning of "Xi <: Bi[A1 := X1, ..., An := Xn]"? i know
that Xi <: Bi means that Xi is a sub-class of Bi, but what does it mean
to have all that stuff in square parentheses after Bi?

It's described in the first paragraph. It means that the actual type
arguments are substituted in place of the formal type variables in order
to determine the actual bounds.
2. What is capture conversion? It is explained in §5.1.10, but i don't
quite understand the explanation. Anyone able to do it in more layman
terms?

As best I understand the text, it is describing a conversion wherein
wildcard type arguments are interpreted in terms of the bounds of the
corresponding type parameters.

The whole section you quoted seems to be defining the semantics of
bounded and unbounded wildcard type variables. That is, the details
governing the fact that you can assign a List<Integer> to a variable of
type List<? extends Number>, but you can't assign a List<String> to that
variable.
 
E

E11

Hi John, your last paragraph went some way in helping me understand
those symbols... its a little clearer now.
1. What is the meaning of "Xi <: Bi[A1 := X1, ..., An := Xn]"? i know
that Xi <: Bi means that Xi is a sub-class of Bi, but what does it mean
to have all that stuff in square parentheses after Bi?

It's described in the first paragraph. It means that the actual type
arguments are substituted in place of the formal type variables in order
to determine the actual bounds.

So, what it means is...
Ai, i = 1..n are the formal type parameters of C
Bi is the declared bound of Ai, i = 1..n (hmm... but is it upper bound
or lower bound?)
If we do a substitution of Ai for Xi, i = 1..n,
then it is necessary that Xi is a sub-type of Bi, i = 1..n, or a
compile time error occurs.

hmm... does that make sense?

i think the issue i face regarding "for each actual type argument Xi, i
= 1..n, Xi <: Bi[A1 := X1, ..., An := Xn]", is due to the scope of "[A1
:= X1, ..., An := Xn]" with respect to the scope of the universal
qualifier.

In other words, if we use parentheses to represent scope, does the
above mean
"for each actual type argument Xi, i = 1..n, (Xi <: Bi[A1 := X1, ...,
An := Xn])"
or
"(for each actual type argument Xi, i = 1..n, Xi <: Bi)[A1 := X1, ...,
An := Xn]"
?



Thanks and Regards,
Edwin
 
J

John C. Bollinger

E11 said:
Hi John, your last paragraph went some way in helping me understand
those symbols... its a little clearer now.

I hope it's both clear and correct. I'm feeling my way on this one --
formal type theory is not one of my areas of expertise.
John said:
1. What is the meaning of "Xi <: Bi[A1 := X1, ..., An := Xn]"? i know
that Xi <: Bi means that Xi is a sub-class of Bi, but what does it mean
to have all that stuff in square parentheses after Bi?

It's described in the first paragraph. It means that the actual type
arguments are substituted in place of the formal type variables in order
to determine the actual bounds.


So, what it means is...
Ai, i = 1..n are the formal type parameters of C
Bi is the declared bound of Ai, i = 1..n (hmm... but is it upper bound
or lower bound?)

Either one. You can't have both for any single type parameter (more's
the pity). See also below.
If we do a substitution of Ai for Xi, i = 1..n,
then it is necessary that Xi is a sub-type of Bi, i = 1..n, or a
compile time error occurs.

hmm... does that make sense?

I think "subtype" isn't quite the right term, because the Bi aren't
types, they're *bounds* (i.e. "extends Comparable<Foo>" rather than just
Comparable said:
i think the issue i face regarding "for each actual type argument Xi, i
= 1..n, Xi <: Bi[A1 := X1, ..., An := Xn]", is due to the scope of "[A1
:= X1, ..., An := Xn]" with respect to the scope of the universal
qualifier.

In other words, if we use parentheses to represent scope, does the
above mean
"for each actual type argument Xi, i = 1..n, (Xi <: Bi[A1 := X1, ...,
An := Xn])"
or
"(for each actual type argument Xi, i = 1..n, Xi <: Bi)[A1 := X1, ...,
An := Xn]"
?

The first, I think; the second doesn't make any sense to me. You must
evaluate each bound in light of all of the actual type parameters, and
in each case you must perform that evaluation before you can evaluate
the <: operation.
 
E

E11

John said:
"for each actual type argument Xi, i = 1..n, (Xi <: Bi[A1 := X1, ...,
An := Xn])"

The first, I think; the second doesn't make any sense to me. You must
evaluate each bound in light of all of the actual type parameters, and
in each case you must perform that evaluation before you can evaluate
the <: operation.

That's actually kinda confusing... so the above actually means

X1 <: B1[A1 := X1, ..., An := Xn], and ..., and
Xn <: Bn[A1 := Xn, ..., An := Xn]

As in, why do we have to repeat the [...] for every Xi and Bi?

Why is it not sufficient to say

X1 <: B1[A1 := X1], and ..., and Xn <: Bn[An := Xn]
or say
X1 <: B1, and ..., and Xn <: Bn, [A1 := Xi, ..., An := Xn]
?

i sort of vaguely recall seeing such a notation before when i was in
college, i think it was in a programming languages, or a computability
theory module... should have tried to stay awake then...



Thanks and Regards,
Edwin
 
J

John C. Bollinger

E11 said:
John said:
"for each actual type argument Xi, i = 1..n, (Xi <: Bi[A1 := X1, ...,
An := Xn])"

The first, I think; the second doesn't make any sense to me. You must
evaluate each bound in light of all of the actual type parameters, and
in each case you must perform that evaluation before you can evaluate
the <: operation.


That's actually kinda confusing... so the above actually means

X1 <: B1[A1 := X1, ..., An := Xn], and ..., and
Xn <: Bn[A1 := Xn, ..., An := Xn]

That's my reading, yes.
As in, why do we have to repeat the [...] for every Xi and Bi?

Because each bound needs to be interpreted in light of all the actual
type parameters. This may not be evident in simple type expressions,
but it will rear its head in some complex type expressions. (If you
feel a breeze, it's from all the hand waving I'm doing.)
 
E

E11

John said:
That's my reading, yes.
As in, why do we have to repeat the [...] for every Xi and Bi?

Because each bound needs to be interpreted in light of all the actual
type parameters. This may not be evident in simple type expressions,
but it will rear its head in some complex type expressions. (If you
feel a breeze, it's from all the hand waving I'm doing.)

hmm... i really don't understand this point... sorry if its frustrating
for you, but it is possible to use an example to illustrate this point?



Many Thanks,
Edwin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top