Open pusolito opened 9 years ago
@RossTate thoughts? Are wildcards in upper bounds OK?
Oops, I just saw this. As I mentioned in the thread, that's not necessary to solve the problem. You probably just have a glitch in importing the wildcard in the inheritance clause.
Here are the reductions that prove that the LocalDateTime
case should be rejected and the ChronoLocalDateTime<LocalTime>
cause should be accepted.
LocalDateTime
case
LocalDateTime <: Comparable<LocalDateTime>
Comparable<ChronoLocalDateTime<?>> <: Comparable<LocalDateTime>
(by inheritance)LocalDateTime <: ChronoLocalDateTime<?>
(by contravariance)ChronoLocalDateTime<LocalTime>
case
ChronoLocalDateTime<LocalTime> <: Comparable<ChronoLocalDateTime<LocalTime>>
Comparable<ChronoLocalDateTime<?>> <: Comparable<ChronoLocalDateTime<LocalTime>>
(by inheritance)ChronoLocalDateTime<LocalTime> <: ChronoLocalDateTime<?>
(by contravariance)?
@RossTate,
To clarify, this following code does not compile with Ceylon IDE 1.1.1.v20150721-1337-Final. The imports from Java are correct and verified.
Can you provide more specifics on how to get this working in the ChronoLocalDateTime
import java.lang {Comparable,Double}
import java.time {LocalDateTime, LocalDate}
import java.time.chrono {ChronoLocalDateTime}
A<T> bar<T>(A<T> t) given T satisfies Comparable<T> => t;
void test() {
bar<Double>(A<Double>());
bar<LocalDateTime>(A<LocalDateTime>());
bar<ChronoLocalDateTime<LocalDate>>(A<ChronoLocalDateTime<LocalDate>>());
}
Or are you saying this doesn't work b/c of a separate bug within the import handling?
Correct. And the feature proposed hear would not solve any of the problems. So I think this would be better classified as an issue for the compiler rather than for the spec. However, I'd first like @gavinking to chime in to confirm that my reasoning is sound.
Also, the LocalDateTime
case will never work because it would be unsound to accept that. According to its definition, LocalDateTime
is a subtype of Comparable<ChronoLocalDateTime<?>>
, but that is not a subtype of Comparable<LocalDateTime>
because Comparable
is _contra_variant, not _co_variant (i.e. in
not out
).
Actually, java.lang.Comparable
is invariant since Java does not have declaration-site variance information.
@RossTate
ChronoLocalDateTime<LocalTime> <: Comparable<ChronoLocalDateTime<LocalTime>>
Where do you get that from? The declaration is:
public interface ChronoLocalDateTime<D extends ChronoLocalDate>
extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDateTime<?>> { ... }
i.e. ChronoLocalDateTime<LocalTime>
is a subtype of Comparable<ChronoLocalDateTime<?>>
but the typechecker is complaining that it's not a subtype of Comparable<ChronoLocalDateTime<LocalTime>>
@RossTate
Comparable<ChronoLocalDateTime<?>> <: Comparable<ChronoLocalDateTime<LocalTime>>
(by inheritance)
I'm also not seeing this one. Comparable
is an invariant Java type, and ChronoLocalDateTime<?>
isn't the same type as ChronoLocalDateTime<LocalTime>
. So I don't think that step is correct at all. It would be correct for Ceylon's contravariant Comparable
, but due to variance, not by inheritance.
ChronoLocalDateTime<LocalTime> <: ChronoLocalDateTime<?>
(by contravariance)
This is sound, but not quite for the stated reason: we treat ChronoLocalDateTime<?>
as ChronoLocalDateTime<out Anything>
in the model loader. So actually it's true by covariance ;-)
You're misreading my proofs because I wrote them backwords. Read them as "in order to prove step 1, we must prove step 2, which then requires step 3, which then holds or doesn't hole due to step 4". The parentheticals indicate why the prior step reduces to that step.
Also, since it sounds like you're not inferring that Java's Comparable
is contravariant, the signature of bar
should be the following:
A<T> bar<T>(A<T> t) given T satisfies Comparable<in T> => t;
Try that. If that works, then the problem was that @pusolito gave bar
an unnecessarilly restrictive signature. If that doesn't work, then there's a glitch in the type importer or type checker.
the signature of
bar
should be the following:bar (A t) given T satisfies Comparable => t;
Right, precisely! That's exactly what I wrote in the issue description!
The problem is that right now we never allow a wildcard instantiation of a supertype, not even for type parameters (i.e. upper bounds). So I can't write that.
Ohh, sorry, I didn't realize you were calling Comparable<in T>
in Ceylon a wildcard instantiation. (It's technically just a use-site annotation.) So, yes, you should allow use-site annotations in bounds. My proofs already handle that.
@RossTate cool, thanks.
Ceylon doesn't support wildcard in the upper bound which prevents interacts with Java like the following:
From @gavinking: