12 thoughts on “feature: Kotlin like extension functions

  1. The Kotlin extension functions are a version of scoped and statically-resolved extension methods, similar to the ones in C#. That makes them easy to implement, but they’re also just a type-based shorthand for calling a static method. It allows someone else to extend a type, but it doesn’t allow a type to specialize the implementation. It also allows conflicts between different extensions and between an extension and the type itself.

    Another option is to define the extension methods on new “static types” that adapt the original types, so instead of adding List<T>.rotate(int n), you introduce a new type MyList<T> that “extends” List<T> and has a rotate(int n) method. Then you do MyList<T> myList = list; myList.rotate(42);.
    That will allow you to choose to adapt any list, and avoid conflicts between different extensions.
    (It’s list traits, basically).

    There are multiple other options, all with different trade-offs, because nothing is ever easy 🙂
    It’s not a new request (#9991).

  2. @lrhn Yes, Kotlin’s extension functions are “just” syntactic sugar and there are several other options in Dart (and other languages in general) like you described. However I think the point is that they are syntactic sugar and that they can be called like functions on the original class. This enables some nice, concise syntax. I, too, would like to see the support for extension functions (and properties?) in a future Dart version 🙂

  3. I really want extension functions in dart. Especially the Iterable API is lacking some features and it would be super handy to be able to add them myself and even publish them as package.

    Example 1

    Wrapping is not bad but sometimes breaks patterns.

    With extension function

    // with proposed extension functions
    // distinctBy not in sdk, but works nicely with extension function
    list.where((it) => it.size > 4)
        .map((it) => it.id)
        .distinctBy((it) => it)
        .skipWhile((it) => isValidId(it))
    
    List<T> List<T>.distinctBy<T>(bool selector(T t)) => /*...*/;

    Current solution

    // current state of the art
    // without extension and wrapping, therefore unreadable
    distinctBy(list.where((it) => it.size > 4)
        .map((it) => it.id), (it) => it)
        .skipWhile((it) => isValidId(it));
    
    List<T> distinctBy<T>(List<T> l, bool selector(T t)) => /*...*/;

    Example 2

    Problem:

    void doSomething(List<String> list) {
      // crashing for empty list with "No element"
      // firstOrNull not in sdk
      if (list.first == "abc") {
        print("found");
      }
    }

    Solution with extension function

    // proposed extension function
    T List<T>.firstOrNull<T> => this.isEmpty ? null : this.first;
    
    void doSomething(List<String> list) {
      // nearly unchanged code
      if (list.firstOrNull == "abc") {
        print("found");
      }
    }

    Current solution:

    // normal helper function, requires wrapping
    T firstOrNull<T>(List<T> l) => l.isEmpty ? null : l.first;
    
    void doSomething(List<String> list) {
      // fixed but list is now wrapped
      if (firstOrNull(list) == "abc") {
        print("found");
      }
    }
  4. The more I use extension functions the more I come to the conclusion that they are fare from “just syntactic sugar” – they are one of Kotlins “killer features”!

  5. Extension methods are wonderful for composition. For example, an app can compose extensions to List from two different package dependencies. Composition doesn’t work if everyone has extended List with their own custom functionality.

    Also, extensions are also great for adding common functionality to ALL children of a certain type. I can add my custom app-specific filter to List and Set with one extension method.

  6. I would love to see Kotlin-like extension functions in Dart 🙂 It really saves lots of time. You do not need to search multiple util or helper classes or helper functions which were not connected to any class. But with extension functions all that you need is to type “variable.” and you will see all methods and extensions classes available for this instance.

  7. It might “just” be sugar but it would be awesome. I find myself extending some classes like Observable just to add some functionality when I would like to declare the extension and be able to use it with the original instance elsewhere in the codebase. Is this on the radar at all?

  8. If Fast Development is Flutter’s USP and Dart cares for Flutter, then I think community deserves to get what they are asking for Extension Function in Dart.

  9. I am working on a project where the backend is written in Kotlin and the frontend in Dart (Flutter), so I am switching back and forth the whole day.

    Extension functions and null-pointer-safety are definitely the number 1 features I miss!

Comments are closed.