Dealing with naming clashes with multiple interfaces

17 views
Skip to first unread message

Chris Buckett

unread,
Apr 28, 2012, 12:03:53 PM4/28/12
to General Dart Discussion
Hi,

Quick question, at present, if two separate interfaces declare the
same method name, there is no way for a single class to implement both
the interfaces at the same time.

eg: http://try.dartlang.org/s/bEo8

Is there any way planned around this (eg, name prefixes or similar? )

Cheers,
Chris.

Seth Ladd

unread,
Apr 28, 2012, 12:12:41 PM4/28/12
to Chris Buckett, General Dart Discussion
Hi Chris,

If you change B.go(name) to B.go() the static analyzer will stop complaining. I tested in the Dart Editor.

Seth

Chris Buckett

unread,
Apr 28, 2012, 12:20:48 PM4/28/12
to Seth Ladd, General Dart Discussion
Aah, let me clarify a bit more :)

at present, if two separate interfaces declare the
same method name with different method signatures
there is no way for a single class to implement both
the interfaces at the same time.

Cheers,
Chris.

Rémi Forax

unread,
Apr 28, 2012, 1:58:09 PM4/28/12
to mi...@dartlang.org
On 04/28/2012 06:20 PM, Chris Buckett wrote:
> Aah, let me clarify a bit more :)
>
> at present, if two separate interfaces declare the
> same method name /with different method signatures/
> there is no way for a single class to implement both
> the interfaces at the same time.
>
> Cheers,
> Chris.

Not exactly true, this by example works thanks to the unsound typesystem

interface A {
m(A a);
}
interface B {
m(B b);
}

class C implements A, B {
m(A a) {
if (this == a) {
print('Ok !');
}
}
}

main() {
A a = new C();
a.m(a);
B b = new C();
b.m(b);
}

Rémi

>
>
>
> On 28 April 2012 17:12, Seth Ladd <seth...@google.com

John Messerly

unread,
Apr 28, 2012, 2:02:36 PM4/28/12
to Rémi Forax, mi...@dartlang.org
On Sat, Apr 28, 2012 at 10:58 AM, Rémi Forax <fo...@univ-mlv.fr> wrote:
On 04/28/2012 06:20 PM, Chris Buckett wrote:
Aah, let me clarify a bit more :)

at present, if two separate interfaces declare the
same method name /with different method signatures/

there is no way for a single class to implement both
the interfaces at the same time.

Cheers,
Chris.

Not exactly true, this by example works thanks to the unsound typesystem

interface A {
 m(A a);
}
interface B {
 m(B b);
}

class C implements A, B {
 m(A a) {
   if (this == a) {
     print('Ok !');
   }
 }
}

main() {
 A a = new C();
 a.m(a);
 B b = new C();
 b.m(b);
}

Yeah, other than exploiting the type system (e.g. leaving off types) and optional arguments, I don't think there's another way around it. It's essentially the same issue as having lack of overloads in Dart, which you can workaround with something like:

// doesn't work:
void overload(Foo f) {}
void overload(Bar b, Baz z) {}

// but can be faked by:
void overload(f, [z]) {
  if (f is Foo && z == null) {
  } else {
    ...
  }
}

IMO dynamic languages usually get by reasonably well without name conflicts, but YMMV.

- John

Rémi Forax

unread,
Apr 28, 2012, 2:09:28 PM4/28/12
to John Messerly, mi...@dartlang.org
On 04/28/2012 08:02 PM, John Messerly wrote:
It's not exactly the same issue, I think you can not override a method
without named parameters
with one which has named parameters.

>
> - John
>

R�mi

John Messerly

unread,
Apr 28, 2012, 2:19:16 PM4/28/12
to Rémi Forax, mi...@dartlang.org
Not sure if it's quite the same example, but this does seem to work, on VM at least:

class Foo {
  void foo() {
    print('Foo.foo');
  }
}

class Bar extends Foo {
  void foo([abc=123]) {
    print('Bar.foo: abc=$abc');
  }
}

void main() {
  new Foo().foo();
  new Bar().foo();
  new Bar().foo(444);
  print("Hello World");

// prints:
//Foo.foo
//Bar.foo: abc=123
//Bar.foo: abc=444
//Hello World
}

- John

John Messerly

unread,
Apr 28, 2012, 2:24:51 PM4/28/12
to Rémi Forax, mi...@dartlang.org
Ah, I see what you mean Rémi. This works at runtime, but flags an error:

interface F {
  void foo();
}

interface B {
  void foo(abc);
}

class Foo implements F {
  void foo() {
    print('Foo.foo');
  }
}

class Bar extends Foo implements B {
  void foo([abc=123]) { // error about overriding without same # of required params
    super.foo();
    print('Bar.foo: abc=$abc');
  }
}

void main() {
  new Foo().foo();
  new Bar().foo();
  new Bar().foo(444);
  print("Hello World");
}

I can fix the error by making B.foo take an optional arg. Suboptiomal tho =\


Chris Buckett

unread,
Apr 28, 2012, 2:30:29 PM4/28/12
to General Dart Discussion
This solution seems like the best way of handling it.

I'm thinking specifically of scenarios where I want to implement
interfaces from different third-party libraries, and there "just
happens" to be a naming clash (like the scenario when two different
libraries are imported, which is fixed by the prefix statement on
#import).

Cheers,
Chris.

Lasse R.H. Nielsen

unread,
Apr 30, 2012, 7:49:24 AM4/30/12
to John Messerly, Rémi Forax, mi...@dartlang.org
On Sat, Apr 28, 2012 at 20:24, John Messerly <jmes...@google.com> wrote:
> Ah, I see what you mean Rémi. This works at runtime, but flags an error:
>
> interface F {
>   void foo();
> }
>
> interface B {
>   void foo(abc);
> }
>
> class Foo implements F {
>   void foo() {
>     print('Foo.foo');
>   }
> }
>
> class Bar extends Foo implements B {
>   void foo([abc=123]) { // error about overriding without same # of required
> params

Personally, I would think that this one *should* be allowed, since it
is compatible with both of the inherited interfaces. Currently it
isn't.
I've just added an issue asking for it:
http://code.google.com/p/dart/issues/detail?id=2824

Even with that, there'll still be interfaces that can't be unified, e.g.:
interface A {
foo([int z]);
}
and
interface B{
foo([int x]);
}
Since optional parameters can be passed both by position and by name,
you can't have the first argument having two names.

/L
--
Lasse R.H. Nielsen
l...@google.com
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K -
Denmark - CVR nr. 28 86 69 84
Reply all
Reply to author
Forward
0 new messages