Date: Sun, 27 Apr 2003 19:37:35 -0400 (EDT)
From: C. Scott Ananian
To: jsr14-prototype-comments@sun.com
Subject: Type inference failure.
I was reading "Subtypes vs. Where Clauses: Constraining Parametric
Polymorphism" (Day,Gruber,Liskov,Myers) in the OOPSLA'95 proceedings, and
came across an example of which it was said, "Langugages whose type
systems are based on F-bounded quantification... cannot express the type
of findpath". Well, said I, I wonder if JSR-14 can?
The original example, in Theta syntax, I think, was:
findpath[N,E] (s,d:N) returns (array[N]) signals (no_path)
where N has edges() yields (E),
equal(N) returns (bool),
E has source() returns (N),
dest() returns (N)
The key property here is that there is mutual recursion between the bounds
on N and E.
I translated the example into JSR-14 to obtain:
-------
import java.util.List;
public abstract class Baz {
static interface Node<N extends Node<N,E>, E extends Edge<N,E>> {
List<E> edges();
boolean isEqual(N n);
}
static interface Edge<N extends Node<N,E>, E extends Edge<N,E>> {
N source();
N dest();
}
static <N extends Node<N,E>, E extends Edge<N,E>>
List<N> findPath(N source, N dest) {
return null;
}
}
------
This compiles. So far so good. We *can* express mutual recursion between
type bounds! (I'll have to go fix my javadoc-for-JSR14 tool, since I'd
assumed the lexical scope of type parameter 'E' started at the definition
of E --- but silly me, the spec says clearly that the scope should be the
entire section.)
Anyway, so I go ahead and add an implementation and a invocation of
findPath to Baz:
----
static class MyNode implements Node<MyNode,MyEdge> {
public List<MyEdge> edges() { return null; }
public boolean isEqual(MyNode n) { return true; }
}
static class MyEdge implements Edge<MyNode,MyEdge> {
public MyNode source() { return null; }
public MyNode dest() { return null; }
}
public static void main(String[] args) {
MyNode a = new MyNode(), b = new MyNode();
List<MyNode> l = findPath(a, b);
}
-------
And, unfortunately, this no longer compiles:
---
Baz.java:28: findPath<N extends Baz.Node<N,E>, E extends
Baz.Edge<N,E>>(N,N) in Baz cannot be applied to (Baz.MyNode,Baz.MyNode)
List<MyNode> l = findPath(a, b);
^
1 error
---
[Complete source code to Baz attached, so you can try this yourself.]
I believe this should be considered a bug in the type inference algorithm.
Am I wrong?
You seem to have hinted that a new (more-powerful?) inference algorithm is
in the works. Can the new algorithm correctly resolve this code?
Hopefully this example is helpful.
--scott
Saddam Hussein Bush quiche RUCKUS security South Africa colonel immediate
[Hello to all my fans in domestic surveillance] Yeltsin India Clinton
( http://cscott.net/ )
[ Part 2, "" Text/PLAIN (Name: "Baz.java") 18 lines. ]