Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static extension methods: implement abstract class #475

Closed
roman-vanesyan opened this issue Jul 26, 2019 · 11 comments
Closed

Static extension methods: implement abstract class #475

roman-vanesyan opened this issue Jul 26, 2019 · 11 comments
Labels
question Further information is requested

Comments

@roman-vanesyan
Copy link

roman-vanesyan commented Jul 26, 2019

Will it be possible to static extension methods to implement some abstract classes (interfaces), like it possible extension to implement protocol in Swift, e.g.:

protocol Foo {
    func foo()
}

extension FooExt : Foo {
    func foo() {
        // some code
    }
}

Such a feature helps a lot to extend primitive type to use for framework's purposes. For example, imagine that we develop an http framework, we can extend String, Map, etc. to provide capability to return it as response to the request, e.g.:

abstract class HttpResponder {
  FutureOr<void> toResponse(Context context);
}

extension HttpStringExt on String implements HttpResponder {
  FutureOr<void> toResponse(Context context) => context.write(this);
}

typedef HttpHandler = HttpResponser Function(Context context);

HttpResponder strHandler() => 'Hello world';
@lrhn
Copy link
Member

lrhn commented Jul 26, 2019

No, this will not be possible with static extension methods.
The static extensions are inherently static. There is no run-time component to them.

As such, passing a String extended by HttpStringExt to something expecting an HttpResponder will fail. At run-time you are passing a string where an HttpResponder is expected, and that must fail.

Or, in short, static extension methods are not traits.

@lrhn lrhn added the question Further information is requested label Jul 26, 2019
@roman-vanesyan
Copy link
Author

Thanks for the quick response 😊
Is it considered to be added to the language in the future? Are there any possibility of it?

@leafpetersen
Copy link
Member

Some ideas in this space have been under discussion for a while, e.g. here. I don't think there's any strong short term plans in that direction yet though. I'm going to close this issue, since I think it's mostly covered by the issue referenced above - feel free to comment there on how that proposal sketch would/wouldn't address your use case.

@lukepighetti
Copy link

lukepighetti commented Oct 8, 2019

Just presenting a use case, I am porting some Swift code over to Dart, and they make use of extensions to implement protocols on classes imported from other packages.

https://github.com/uber/RIBs/blob/master/ios/tutorials/tutorial1/TicTacToe/Root/RootComponent%2BLoggedOut.swift#L27

Something like:

class Foo {
  String get foo => "foo";
}

abstract class Protocol {
  String get bar;
}

extension on Foo implements Protocol {
  String get bar => "bar";
}

Is there a possibility this can be added in the future? Is this a complex feature to implement now that we have static extension methods?

@lukepighetti
Copy link

@rrousselGit I've noticed swift has a very large namespace by default, does that have any effect on why they are able to do implementations with extensions? It doesn't seem like it would at first glance, but your reply seems to allude that it might.

@rrousselGit
Copy link

My bad, ignore my previous comment. I've misread the code snippet.

I thought it was:

class Foo implements Protocol {
  String get foo => "foo";
  // bar not implemented
}

extension on Foo implements Protocol {
  // implement bar as an extension
  String get bar => "bar";
}

@lukepighetti
Copy link

lukepighetti commented Oct 9, 2019

Ahhh, gotcha! Yeah the question is if you can use extensions to make an imported class implement a protocol/interface of some sort. Would be a real nice way to write adapters!

Another question, not sure if this is the right place for this, or if this is for Stack.

import 'package:flutter/widgets.dart';
import 'package:rxdart/rxdart.dart';

main() {}

extension on StreamBuilder<T> {
  static StreamBuilder<T> seeded({Key key, ValueObservable<T> stream, AsyncWidgetBuilder<T> builder}) =>
      StreamBuilder<T>(key: key, stream: stream, initialData: stream.value, builder: builder);
}

class FakeWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<bool>.seeded(
      stream: Observable.just(true).shareValueSeeded(true),
      builder: (context, snapshot) {
        ///
      },
    );
  }
}

Possible to add static methods? Right now this is invalid, showing error

The class 'StreamBuilder' doesn't have a constructor named 'seeded'.
Try invoking a different constructor, or define a constructor named 'seeded'.dart(new_with_undefined_constructor)

@natebosch
Copy link
Member

Possible to add static methods? Right now this is invalid, showing error

No. You'd have to refer to the extension name not the type it's on to invoke a static. As a consequence you can't call a static on an unnamed extension. I filed #617 to discuss whether we should make the definition a warning.

extension Seeded on StreamBuilder {
  static StreamBuilder<T> seeded<T>(...) =>;
}

// usage
return Seeded.seeded<bool>(...);

@lukepighetti
Copy link

lukepighetti commented Oct 14, 2019

Yeah for this specific case I can't find a way to make extensions improve over this style of implementation. If we could extend a class with a new constructor or create an extension with its own constructor or add a static method to the original class I believe it would be an improvement.

class ValueObservableBuilder<T> extends StreamBuilder<T> {
  ValueObservableBuilder({
    Key key,
    ValueObservable<T> valueObservable,
    AsyncWidgetBuilder<T> builder,
  }) : super(key: key, stream: valueObservable, initialData: valueObservable.value, builder: builder);
}

@izouxv
Copy link

izouxv commented Mar 10, 2022

just swift can do it .

@jejer
Copy link

jejer commented Jul 17, 2023

Wish Dart could support this feature like Swift.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

8 participants