ceylon-dart icon indicating copy to clipboard operation
ceylon-dart copied to clipboard

interop mapping for classes that act like interfaces

Open jvasileff opened this issue 9 years ago • 8 comments

In Dart, all classes can be used as interfaces. The Ceylon translation would be:

class MyClass satisfies SomeOtherClass { ... }

which of course is not legal in Ceylon.

There seems to be no option but to have each Dart class map to two separate types: a Ceylon interface and a Ceylon class that satisfies that interface.

Either the class or interface will need a synthetic name.

Scenario 1: Use class DartClass and interface I_DartClass

  • The model loader would map parameters and returns of type DartClass to I_DartClass
  • Use of DartClass for parameter types in Ceylon code would be discouraged; I_DartClass should be used instead, for maximum flexibility.
  • The identifier DartClass would be use for instantiations and extensions in Ceylon code (e.g. DartClass() and ... extends DartClass().
  • I_DartClass would be erased to DartClass by the backend compiler.

Scenario 2: Use class C_DartClass and interface DartClass

  • Parameters and returns would be of the type DartClass.
  • Use of C_DartClass for anything other than instantiations and extensions would be discouraged.
  • C_DartClass would be erased to DartClass by the backend compiler.

Perhaps Scenario 2 is the most natural, since the synthetic name would be used less frequently, and when needed (for instantiation & extension), its use would be forced by the typechecker.

A further concern is that classes DartClass_A and DartClass_B that do not share a subtyping relationship are not guaranteed to be disjoint, which breaks Ceylon's type system. Adopting scenario 2 (which helps reduce unintentional use of the identifier that maps to the class) should help to avoid this unsoundness.

jvasileff avatar Feb 07 '16 16:02 jvasileff

Especially considering the disjointness problem, it seems to me like the class types shouldn’t be visible at all. Is it possible to make DartClass mean the class in expressions and the interface in types? I. e.:

// Interface      Class
   DartClass c1 = DartClass();

// Interface        Class
   DartClass() c2 = DartClass;

// Interface
   DartClass c3 = c2();

Another question: do native ("dart") Ceylon classes, or perhaps even any Ceylon classes within native ("dart") code, exhibit the same behavior?

lucaswerkmeister avatar Feb 07 '16 16:02 lucaswerkmeister

Is it possible to make DartClass mean the class in expressions and the interface in types?

Without typechecker support, it would be possible to map Dart constructors to static factory methods. But we'd still be without the ability to extend Dart classes, which may be too limiting/inconvenient.

Beyond that, I'm not sure.

do ... Ceylon classes ... exhibit the same behavior?

Good point. There is no way to prevent things like a Dart class implementing ceylon.language::Sequence. But I'm not convinced it's useful for Dart code to consume Ceylon types except in special cases such as when implementing parts of the language module.

jvasileff avatar Feb 07 '16 17:02 jvasileff

In Dart, all classes can be used as interfaces.

What precisely does this mean? Does Dart support multiple inheritance for classes? Or, when I "satisfy" a class, do I have to reimplement all its operations?

I don't understand the semantics here.

gavinking avatar Feb 17 '16 14:02 gavinking

There are no interfaces, only classs which may be abstract. There are three ways to inherit a Dart class:

  1. A class may extend one other class
  2. A class may implement zero or more other classes. When implementing a class, the implementations of it's members are not copied into the new class.
  3. A class may mixin zero or more other classes using with. Implementations of the mixed-in class's members are copied into the new class (but not implementations of the mixed-in class's supertypes). Mixed-in classes must not define a constructor.

This issue is primarily focussed on 1 & 2, since I'm not sure 3 adds any additional complexity to subtyping.

jvasileff avatar Feb 17 '16 17:02 jvasileff

@jvasileff OK, then could we model this as:

  1. Dart class => Ceylon interface
  2. Dart constructor => Ceylon function

Wouldn't that capture the semantics, without requiring strange generated names?

gavinking avatar Feb 19 '16 13:02 gavinking

Yes, I think it's a good idea to map constructors to static functions, but we still need a class to support extending Dart classes in Ceylon.

We also need a name for the functions for default (nameless) Dart constructors.

jvasileff avatar Feb 19 '16 16:02 jvasileff

The current implementation status is that we have:

  • Dart Class => Ceylon interface of the same name, and
  • ~~Dart Class => Ceylon class named like DartClass_C, and~~
  • Dart Class => Ceylon static member class named like DartClass.Class

~~Of the second two, I'm leaning towards keeping the last.~~

Gotchas are:

  • Static references to constructors in Ceylon are not very useful since they require an instance of the class as an argument, which is a subtype of the interface that is more commonly used/exposed.
  • The non-disjointedness problem in the issue description.

10/16/2016 edit: classes like DartClass_C are no longer generated.

jvasileff avatar Feb 19 '16 16:02 jvasileff

I like the static inner class. Makes sense to me.

Sent from my iPhone

On 19 Feb 2016, at 17:12, John Vasileff [email protected] wrote:

The current implementation status is that we have:

Dart Class => Ceylon interface of the same name, and Dart Class => Ceylon class named like DartClass_C, and Dart Class => Ceylon static member class named like DartClass.Class Of the second two, I'm leaning towards keeping the last.

Gotchas are:

Static references to constructors in Ceylon are not very useful since they require an instance of the class as an argument, which is a subtype of the interface that is more commonly used/exposed. The non-disjointedness problem in the issue description. — Reply to this email directly or view it on GitHub.

gavinking avatar Feb 19 '16 17:02 gavinking