Profile cover photo
Profile photo
Pär Eklund
222 followers
222 followers
About
Pär's posts

Post has attachment
[Programming Question/Reply via email posted here for public access]

Generic class hierarchy and mutual recursive type bounds

Pär Eklund
Jan 31

to wadler 
Dear Mr. Wadler, ...

PURPOSE

I have a private project where I am implementing a class hierarchy in Java and want to use generics for optimal extensibility and type safety. 

THE NEED FOR MUTUAL RECURSIVE TYPE BOUNDS

In doing so, I quickly realised the need to parameterise each class with a type bound for each class known to said class, which directly leads to recursive type bounds such as:

public class Player
<
   L extends Level<L, P>, 
   P extends Player<L, P>, 
> { ...}

public class Level
<
   L extends Level<L, P>, 
   P extends Player<L, P>
> { ... }

The problem is that this quickly becomes unwieldly, since it requires modifying the header for every class in the hierarchy as soon as another class is added. Apart from the maintenance problem, comprehension is impeded which can be illustrated by the following example:

public interface Projectile
  <
    GC extends ActionGameComponent<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    S extends ActionGameComponentState,
    L extends ActionGameLevel<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    P extends ActionGamePlayer<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    EN extends Enemy<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    CO extends Collectable<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    A extends ActionGameActor<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    EX extends Exit<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    PR extends Projectile<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    CS extends Consumable<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    I extends Inventory<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    II extends InventoryItem<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    GU extends Gun<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    AM extends Ammo<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    VA extends Valuable<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    ENG extends GroundBasedEnemy<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    ENA extends AirBasedEnemy<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    WE extends Weapon<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>,
    IL extends InventoryListener<GC, S, L, P, EN, CO, A, EX, PR, CS, I, II, GU, AM, VA, ENG, ENA, WE, IL>
    >
  extends GameComponent<S, L> {
  A getOwner();
  int getDamage();
}

Seeing that only type bound A is actually used in the body, makes this feel even more "wrong" (even though I understand that the definition of the A type bound is recursively defined by the other type bounds).

Also, applying wildcards instead of type bounds to avoid the recursion will not work (to my experience and as I believe confirmed by your book Java Generics).

Thus my question: Would you know whether there is a better way to do this or if I have encountered a(n arguable) limitation in the Java Generics implementation?

Sincerely

/Par Eklund

Philip Wadler 
Jan 31

to Gilad, Maurice, me 
Thank you for your note. Yes, you have encountered a limitation in Java. One technique for dealing with these sorts of mutual bounds is to use type families, see this paper:

http://homepages.inf.ed.ac.uk/wadler/topics/gj.html
A statically safe alternative to virtual types

Kim B. Bruce, Martin Odersky, and Philip Wadler. European Conference on Object-Oriented Programming (ECOOP 98), Brussels, July 1998. Extended abstract in: Workshop on Foundations of Object-Oriented Languages (FOOL 5), San Diego, January 1998.
Parametric types and virtual types have recently been proposed as extensions to Java to support genericity. In this paper we examine both in order to investigate the strengths and weaknesses of each. We suggest a variant of virtual types which has similar expressiveness, but supports safe static type checking. This results in a language in which both parametric types and virtual types are well-integrated, and which is statically type-safe.

Available in: dvi, ps, dvi.gz, ps.gz, Springer web site.

You may also want to look at languages such as Beta and Newspeak, which make it easy to construct mutually dependent families of types. Yours, -- P

.   \ Philip Wadler, Professor of Theoretical Computer Science
.   /\ School of Informatics, University of Edinburgh
.  /  \ http://homepages.inf.ed.ac.uk/wadler/

Post has attachment

Post has shared content
Very true
The real secrets behind Apple's success

Ever wondered why Apple is so popular? Hint: it's about a heck of a lot more than just good marketing -- though that certainly helps a lot. 

Post has attachment

Post has attachment

Post has attachment

Post has attachment
Wait while more posts are being loaded