Monday, October 17, 2016

Good-bye symlinks

Dart 1.20 is now available. Get it now!

Back in the Dart 1.19 release we introduced support for the .package file; our replacement for the /packages/ directory often filled with hundreds of symlinks. In 1.19 this support was opt-in via passing an option to pub get. Now that it has had time to mature, and based on favorable feedback, we have gone ahead and made it the default. If for some reason this causes issues, you can still get symlinks by using the pub get --packages-dir command; in such cases make sure to file an issue.

One common question we have received is how to handle resource loading in a world without packages symlinks. The symlinks blog post covers this in detail. In summary you can either resolve a Uri to a resource using the new resolvePackageUri API (e.g., Uri actualURI = 
    await Isolate.resolvePackageUri(Uri.parse("package:foo/bar.txt")) ), or you can use the new package:resource that provides a more abstract API.

Finally, the VM has been updated to throw catchable Error objects when method compilation fails. This allows package:test, for instance, to provide useful stack traces when running code with syntax errors.

See the full changelog here.

Download the latest release, and let us know what you think!

Thursday, October 13, 2016

The new Google AdSense user interface: built with AngularDart

AdSense is a free, simple way to earn money by placing ads on your website. The team just launched a completely new version of their app for publishers. Read all about it here. We asked Daniel White, the tech lead for the project, some questions because the new UI happens to be built with Dart and Angular2.

AdSense launched way back in 2003. How long is it since the last big redesign?
Last big redesign was called ‘AdSense 3’ and launched about 6 years ago. It was written in Google Web Toolkit (GWT) and the UI has evolved through several iterations - but this is the first ground-up redesign in 6 years. There are a number of long-standing UX issues that we’ve taken the opportunity to solve. A big shout-out to our UX team who’ve been 100% behind this project. We couldn’t have done it without them!

How many software engineers worked on the project?
Purely on the AdSense applications, we have a team of close to 100. Around 25% of them write Dart.

How many lines of code?
We have around 160K LOC of Dart.

How long does it take to do a complete redesign like this?
We’ve been following Dart for a long time and started to pilot it about 2.5 years ago. In the last 18 months we’ve shipped most major new features in Dart. For AdSense Material Design, we started UX work in December 2015 - coding started in February. So, 8 months.

What’s the stack?
Strong mode Dart, Angular 2 — we just migrated all our codebase away from AngularDart1. Java servers. We use protocol buffers to communicate between the browser and our UI servers.

We also have an older GWT app running on the same page and we use protocol buffers to communicate between the Dart and GWT codebases.

Have you seen any productivity improvements?
Compared to our old GWT workflows, we see much faster iteration. Compiling and starting the server is about 8X quicker than it used to be. Refreshing a page is about 6-7X quicker in dev mode. Tech leads that have shipped products have estimated a 2X improvement in overall project speed - from beginning implementation until launch.

How about performance improvements?
Loading the page requires about 50% less data (it’s around 900K-1000K smaller - this is mostly due to a new architecture, but moving to Dart let us redesign all that stuff). Using a cold cache, the time from initial request to working UI is about 45% less.

Were the developers happy?
Yes. The combination of Dart and Angular is working really well for us - we anticipate this to improve even more now that Angular’s Dart codebase can be tailored to the language (better error messages, optimizing code size).

When we decided to push ahead with Dart, the response from tech leads within AdSense was very enthusiastic - to the point where the small pilot team was overwhelmed with new requirements to support!

What are the advantages and disadvantages of the new stack?
The main advantage for us is having a top quality tech stack that we can share with other Google products - shared code and components can be developed for reuse by other teams. This gives us consistent UIs and massively reduces the amount of custom code we need to write. The benefits of that can now be shared with the outside world too — the Material Design UI components that have been worked on by hundreds of engineers will be gradually released to open source.

The disadvantages have largely been around being on the cutting edge, particularly with Angular2. We need to keep up with breaking changes in Angular. Thankfully, Angular has mostly stabilized now and we’re looking forward to 2.0 final (to be launched on the Dart Developer Summit).

Any surprises?
What’s been very gratifying is that investing in improved developer productivity/workflows has had visible impact on the quality of the Material Design AdSense applications. Developers feel ‘in tune’ with the page because they can see the effects of code changes very quickly, but they also get the benefit of types/refactoring/tool support that come with a statically typed language.

Alright, so now that you launched, what’s coming next?
Our new tech stack is going to allow us to ship higher quality changes more quickly, which is what we plan to do as we launch more Material Design changes over the coming months and years.

Thank you, Daniel!

Tuesday, October 11, 2016

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?

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.

--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.

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:


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.

--JIT Juggler

Someone I was talking to mentioned another of my favourites - using interpolation instead of 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();

Now we can:

o = new MyObject()

--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 => foo(x)) do

--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

--Optimized Object

The only question remaining now is:

What is your favorite Dart feature?

Tuesday, September 20, 2016

Dart Developer Summit announcements: AngularDart 2.0 and more

The Dart Developer Summit is only 5 weeks ahead, and we’re excited about its agenda: 17 talks, many demos, 25 speakers, plus a lightning talks session and a panel discussion. Expect the full program soon on the site, but here’s a teaser:

  • Major improvements to the type system
  • Much better interoperability with JavaScript
  • Improved developer workflow
  • AngularDart 2.0
  • And much more

We will share more details as we approach the summit. Because the TypeScript flavor of Angular just released version 2.0 last week, we think it’s a good opportunity to share more details about AngularDart 2.0.

Besides the changes you’d expect, such as faster execution and reduced size (on which we’re already making a lot of progress), we will also have a better template compiler and some nice surprises for you.

The beta releases of AngularDart have been in production use at Google since January, in MLOC-sized apps. This has helped us to see what works well for large apps, and to improve the APIs accordingly.

We hope you’ll join us in person or online at the Dart Developer Summit in Munich. To learn about AngularDart, visit

Tuesday, September 6, 2016

Configuring Static Analysis using an Analysis Options File

Static analysis allows you to find problems before executing a single line of code. It’s a powerful tool used to prevent bugs and ensure that code conforms to style guidelines. With the help of the analyzer, you can find simple typos. For example, an accidental semicolon made its way into an if statement:

The analyzer can also help you find more subtle problems. For example, perhaps you've forgotten to close a sink instance:

In the Dart ecosystem, the Dart Analysis Server and other tools use the analyzer package to perform static analysis. You can configure the analyzer using an analysis options file.

For more information, see our new page, Customize Static Analysis.

Friday, August 26, 2016

Dart 1.19: Improved developer experiences

Dart 1.19 is now available. Get it now!

We closely collaborate with the Flutter team on providing the best developer experience for Dart for Mobile. This includes language changes that optimize the Flutter development experience. Dart code for Flutter apps commonly have long argument lists. Before 1.19, a trailing comma was not allowed after the last argument. This made it really tedious when removing the last argument, or when reordering the arguments. With 1.19 we introduce support for an optional trailing comma after the last argument of a call and the last parameter of a function declaration. This makes code editing much easier:

If you've struggled with package directory symlinks, you're in luck. You can now opt-out of creating a package directory and the associated symlinks scattered around your project directories. The flag to provide to pub get and pub upgrade is --no-packages-dir. We've posted a detailed writeup of the changes if you'd like more information. Please test your code with this flag. We intend to make --no-packages-dir the default behavior in an upcoming release.

See full changelog here.

Download the latest release, and let us know what you think!

So Long, Symlinks!

Long ago, back in the dawn of time, when nary a Dart file was to be found outside of the SDK repository, imports in Dart only supported file paths. As the language got older and an ecosystem began to grow around it, it quickly became clear that paths weren’t enough: Dart needed a way to import libraries that didn’t care about the location of the file doing the importing. The language team talked to the VM team and they came up with a solution. In addition to file: URIs, Dart would support a new package: scheme by looking for packages in a packages/ directory next to the entrypoint, wherever that happened to be.

This worked pretty well—well enough to form the foundation for the pub package manager, written by Bob and myself. But it also had flaws. A lot of symlinks had to be generated all over every package—the test package currently contains about four hundred. Not only was this messy, many tools ended up following the symlinks and corrupting the package cache. So the team came together again and came up with the idea of a package configuration file that lists available packages as well as the concrete URIs where they can be found.

Support for package config was quickly added to all Dart implementations. In fact, pub has been generating them since Dart 1.12. The only task remaining was to gracefully turn off pub’s support for generating the packages/ directory and all the symlinks that come with it… but that turned out to be easier said than done.

The thing is, for all its flaws, the packages/ directory was pretty easy to work with from Dart code. You just had to do some path manipulation with Platform.script to figure out where the packages/ directory was, and from there you could do whatever you wanted. It wasn’t clean, but it worked most of the time, and there was no way to do the same stuff with .packages.

Once again conversation ensued. APIs were proposed, rejected, redesigned, tweaked, implemented, rolled back, iterated on, landed, stabilized1, and verified. It took seven releases to get everything just right, but we did it, and we’re ready for you to try it out. And I’m here to tell you how.

Disabling The Packages Directory

The first step on your journey to package enlightenment is to abandon your attachment to worldly directories. Relinquish your need for the comfort of familiarity by passing --no-package-dir2 to pub get (or upgrade or downgrade). Pub won’t generate a packages/ directory, nor of course will it symlink to the directory that it doesn’t generate. If you already had a packages/ directory, pub will get rid of it as well as any symlinks pointing its way.

For most packages and applications, this is all you’ll need to do! The latest versions of core Dart tools like pub and test fully support running with a package config. As long as your code isn’t manually dealing with packages, you’re good to go. And if it is, keep reading!

Core Package APIs

The core libraries have a few primitive APIs for providing information about package resolution. They form the foundation of more advanced APIs implemented in packages, but they’re also straightforward enough to use on their own. They cover many of the most common use-cases for dealing with packages. It’s important to note, though, that they only work in the Dart VM; the JavaScript compilers only deal with packages at compile-time, so they have no way of reporting anything about them at runtime.

The most broadly-applicable library package API is Isolate.resolvePackageUri(). It converts a package: URI into a file:3 URL that can be easily converted to a path. This is the easiest way to find resources in your package, or even public resources in your dependencies.

It’s important to note that this API is asynchronous, though: it returns a Future<Uri> rather than just a Uri. This is because the VM loads package information lazily, and the load process is asynchronous. If you have any package: imports in your code, the information will already be loaded, but it’s not safe to assume that—even code that uses lots of different packages may be run from a snapshot every now and then.

The other important core APIs tell you where the package resolution comes from. Isolate.packageConfig returns the URL of the package config file used for the current isolate, and null if a package root is being used. Its twin, Isolate.packageRoot, returns the URL of the current isolate’s package root, and null if a package config is being used. These getters are useful for forwarding the current resolution scheme—for example, if you want to start a Dart process that uses the same resolution as the current isolate, you can use these to figure that out.

I should probably also mention the Platform.packageConfig and Platform.packageRoot getters as well, but I do not recommend using them. They return exactly the text passed on the command-line for the --packages or --package-root flag, respectively. This means they’re unreliable: if the package resolution information was auto-detected, they’ll return null. If the current Isolate uses a different resolution scheme than the main isolate, they could return something completely irrelevant. Avoid them.

The package_resolver Package

If you want to go beyond the basics in your package code, package_resolver is the package for you. It provides classes that encapsulate strategies for package resolution—using a package config, using a root, or using nothing at all. Where code used to just pass around a packageRoot string, it can now pass a PackageResolver that says how to resolve URIs.

You can construct a PackageResolver by passing a package config map to new PackageResolver.config(), or by passing a package root to new PackageResolver.root(). If all you have is the URI for a package config, you can also use PackageResolver.loadConfig(). But most of the time, all you need is information about the current isolate’s package resolution, which you can get from the PackageResolver.current getter.

The resolver supports more or less the same APIs that the Isolate does: resolveUri() is equivalent to Isolate.resolvePackageUri(), packageConfigUri to Isolate.packageUri, and packageRoot to Isolate.packageRoot. But it builds other useful methods on top of these as well.
The packagePath() method returns the root of a package on the local filesystem. It assumes that you’re using pub, since it needs to look above packages’ lib/ directories, but this works in practice for essentially all Dart code.

The packageUriFor() method is the reverse of Isolate.resolvePackageUri(): it converts a file: URL into a package: URI that refers to the same file, if such a URI exists. This is useful for reporting nice-looking messages; it’s much easier to read a short package: URI than a long absolute path.

The processArgument getter is useful when running Dart processes or compiling Dart to JS. It returns an argument that can be passed directly to the dart, dart2js, or dartdevc executables that will cause them to use the resolver’s resolution strategy. If you passed using a custom package config map, it’ll even manufacture a data: URI for you4.

It even exposes the package config map directly through the packageConfigMap getter. Note that since the isolate API doesn’t yet provide this information directly, this may require re-loading it from disk.

But I Want It Synchronous!

All the PackageResolver APIs are asynchronous because they might be implemented using the asynchronous Isolate APIs. But asynchrony can be annoying to work with, and sometimes it’s not necessary. That’s what the SyncPackageResolver class is for. It exposes pretty much the same API as PackageResolver, but with no futures to be found.

The catch is that if you want to get a SyncPackageResolver, all the information—the package config map or the package root URI—needs to be available up-front. So SyncPackageResolver.current and SyncPackageResolver.loadConfig() both return Future<SyncPackageResolver>, since they have to wait for Isolate API futures and/or load information from disk.

You can convert back and forth between synchronous and asynchronous package resolvers easily using the asSync and asAsync APIs. This makes it possible for packages to take whichever one they work best with without causing pain for their users. For example, source_map_stack_trace takes a SyncPackageResolver so it can work synchronously, but shelf_packages_handler takes a PackageResolver since serving handling requests is already inherently async.

Why Bother With The Package Root?

The package_resolver package goes to pains to work well with both package configs and package roots, and to make it easy for users to support both. This raises a question: if pub is moving away from generating a packages/ directory, what’s the point of supporting it?

First of all, there’ll be a transition period where both modes will be fairly common. Pub still generates the packages/ directory by default for now, and the language implementations prefer it if it exists. A smooth transition relies on code’s ability to be used in both old and new settings.
But even in the future when packages/ files aren’t generated by default, support for package roots will be sticking around, and it can still be useful. It may not be the best way to run code manually, but a lot of code isn’t run manually—Pub’s transformer support, for example, loads isolates over HTTP, where it serves virtual packages/ directories.

In addition to supporting current tools, we want leave the door open for future tools to innovate as-yet-undreamed-of ways to handle Dart code. So we choose flexibility and continue to support package roots.

On Into The Future

Once there’s been a release or two with the --no-package-dir flag and users have a chance to make sure their packages work with only a package config, we’ll disable the flag by default. You’ll need to pass --packages-dir explicitly if you want it generated. A while after that, we’ll hide the flag and stop officially supporting it. We may get rid of it entirely one day, but there’s no hurry—it’s not that hard to support.

So go forth and update your packages! Use the core library APIs and the package_resolver package, or one of the helpful packages I didn’t have a chance to get to: resource provides an abstraction for loading resources, and shelf_packages_handler makes it easy for a Shelf server to support a package root. Or write your own! The underlying tools are powerful, and I’m excited to see what you can do with them.

  1. Well, mostly stabilized. There are still a few corners of the API that are still in the process of being thoroughly tested. Bear with us if you run into them, and maybe wait another release cycle before you depend too heavily on running without the packages/ directory.
  2. This flag is new in 1.19, but some readers may notice its similarity to the undocumented --no-package-symlinks that pub used to support. --no-package-symlinks was added ages ago to let the Dart analyzer team experiment with their package config support, and we decided to tweak it a bit when making it public.
  3. Since the Dart VM supports loading packages over HTTP, it’s theoretically possible for it to return an http: URL. This doesn’t happen that often in practice, but it is a possibility—for example, the test runner can load test suites over HTTP from a pub serve instance.
  4. Note that there are usually limits on how long command-line arguments can be, so this may not work if the package config is too big.