Skip to main content

What’s your favorite Dart feature?

Earlier this year we had an ongoing thread where Googlers shared their favorite Dart feature—perhaps a less known one. We wanted to share these insights from some of our most engaged internal users more broadly. Hence this post.

The names have been changed to protect the innocent, but the contents should constitute some fine reading.

Here we go:



What's your favorite "less known" (or undocumented) feature of Dart?
Any particular syntax trick or library function?

Java has loads of these, tricks ranging from the double-paren. init (Map<String,String> {{ put("a", "1"); }};) to "sneaky throwing" ANY exception.
Anything similar in Dart?

Cheers,
Agile Analyzer



As a Java developer, my opinion of both of those is: this is clever, but don't do it in real code under any circumstances.

-Bug Basher



I'm not a fan of tricks, and from what I've seen so far Dart needs very few. There are some features of the language that I feel are underutilized or are very new. Here are a few:

- Null is a type, so if you have a Future and you want to document that it doesn't return anything useful, make it a Future<Null>
- You can throw arbitrary objects in Dart without losing stack traces: throw "This is an error"
- const can be a local variable and it will still be allocated only once (no need to hoist it into a static field or top-level constant)
- You can create custom matchers and use them in your tests (example)
- There exists package:meta that the analyzer understands, and which has @protected, @required (for required named parameters), and others
- You can implement classes as every class also exports its interface.

-Clever Compiler



My favorite lesser-known feature is pretty simple: you can define stuff outside of classes.

I see a lot of users coming to Dart from Java or C# and they are in the habit of stuffing every variable or function inside a class either because they think you have to—which you do in those languages—or out of a belief that it makes their code better in some vague "OOP paradigm is best paradigm" sort of way.

Object-orientation is a fantastic paradigm for expressing some kinds of code. It works really well when you have interesting state and interesting operations that are deeply tied to that state. It's also great when you want polymorphism based on kinds of objects.

But a lot of times, you're just trying to express some vanilla data or some imperative behavior. For those, classes don't provide any value. If you just want to define the value of π somewhere, you don't need a class named, like, I dunno "MathematicalConstants" to put it in. You can just do:

const pi = 3.1; // Eh, close enough.

Likewise, sometimes all you need is a procedure, not a method. Say you create and file and write some string to it. You could make a "FileWriter" class or something, but why bother? You can just do:

void writeFile(String path, String contents) { ... }

You might be thinking that you need to put definitions inside classes to avoid name collisions and to "namespace" things, but you don't need to do that in Dart. Libraries in Dart are the unit of namespacing and modularity. With show, hide, and import prefixes, libraries are much better at expressing namespaces and dealing with name collisions.

If you made it this far, I will note one feature that really is rarely used. Did you know that you can define getters and setters at the top level too? You can define something that looks like a top-level variable but is actually doing computation.

Cheers!
--Dart Dogfood



+1 for simple short-hands.  When a language is young, there's a tendency to use it like that-other-thing-you-know.  These conversations are a really good thing.

Instead of writing:

if (foo == null) {
  foo = 'bar';
}

Just do:  foo ??= 'bar';

The "cognitive load" (ahem!) is much lower.  It's similar to Ruby's foo ||= 'bar' but better, because it strictly applies to nulls (vs. nil & false).

-Eager Execution



I like ??= for lazy-initialized fields

   T _foo;
   T get foo => _foo ??= _computeValue();

--Failed Function



I wouldn't describe these as "favorite" features, but they do seem to be lesser known:


+1 to avoiding things that are "clever" but hard to read.

--Great Googler



I don't see generators used all that much and there are some places where they really help.
https://www.dartlang.org/articles/language/beyond-async#generators

For some use cases a generator is going to be more readable than the alternatives, in others it's very tempting to write a 'clever' generator.

--Heated Hotspot



One of my favourite features is that the analyzer will tell you if you use a switch statement with an enum and don't list all the enum values.

This means that if you've been careful always to use switches when using enums (rather than if/else chains), you can just add the new value to the switch, run the analyzer, and it'll tell you all the places you need to update.

--Injected Iterator



Thanks everybody!!!

Lots of stuff to try out and/or read about! I've been actually thinking that something like the meta library would be nice (and hey, it's already live!)

Awesome thread :)

--Agile Analyzer



My favourite Dart things are foremost the ones I created ;) ... immutable collections, immutable value types, proper enums, and object oriented serialization:

- https://github.com/google/built_value.dart/blob/master/libraries_for_object_oriented_dart.md

And a few I didn't:

 - The ".." operator is a gift for anyone who likes fluent APIs.
 - source_gen (and now the "build" package) really hits the sweet spot for code generation.

Cheers
--JIT Juggler



Someone I was talking to mentioned another of my favourites - using interpolation instead of toString.

    x.toString()

can usually be replaced by

    '$x'  or  '${x}'

It is shorter, looks like it should be a string, and guarantees the result is a String (toString() may perversely return null, even in checked or strong mode).

--Failed Function



Kinda late for the party ;)

I just started to use Dart for two months, still so much to learn. Other than null-aware operators that is already mentioned, I also find double-dot operator very handy for method cascade.

Instead of doing:
o = new MyObject();
o.set(x);
o.set(y);

Now we can:

o = new MyObject()
   ..set(x)
   ..set(y);

--Klever Kompiler



Here's some I like:

You can use 'expand' to concat lists:
[[1,2,3], [4,5,6], [], [7,8,9]].expand((x) => x) // returns [1,2,3,4,5,6,7,8,9]

I don't think this pattern is used often enough, abstract classes which have a forwarding factory constructor to the real implementation:

abstract class Foo {
  factory Foo() = _Foo;
  // ... Foo methods ...
}

class _Foo implements Foo {
  // ... implementation  ...
}

This lets you put all your documentation on 'Foo' and let people call 'new Foo()' while the private class '_Foo' actually has all the implementation details that nobody cares about.

--Linked List



This may not come up that often, but I love the * operator on Strings (thanks Failed Function!):

_padRight(String message, int columns) {
   var padding  = " " * (columns - message.length);
   return '$padding$message';
}

--Main Method



I wouldn't call it a feature, but lot of people don't seem to realize (is it something originating from Java?) you can pass any function/method tearoff as an argument, not necessarily an anonymous literal, ie:

Instead of xs.map((x) => foo(x)) do xs.map(foo).

--Non Nullable



I really like functional methods in combination with tear-offs:

int bestScore = [1, 2, 5, 1].reduce(max);

And generators.

/// Merge [a] and [b] until [a] is fully consumed. Then add 42.
Iterable<int> combine(Iterable<int> a, Iterable<int> b) sync* {
  var aIterator = a.iterator;
  var bIterator = b.iterator;
  while (aIterator.moveNext()) {
    yield aIterator.current;
    if (bIterator.moveNext()) {
      yield bIterator.current;
    }
  }
  yield 42;
}


Seriously, though, this whole thread should be a blogpost on news.dartlang.org.

--Optimized Object



The only question remaining now is:

What is your favorite Dart feature?




Popular posts from this blog

Dart in 2016: The fastest growing programming language at Google, 2nd fastest growing in TIOBE Index

Dart was the fastest growing programming language at Google in 2016 with millions of lines of code written. It also made it to TIOBE Index Top 20 this month (see TIOBE's methodology ). It takes time to build something as ambitious as Dart and, in some ways, Dart is still in its infancy. But we're glad the hard work is starting to pay off. Many thanks to our amazing community! We're going to celebrate by ... releasing 1.22 next week (as per our usual 6 week release schedule).

AngularDart is going all Dart

Until now, the multiple language flavors of Angular 2 were written as TypeScript source, and then automatically compiled to both JavaScript and Dart. We're happy to announce that we’re splitting the Angular 2 codebase into two flavors – a Dart version and a TypeScript/JavaScript version – and creating a dedicated AngularDart team. This is amazing news for Dart developers because: The framework will feel more like idiomatic Dart. It will make use of Dart features that couldn't work with the TypeScript flavor. It will be faster. This is equally great news for our TypeScript and JavaScript developers, by the way. Cleaner API, performance gains, easier contributions. Read more on the Angular blog. Angular 2 for Dart is used by many teams at Google. Most famously by the AdWords team, but many other Google teams build large, mobile-friendly web apps. Some of the top requests from these teams were: make the API feel like Dart, provide a faster edit-refresh cycle, and

The new AdWords UI uses Dart — we asked why

Google just announced a re-designed AdWords experience. In case you’re not familiar with AdWords: businesses use it to advertise on google.com and partner websites. Advertising makes up majority of Google’s revenue, so when Google decides to completely redo the customer-facing front end to it, it’s a big deal. The Dart team is proud to say that this new front end is built with Dart and Angular 2. Whenever you asked us whether Google is ‘even using Dart for anything,’ this is what we had in mind but couldn’t say aloud. Until now. We asked Joshy Joseph , the primary technical lead on the project, some questions. Joshy is focusing on things like infrastructure, application latency and development velocity, so he’s the right person to ask about Dart.   Q: What exactly did we launch on Monday? It’s a complete redesign of the AdWords customer experience that is rolling out slowly as a test to a small initial set of advertisers. The most noticeable thing is probably the Material Design look