0

I use Dart2JS Compiler version 1.0.0_r30798 (STABLE).

Sample code (only for introducing problem):

The real code here (now corrected for dart2js behavior): https://github.com/mezoni/queries/blob/master/lib/src/queries/lookup.dart

This is a part of Queryable collections for Dart language.

class ILookup<TKey, TElement> implements IEnumerable<IGrouping<TKey, TElement>> {
}

class Lookup<TKey, TElement> extends Object with Enumerable implements ILookup<TKey, TElement> {
}

class IEnumerable<T> implements HasIterator<T> {
}

class HasIterator<T> {
}

class IGrouping<TKey, TElement> implements IEnumerable<TKey> {
}

class Enumerable<T> implements IEnumerable<T> {
}

void main() {
  var obj = new Lookup();
  print(obj);
}

This code generates the following error of Google Dart dart2js Compiler:

 Internal Error: Inheritance of the same class with different type arguments is not
 supported: Both HasIterator<dynamic> and HasIterator<IGrouping<TKey, TElement>> are
 supertypes of Lookup<TKey, TElement>.
 class Lookup<TKey, TElement> extends Object with Enumerable implements ILookup<TKey,
 TElement> {

 ^^^^^
 Error: Compilation failed.

That is, the dart2js compiler cannot compile this code.

So, I cannot understand: " Is this bug, feature or limitation?".

mezoni
  • 10,684
  • 4
  • 32
  • 54
  • 3
    It's not possible to provide a reasonable answer to this question as it contains mostly random rants (as usual) and provides no information what was the expected result. 'I want the compiler to compile some random characters isn't really a question.' – Günter Zöchbauer Jan 12 '14 at 17:08
  • I made a small edit `with Enumerable impl` but as you provided no information besides `I want this to compile` I can't know what type parameter should be used here so I took one randomly. – Günter Zöchbauer Jan 12 '14 at 17:10
  • This code conforms to language spec. It not required your editing. – mezoni Jan 12 '14 at 17:12
  • 1
    @mezoni: Is there a question hidden somewhere in your post? If so please clarify. Unfortunately it looks to me mostly like ranting... – ronag Jan 12 '14 at 18:36

2 Answers2

3

First off, dart2js is NOT the Dart VM Compiler, to which the language specification applies. Because the Dart VM and Javascript are different languages, differing behaviour or restrictions in very abstract corner cases can happen. They shouldn't, but they do.

That being said, I don't understand why this code is able to run in the VM in the first place. According to everything I know about inheritance and mixins in Dart, your definition of Lookup should look like this:

class Lookup<TKey, TElement> extends Object with Enumerable<IGrouping<TKey, TElement>> implements ILookup<TKey, TElement>`

Because otherwise, as the error message says, you would inherit HasIterator two times with different type parameters, which of course is a little bit of a problem - if you finally add methods to HasIterator, which of those two should be called? method1(dynamic) or method1(IGrouping<TKey, TElement>)?

MarioP
  • 3,752
  • 1
  • 23
  • 32
  • MarioP, "So, is there a bug in the Dart VM? Probably, yes." This is not a bug. Here is answer to your question, your current answer and your issue: https://code.google.com/p/dart/issues/detail?id=16047#c5. In short words: "The VM behavior is correct, and dart2js isn't implementing it yet." – mezoni Jan 15 '14 at 05:38
  • @mezoni Your point being? I can accept the VM working as designed. I didn't expect it and I'm still confused (see follow-up post in the very link you posted), but the point is: From the very beginning, I wrote "differing behaviour or restrictions [...] can happen". You were provided a workaround, but instead chose to discuss why that shouldn't be necessary. You weren't looking for help, but for a discussion totally useless on SO and more appropiate for message boards and forums. In all honesty, I could imagine that's the reason why many of your questions don't get helpful answers anymore. – MarioP Jan 15 '14 at 09:27
  • Also, I reverted the answer back to it's original state and deleted the objectively wrong edit I added. – MarioP Jan 15 '14 at 09:28
  • MarioP, I have no claims against you but you said: "I could imagine that's the reason why many of your questions don't get helpful answers anymore". My answer to you: Not only my questions and not only here. Because in order to answer them will need to recognize unpleasant facts. I'm not surprised, because I speak the truth that may contains unpleasant facts (that may annoying group of some people). – mezoni Jan 15 '14 at 10:18
  • @mezoni That was in no way meant as an insult, but as honest-to-god advice: I can't speak about other platforms you may post or have posted to, but StackOverflow isn't a discussion platform. It is a platform to post problems to and, ideally, receive immediate solutions to said problems. And, as I said, it looks like this is not what you are looking for. This is much more annoying than some subjectively unpleasant facts. And from what I have seen in other SO questions of yours, I don't seem to be the only one who thinks like that. – MarioP Jan 15 '14 at 11:01
  • MarioP, Thanks, for explanation (receive immediate solutions to said problems). – mezoni Jan 15 '14 at 11:26
1

Answer from Dart Team is very well.

"The VM behavior is correct, and dart2js isn't implementing it yet."

https://code.google.com/p/dart/issues/detail?id=16047#c5

Also answer from Gilad Bracha.

"FWIW, the spec does not have such a restriction" (RE: class implements an interface with two different type parameters).

https://code.google.com/p/dart/issues/detail?id=14729#c2

Also very well mentioned:

"Unfortunately this is an intentional restriction in dart2js for now. Implementing the same interface with different type arguments has never really worked, so we felt very uncomfortable having people depend on the broken behavior."

https://code.google.com/p/dart/issues/detail?id=14729#c3

This answer fully fits in that the sample code in original question correct and it cannot be compiled currently via dart2js.

P.S.

My thoughts (my jumpers):

I think this problem can be solved in the Dart2JS compiler via better testing of type compatibility but not only via testing the equality of classes.

I think that in this case HasIterator<dynamic> and HasIterator<IGrouping<TKey, TElement>> is not the same types (even they the same classes) because they both just implicitly specifies lower and upper bounds of TElement parameter of HasIterator<TElement>.

In practice this is more complex that I can explain here but I can add the following.

They not the same types because this expression is true:

HasIterator<dynamic> != HasIterator<IGrouping<TKey, TElement>>

They not conflicts (but implicitly specifies lower and upper bounds) because one from the following expressions is true.

HasIterator<dynamic> is HasIterator<IGrouping<TKey, TElement>>
HasIterator<IGrouping<TKey, TElement>> is HasIterator<dynamic>

Is our case (implicit) lower bound is dynamic and (implicit) upper bound is <IGrouping<TKey, TElement>.

The implicit term means only resolved at compile time.

This means that one from them is a subtype of another and compiler must allow both of them in declaration. And in type annotations the compiler must tests parameters on compatibility with both of them (including other super interfaces).

If Dart2JS will test supertypes more thoroughly it can bypass around this problem.

I not want here give sample how this is possible but I think developers know how to solve this problem.

mezoni
  • 10,684
  • 4
  • 32
  • 54
  • You do sometimes have valuable opinion and questions baked into your rants and sometimes insulting posts. It would be great if you could also respect other peoples opinions the same way as you expect others respect yours, without insulting them. If you could just get past that I believe you could be quite valuable to the Dart community instead of what many people now find just annoying. – ronag Jan 13 '14 at 13:05
  • ronag, I think it would be better if it was not allowed (as you mentioned early). But developers found that it is permissible in the optionally typed Dart language allow implementing an interface with two different (but relevant by the variance) type parameters. – mezoni Jan 13 '14 at 13:35