kt.dart — Kotlin like collections for your Flutter business logic
No matter how great Flutter is, using Dart feels like a step backwards when coming from Kotlin. I understand the reasoning why Dart was chosen as Flutters language but I miss Kotlins feature rich standard library. That’s why I decided to port it to Dart. Welcome kt.dart!
kt.dart doesn’t introduce new language features but it would definitely benefit from some. That’s why I invite you to upvote some of my favorites Dart language proposals: Extension Methods, Optional Semicolons, Non-Nullable types, Destructuring Declarations, Data Classes
Dart’s missing high-level collections for business logic
The most common collection in nearly every programming language is the array. Dart doesn’t have arrays, Dart arrays are Lists. And Dart’s Lists are amazing compared to Java’s Array
. But is such a comparison justifiable? Shouldn’t Dart’s List
better be compared with Java’s ArrayList
or Kotlins MutableList
?
Neither of those comparisons are fair. The most important aspect is that there is a right tool for the job.
My job is to write business logic and SDK with stable APIs. This is much more challenging in Dart compared to Kotlin. Especially Dart’s collections aren’t perfect for the job. That’s why I ported Kotlins high-level collections to Dart, allow me to write better APIs.
Before I jump into kt.dart
s API, I’d like to show where Dart’s collections are lacking compared to kotlins collections:
Explicit immutability
Using Kotlin made me used to immutability. My entities are immutable (data classes) and so are the Lists I return from my APIs. Immutable entities aren’t a problem in Dart. But a immutable List
has the same API as a modifiable List
. Consumers might expect to be able to mutate a immutable List
. There is no compiler warning, it crashes at runtime.
There is also no way to test if a List
is modifiable or not. Unlike Kotlin, Dart doesn’t differentiate between List
and MutableList
.
Deep Equality
Comparing two Dart collections (List
, Set
or Map
) doesn’t compare their contents, it only checks their identity. Dart offers a solution: The equality functions in the collection
package.
But Dart’s collections don’t use DeepCollectionEquality
for their equals checks internally, which makes methods like List.contains
or Map.containsValue
unusable.
Dart doesn’t offer collections which are deep equal and differentiate between immutable and mutable collections. Since it doesn’t exists kt.dart is here to fill the void.
kt.dart: collection
kt.dart
s collection package offers immutable collections (KtList
, KtSet
, KtMap
) with a correct equals implementation.
This is similar to built_value, but it doesn’t stop there. kt.dart collections also offers mutable types. Only the mutable types offer mutation methods. Nobody can accidentally try to mutate an immutable collection.
KtIterable doesn’t extend Dart’s Iterable
Unlike built_value, kt.dart collections don’t extend Dart’s Iterable
. The reason for this is that Dart’s naming of methods is uncommon. Modern languages (Kotlin, Swift, TypeScript) all named their Iterable
methods the same (map
,flatMap
, filter
, …). This helps a lot when working with developers from different platforms. Dart’s expand
or where
is less common.
The minor downside of not extending Iterable
is that for loops don’t work out of the box. To solve this, each KtIterable
exposes a Dart Iterable
via iter
. A for loop then looks like this:
150+ methods
Additionally, kt.dart collections comes with over 150 methods out of the box. All of them can be easily discovered via auto-completion.
Checkout the documentation to discover more methods. Or just start using it. Here are some of my favorites:
Notice that collections can be created by either a function listOf(1, 2, 3)
, listFrom([1, 2, 3])
(Kotlin style) or a constructor call List.of(1, 2, 3)
, List.from([1, 2, 3])
(Dart style). Both versions are equally supported the usage depends on your personal taste.
Just the beginning
This is just the beginning of kt.dart. The collection
module is the first (and most important) part. But I can already think about more modules. For example ranges
,sequences
or text
.
If you have questions or feedback, let me know! Hit me on Twitter for a quick chat. I’m super interested!