Google I/O 2012 - Migrating Code from GWT to Dart


Uploaded by GoogleDevelopers on 29.06.2012

Transcript:

RAY CROMWELL: Good afternoon.
How you guys doing?
I'm looking around the room and I'm seeing a lot of people
who I think are either passionate about GWT or Dart,
because you could have been downstairs getting your Nexus
7, your Galaxy Nexus, and your Nexus Q, but
you're here in my session.
So thanks for coming.
This session is titled "Migrating Code from GWT to
Dart." And if you might notice--
I'm tech lead for GWT.
My name is Ray Cromwell.
So the first thing you might be asking-- and I get this a
lot-- before the session even starts, is why Dart?
Why am I even giving a Dart session in the first place?
I'm tech lead on GWT.
Well first of all, actually, I think Dart's
a really cool language.
And I'm a compiler geek so I tend to like languages and
language-oriented stuff.
So I volunteered to give this session, because to me,
learning programming languages is not about discussing which
language is best, whether Dart is better than JavaScript or
better than Java and so on.
Because every language that you encounter has things that
are good about them and things that people
will complain about.
And so for each type of application, there's always
sort of a sweet spot, and Dart is no exception to that.
But it is a very cool language, and it takes some of
the best features from JavaScript and Java and
combines them into one.
And I'll get to that later.
I also think learning new languages is
good for your brain.
Just like bilingualism and spoken languages, if you learn
multiple programming languages, it's going to be
good for your career.
It's going to make you think in different ways.
And hopefully exposure to Dart will make you think about
designing web applications in different ways, perhaps ways
that are more structured, if you're not a Java programmer.
And finally, I don't really think that you can evaluate a
language unless you've developed using it.
A lot of times, you're online and you'll see people having
wars over programming languages.
My language is better than yours.
They'll microcriticize various parts of the spec.
But really, you'll never know what's cool about a language
or what sucks about it unless you actually develop with it.
And so this presentation is designed to help you utilize
what you already know, which is hopefully Java and GWT, and
get you up to speed on Dart as fast as possible so you can
try that experiment out for yourself.
And then you can make the decision whether or not you
think Dart is a good language for you or GWT is a good
language for you, or hand-coded JavaScript's a good
language for you.
And so I want to try to map concepts that you already know
from Java and GWT into Dart so that you'll understand things
faster and quicker.
I want to try to teach you some Dart idioms and to get
your feet wet in terms of porting some existing GWT
application constructs into Dart.
So what is Dart?
We say it's a structured language for web applications.
But it's more than that, because on the surface, it has
the appearance of being Java-like.
But underneath it's a dynamically typed language.
So what does that mean?
If you think of JavaScript--
it means that you can refer to things on an object, fields or
invoke methods and so on, regardless of what the
declared type is.
You might say it's a customer object, but at run time you
can still refer to that object as if it was a totally
different type.
The type doesn't restrict you from shooting
yourself in the foot.
But Dart goes a little bit further, because although you
can do that, you can also run, optionally, your application
in checked mode.
And in checked mode, the types do have meaning.
And you will get runtime errors if you, for example,
try to access something on an object or a class that wasn't
there in that type.
But in general, when you're programing in Dart, unlike in
Java, you should treat the types like annotation or
documentation for both people reading the code and for
machines that are processing it, like tools.
Dart's also a class-based
object-oriented programming language.
It's not a prototype-based language.
It's not functional language.
It's class-based object-oriented.
But because it has a type system and it's
OO, it's very toolable.
So one of the things you'll be able to do is you'll be able
to go out and get things like the Dart Editor, which is
based on the Eclipse framework, or the latest
IntelliJ plugin, and you'll actually be able to get all of
this nice stuff that you like in Java in Dart.
Command method completion, field completion, refactoring,
go to declaration--
all those things are there.
Things that are actually typically hard to do in
dynamic languages with IDEs, you can do
quite easily with Dart.
And Dart has the option of running either natively in the
Dart VM or in any other browser by using a Dart-to-JS
compiler, which compiles the JS just like GWT.
So let's dive right in.
Rather than teaching the language spec, if you haven't
seen any of the other sessions, I'm just going to
start off with Java and try to transmorgify it into Dart.
Let's see how that works out.
So the first thing that's different between Dart and
Java is basically, there's no access modifier keywords.
So you can basically just remove the private and public
declarations and the code will continue to work.
The next thing is that types are optional.
So it's not-- we don't always recommend removing types.
I think well-written library code should have the types
there so when other people are reading your code, they'll
actually kind of know the intent.
But just to show you, we can remove that string
declaration, that Boolean field declaration, and we end
up with that.
The other thing is that--
and I actually like this feature.
This is one of my favorite features of Dart.
In Java, you write the same code over and over and over
again for initializing constructors.
You have a constructor.
It takes three parameters.
What is the first thing you do in the body of the
constructor?
This dot x equals y, this dot a equals b, and so on, right?
The same thing--
and a lot of languages have this problem too, but Dart
actually has a little bit of syntactic sugar for this.
So if you want to auto-assign a parameter to a field, then
you refer to the field in the constructor parameter
declaration with a this qualifier.
So here I'm saying this.name and that's it, in the
constructor parameter list.
And basically the Dart VM or the Dart compiler knows that
that refers to the field name, which has a string type, and
it's going to autogenerate this.name equals name for you.

In Java, if you have a block of code in an if statement or
a for statement that only has one line, you now that you can
eliminate the curly braces and just put a semicolon.
In Dart, even for method declarations, you can
eliminate the curly braces.
So here is a method that only has one line of code in it.
And so the cat constructor just equals greater-than and
then an expression to the right of it.

So Dart doesn't have packages.
It has something that's not exactly like a package.
It's called a library.
And so here we just delete package com.foo and we just
use #library('foo'), which is basically saying the code
below it is part of that library.

Now I said that Dart doesn't have access qualifiers, like
public and private.
But you can hide things within a library.
So you can make it so that no one outside of the library foo
can see a particular variable.
And the way you do that is by putting a leading underscore
on the field name.
So in this example, _name and _iCanHazMeme are only visible
to classes within the library foo.
So Dart doesn't have an import statement like Java, but it
does have #import.
And with #import, basically, you import libraries.
And this is the syntax for it.
So we're getting there.
We're almost fully converted.
So Dart has final fields, but they're initialized
differently than Java.
They're using the C++-style initializer list.
So if you have some final fields, they have to be
assigned during construction.
And so the way you do it is you put a colon after the
constructor and then a comma-separated list of
assignments.

Dart also has static fields.
So you can see in this example, UBER_CAT, we want it
be a static, final, immutable Cat, right,
that everyone sees.

And you can initialize them to be immutable or singleton--
think of string interning in Java--
by using something Dart has called a const constructor.
So if you put the const keyword in front of the Cat
constructor, essentially what this is saying is that there's
only ever one instance of that Cat with that parameter name.
So if you construct a Cat and the name is Mr. Tibbles, then
there's only one instance of Mr. Tibbles.
And the next time you try to allocate one, you'll still get
the same instance.
That means you can use a reference
comparison, for example.
Another biggie, and this'll probably be the biggest shock
if you're coming from Java or GWT, is that there's no
function overloading in Dart.
And so here's a typical example of Java--
the Money class, where it's storing things as a
fixed-point integer.
Let's say multiplied by 100, so it's in pennies.
And so someone might have three constructors.
One that takes an int, one that takes a string, and one
that takes a double.
And they might have some overloaded methods.
So down at the bottom we have two add methods.
One takes another Money class, and one takes another Money
class but optionally charges tax before it adds the money.
So Dart works around this problem by introducing named
constructors.
So in Dart, your constructor does not always have to have
the same name as your class itself.
In Java, your constructor for the Cat class is
always called Cat.
In Dart, you have a constructor called
Money.fromDouble and Money.fromString.
So the actual qualified constructor name is itself an
constructor.
So someone, if they wanted to create Money from a double,
they'd say new Money.fromDouble
and then the value.

Likewise, for the overloaded method case, what we can do is
we can collapse those two methods into a single method
because Dart has optional parameters.
So all you do to make a parameter optional is you
enclose it in square brackets.
So now the original Money class, which had two
parameters, and then another specialized version, which had
the emitted parameter is collapsed into a single method
which has the optional parameter.

And you could specify default values for the parameters.
So typically in Java, if you have this case where you have
two overloads, and one of them is just an overload because
you want to allow the person to emit an optional parameter,
you'd typically have one method call the other and pass
in the default value.
Here you can just specify the value.
So I say in the default, if you don't specify
chargeTax is true.
The government's gonna love that.
As a bonus, all optional parameters are named
parameters.
So if you have a list of like five optional parameters, and
maybe you don't memorize the API but you happen to know the
names of the parameters, you can specify the optional
parameter by putting a colon in front of its name.
So I'm passing the chargeTax parameter by
saying chargeTax: false.

Here's an interesting thing.
A lot of people complain about Java, of people creating tons
of factory service locator, factory factory classes, and
things like that.
And factories and dependency injection are very, very
common in Java.
And I think Dart recognized this and said, we should
provide a solution for this that doesn't
add a lot of bloat.
And so what you can do is you can designate a constructor as
a factory constructor.
So here we're saying the Money constructor that takes an
amount is a factory constructor.
And what it does is it says, if the amount is equal to
zero, then return this static final interned instance of
zero, else return a new Money object that's
constructed on the fly.
And typically you might do this if you want to use zero
as a special value to use reference equality.
There's only ever one Money object representing zero
money, but other ones actually have differing values.
And so what happens is, when you new the Money object it
actually calls this method, and the method actually can
return a different object, unlike a typical Java
constructor.
You can't return something from the constructor that's
different than the object itself.

And Dart also has operator overloading.
So we can make that Money class a little easier to use
by overwriting operator+ on it.
And now you can just say money+money instead of
money.add(money).

And finally, Dart has getters and setters.
So this is a typical POJO, Plain Old Job
Object bean, in Java.
And so we have a field called Amount, so naturally we have
to write an int get amount that returns _amount, and a
setter for it.
And then on the bottom, you see method calls from it.
Whereas in Dart, what you can do is you can put a get
keyword in front of the function name and a set
keyword in front of the setter.
And then what happens is you can reference the object as if
those were field references, not method calls.
And Dart will actually invoke the getter methods for you.
So this is kind of a less boilerplate-y way of setting
up fields with getters and setters or properties.
Let's talk about the type system differences.
So there's really only five built-in types you need to
worry about.
There are two numeric types.
There's int and double.
And yes, you're reading that right.
The integer is infinite precision, so you never have
to worry about overflow in your code.
If you want to compute--
boy, don't try to compute Google because
you'll run out of memory.
But if you want to compute a very large number, you can use
integers to do it.
Doubles are 64-bit IEEE-754 goodness.
Typically you might have a game or a lot of math or
physics code, and they're great to use for that.
Dart does have a String.
Class It has a bool type--
not Boolean, but bool.
And it has two fundamental collection types that
everybody uses, hopefully, which is List and Map.
And like every other language except for Java, they have
first-class support.
So there are literals for maps and lists
built into the language.
So you define a List literal with square brackets, and you
define a map with curly braces, much like JSON and
JavaScript.
There's some big differences with strings
between Java and Dart.
String support interpolation in Dart-- so you can put a
dollar sign and then a variable name inside of any
string, and Dart will substitute that with the
variable of the same name that's in the same scope.
But you can go a little bit further, too.
You could put a curly brace.
And for example, you can invoke a method call on that.
If this looks familiar to you, it looks very much like the
expression language that's often in many Java frameworks,
like JSP and JSS and things like that, or like Apache
property substitution.
One of the features I love most, actually, is heredocs,
and Dart was very good to add that.
And it's basically multi-line strings that you can include
verbatim in the code.
And that's really, really useful if you want to bake in
some HTML or some CSS into your app, and you don't have
to worry about going in and escaping every new line and
all the other kind of stuff.
You can kind of structure DSL-specific syntaxes right
into your Dart source code, just by putting
in a multiline string.
And if you don't want interpolation, because maybe
you want literal dollar signs, just put an @ in front of the
string, and it turns it off for that string.

I don't want to say a lot about generics.
Dart does have generics, but they are radically simplified
generics, which is a good thing.
Because Java generics--
I mean, if anybody's played around in Scala, this sounds
like somebody whining, but Java generics are actually
kind of complicated, and a lot of people don't understand the
difference between covariants, invariants, contravariants,
wild cards, and things like that.
And as a result, most people don't even use those features.
I mean, if you're Joshua Bloch, you use them in the
Java collections classes, but if you go look at most regular
Java programmers, they hardly ever use most
of these extra features.
And so Dart basically said, why add all this extra
complexity?
Most people would just use Foo if T So Dart only has
covariants for generics.
But Dart does not use erasure.
So generics in Dart are actual reified.
You can check the runtime types.
So a Foo or a list of int-- you can actually check
it to see what it is.
And if you try to say, is this a foo of
string, it will say false.
That's not the case in Java, where if you have a list of T,
a list of anything, basically it's only really a list, and
you actually cannot check what it is at runtime.
But in general, I would say, don't worry
too much about this.
Things just kind of work, and you don't have to worry too
much about it.
Generics in Dart are simple and they work out of the box.
And don't get yourself worried about what's being left out.

The other-- and I want to say the third favorite feature of
mine is finally lexically scoped closures.
I wish Java had them.
I wish Java 8 will have them.
Hopefully they will.
But yes.
Bye-bye, anonymous classes, and hello function types.
So here is an example of an apply function.
It takes a list of integers and applies the function to
each thing in the list and returns a new list.
And so at the bottom I just show a simple example.
Apply an inline literal list of 1, 2, 3, 4, 5, a function
which basically doubles its input.
So what you do to declare a closure is you basically put
the parameters in parentheses with optional types, and then
you put =>, and then the expression to be evaluated,
the function body.
You can use curly braces there too if you want.

And you can make things a little bit more readable
because Dart has typedefs.
So often, these function declarations, if they're
really complicated and take a lot of parameters-- maybe have
a function which takes functions to functions, and
things like that--
you want to break them down into separate steps.
And with typedefs, you can do that.
So here I'm basically saying that there is a function that
takes an int and returns an int, and I'm going to give it
the name Transformer.
And then my apply function now, rather than saying--
if you look at the previous slide, it's int f(int arg))
Now this says Transformer bay.

Maybe some of you get the reference to that.
And so then at the bottom, I have another one where I say
Transformer prime = (x) => 2 * x.

And so it looks a little more readable.
You can document the typedef and things like that.
OK so that kind of covers the language syntax case.
Now I'm going to cover just some of the API differences.
So Dart has two collection classes, as I mentioned
before, and they are generified.
That's List and Map.
And so in Dart, you can create them in two ways.
You can new them, with the new operator, or you can construct
them inline with literals, which a lot of people do.
That's a very common thing to do.
And you don't actually have to worry about the underlying
concrete types.
So Map and List will be abstract classes and there
might be multiple implementations of Map and
List, but Dart will pick a default
implementation for you.
In Java, you have to think, am I going to use HashMap?
Am I going to use LinkedHashMap?
And things like that.
And then iteration--
you have multiple choices, right?
So you can use what's called external iteration, where you
basically have your own for loop, you ask for the length
of the list, and you iterate over it and you index into it
like an array, like List[i].
No operator overloading to access list members.
You don't have to say List.get(i).
Or you could use the For In operators.
You could say for (value in list) {doSomething}.

Or you can use an internal iterator, which is basically,
you pass a closure to the forEach method, and it will
loop over the collection internally and call your
function for each member of the list.
And then there's equivalent methods for Map.
It's just that they take two parameters for the forEach
method, key and value, or you have to get the set of keys
and the set of values to iterate over.
All right.
So now let's actually move on to converting the actual GWT
code over to Dart.
And so let's first convert a really simple example.
Here's a "Hello World" in GWT.
You have the onModuleLoad function, and I'm going to
call window.alert("Hello World").
What would this look like in Dart?
Really, really compact.
So first thing is we import the Dart HTML library so we
can get the window function, the alert function.
Secondly, Dart's EntryPoint, is the main function.
So--
whoops--
what?
There we go.
Let me restart.
I don't know why that happened.
Let's go back.

I have a lot of slides.
OK.
There we go.
This one.
And so if you look at this, you have to declare a class.
You have to implement EntryPoint.
You have to have an onModuleLoad function with
access qualifiers.
And then you call window.alert.
Here you just declare a main function and that basically
runs whatever code is specified.
But a lot of times people are going to structure a little
more, because you don't want everything running in main.
So people might decide to declare a class.
So here I have a class called Hello, and my equivalent of
onModuleLoad is the go function.
And from main, I just create that Hello
instance and invoke go.

So this is a really important point right now.
So you know, Dart is bleeding edge.
And we're working hard on it, and we're working
as fast as we can.
But we don't yet have a widget library in the SDK that you
can download today.
One will be available soon.
If you've seen some of the other demos, like the Swarm
app, there's some really slick stuff going on.
And that knowledge will translate into an awesome
widget library.
But for now, we just have DOM programming.
And so I'm going to compare GWT DOM program versus Dart
DOM programming.
So here is an example.
I might have a div tag with ID "button" in the HTML.
So I'm going to add an EventListener, a click
EventListener, to that div tag.
And so here's the GWT code that you have
to write to do that.
So you have to look it up by going Document.get, which gets
the document element.
Then getElementByID and the button.
Then you have to sink the event type event you want to
listen to, so you use DOM.sinkEvents.
Then you have to set the EventListener callback,
DOM.setEventListener, and have an anonymous inner class
callback with a function declared in it, which then has
window.alert.
So what would that look like in Dart?
You just say Query ("#ID").on.click.add and then
a closure for the EventHandler.
Now there's a couple of interesting
things going on here.
First of all, Dart has global functions, and so not every
method has to be part of a class.
So there's a global top-level query function, and basically
it kind of acts like the dollar-sign function in
jQuery, if you want to think of it like that.
So I'm looking up the button with ID "button." And I'm
going to get back an element.
Now the element going to have a magic field in it called on.
And on is going to have a bunch of setter properties--
like I showed you setters earlier--
for each type of event.
So here we've got one called click--
a setter.
We've got one called mouseOver and things like that.
And each one of those is going to have an add method on it.
And so now, I'm just saying--
for the element that I got back, on click, give me back
this click thing, which can then allow me to add a closure
to it, which will be called.
And so that's basically how you would write the same code.
You look at it again--

it looks a lot more readable.

So that's basically converting a Hello World and some simple
DOM programming.
This is kind of where Dart is today.
As I said, there's high-level libraries that are on the way
real soon now.
But for now, it's really an HTML5 experience, which is not
always the worst thing.
But here's the sort of high-level mapping of what API
in GWT corresponds to what you have to do in Dart.
So if you're using com.google.gwt.dom, you're
going to import the dart:html library.
If you're using UIBinder and SafeHTMLTemplates and
[INAUDIBLE] messages from GWT, you're probably just going to
use Dart string interpolation to do the same thing.
If you're doing server communication, like GWT RPC or
Request Factory, in Dart, right now, today, you're going
to use XMLHttpRequest.
For widgets, of course, GWT has widgets.
For Dart, real soon now there's going to
be some cool stuff.
And in multi-process, for using WebWorkers, GWT has some
third-party hacks that add WebWorker support to GWT.
Dart actually has WebWorkers built in to the language as a
first-class construct.
They're called isolates.
And so doing multi-process stuff within Dart really has
no equal anywhere.
They make it really easy to use.
So let's try to get a little more deeper and port something
more complex.
Let's try to port a widget.

Now widgets are written in many different ways in GWT.
I'm just going to focus on the modern way people do widgets
with GWT, which is with UIBinder.
And so the idea here is just how can I take a GWT widget
that I've written that uses UIBinder to define its HTML
structure and port that over to Dart?
And the general idea here is just to take the UIBinder
template and enclose it in a multi-line string.
Convert any of the ui:field attributes to just be ID
attributes on the elements.
Then build a Dart class to represent normally what GWT
would generate to bind that template, which is basically
looking up the IDs and assigning them to fields in
your object.
And then you'll have to basically move the raw HTML
resources, like CssResource, to be external CSS by using a
link tag to include the CSS.
It's not a perfect solution, but it's not horribly bad to
port code like this.
So here's an example.
This is how it looks in Java.
I have a UIBinder template with a div tag.
It says, Hello, .
And then here I have a little bit of code which basically
calls setElement(UIBin der.CreateandBindUi(this)).
Now if you're GWT programmer, you know
this works some magic.
And what happens is, is it basically generates some code
behind the scenes that will take that UIBinder template,
create a div tag, and inject that HTML source, as an inner
HTML, into it.
And put it into the document.
And then the next thing it will do is it will go through
and it will look up that field, that
UI field, the nameSpan.
And when it finds that element, it will store it in
the field on your class.
You can see here, this nameSpan attribute.
So this element will be looked up in the DOM with
getElementById and then put there for you.
So kind of like a dependency injection.
So we want to get that into Dart.
So how can we emulate that?
So the first thing is, we remove the top and bottom XML
tags and replace them with triple-quote.
And so now we've just put it into a multi-line string.
And we replace the ui:field with just id='nameSpan'.
And then secondly, the next step that we'd do is we would
write a function--
that you can see right here--
which will first create a new HTML element with the
template, which we defined up here.
And what this new Element.html does is it actually kind of
creates a div and injects the string as the innerHTML of it.
So what you get back, basically, is essentially what
UIBinder was doing as a div element with the HTML in it.
And then once we get that, we input it into the DOM, the
next thing we're going to do is run element.query on it and
look up id nameSpan and then assign it to the field
nameSpan here.
So GWT kind of automates that part of it, which is
automatically looking up the element for you and then
signing it.
So you actually have to write that code yourself here, but
it's not too bad.
But you could make it expandable, extensible.
So here I have one where we have two nameSpan tags in my
template and I would have two fields, like a
nameSpan1 and a nameSpan2.
Instead of having fields on my object, I use a map, a map
from the id to the element.
And then what I do is I extend my setElementByTemplate
function to take the template, which was from up here, and
take a list of ids to look up, which were up here.
And then what this is going to do is it's going to inject
this and then document.query look up each one of those and
inject them into the map for me.
And that's what this basically does here.
It loops over for each ID and then it injects into the map,
calling element.query with the id.
And so that's a way to sort of make it extensible.
So you could have an arbitrary number of elements that are
looked up and automatically injected for you, so you can
cache them and look them up later.
What about instantiated widgets, though, right?
So I just showed you HTML tags that
are in UIBinder templates.
But you know that GWT does a lot more.
So for example, you might use HTMLPanel, or Menu item, or
Tree item, and things like that.
Well, if it's a basic leaf widget in GWT, like an input,
or a checkbox, or a text area, or something, you can just
replace those with the HTML5 equivalents.
In fact for GWT, even, we recommend actually not using
heavyweight widgets for stuff that's just basic HTML5.
It's just too much overhead.
But if you have something like a composite type that's really
complex, like a menu or a tree--
yes, right now, you're going to actually need to code
replacements.
The good news is you're only going to do it once, but yeah,
you're going to have to write your own tree for now.
And I expect that as Dart gets a larger and larger community,
even if Dart provides its own widget library, probably other
people are going to write their own
widget libraries too.
Someone will have a fancy tree or a fancy carousel widget or
something that is not included in the library.
So for now, it's an HTML experience, but things will
get better.
But if you think it's too hard to port widgets, then there's
an alternate pattern that you can use to get your
feet wet with Dart.
Let's say you have an existing GWT application and you want
to kind of try out Dart.
Maybe you want to write a new page.
You want to add a new page to your application, like a
settings screen or like a feedback page or something.
And you want to write that part in Dart, but the entire
rest of the part, you want to keep in GWT.
So you want to keep your application running at all
times and not throw everything away and start from scratch.
The good news is that if you use the Activities and Places
model that's been in GWT for a while, or if you've always
been using history tag routing, then you could do
this quite easily.
And the way you could do it is this.
You have your GWT application look for history state changes
in the hashtag.
And if the history change is one of the things that your
app understands, then route the event to the existing GWT
code that's going to put up that page.
But if it's something you don't understand, then send a
message or let it fall through to a Dart application that's
running in the same page.
So you've source-scripted in the GWT module and you've also
source-scripted in your Dart app, and they're both looking
at the history.
And if they agree not to step on each other's toes, this
could work very well.
The Dart code could look at it and go, well, I don't
understand that history tag, so GWT can probably take care
of that one.
But I see one that's destined for me, like the feedback
page, the new feedback page, so I'm basically going to take
over the main content area of the page and
replace it with my UI.
Right?
And so that gives you kind of a very high-level integration
point for putting Dart pages into your existing GWT apps.

You could migrate page at a time that way.
Here's a picture, like you might have a banking
application.
And so maybe you have an existing bill payment service,
and #billpay on the URL will send you to the bill pay
activity in the GWT app.
But you're adding a new page, which is banking, like maybe
bank transfers.
And so you've written that one in Dart.
So what you do is you just have the Dart part of the app
that's sitting in the page look for #banking in the URL.
And that's the signal for it to actually take over the
content area and install its view.
But if you do this, the very next thing you're going to run
into is, how do you share application state?
I mean, maybe the GWT app just did something and now the Dart
app actually has to get what was changed.
And so there are a number of options for this.
One option is, use browser storage.
So you could use IndexDB, SessionStorage, or cookies and
have GWT commit transient session-oriented data, let's
say the current account or profile representing the user.
Have it committed to IndexDB storage in the browser.
And then when Dart goes to kick off its view, like you
navigate to the banking page, then it's going to read from
the database and get things related to the user, like his
name, his current account, authentication tokens to let
him make transfers, and things like that.
The other option is, you could put serialized data objects
into the DOM.
So if you want Dart to pick up something that GWT has to send
to it, one option is just create an element, like a div
element, use display none, and put some data in there.
And then give it an id, like an id =
data object or something.
And then just have Dart look it up and parse
the JSON out of it.
That's another option.
Probably the cleanest mechanism
is just to use messaging.
So in the new HTML5 browsers. you have window.postMessage().
So you can use this for communication
between GWT and Dart.
Have Dart listen on window object for messages and just
have GWT post messages, so you can transfer data back and
forth between the two running apps that way.
So one thing, as a GWT programmer, you're probably
wondering about is something like JSNI.
And we got a lot of mileage out of that with GWT.
Early on in GWT's adoption, there were a lot of JavaScript
libraries out there.
We didn't have really killer widgets.
GWT widgets really looked terrible out of the box.
And so people we're going and picking up jQuery or picking
up Ext JS and things like that and they were
wrapping them with GWT.
And that really held people over until we could actually
deliver better widgets in later versions.
And so you might be thinking, well I'll do that for Dart.
I'll use Dart and I'll wrap some cool widgets until the
Dart team delivers the better widget set.
Unfortunately, Dart does not have JSNI.
And there's a very good reason for that.
And so you might think of Dart as it is today as
a Dart-to-JS compiler.
But Dart as it's envisioned is actually a virtual machine
that runs just like V8 does, but it runs Dart code.
And so because it's another virtual machine in the
browser, it's separate from V8.
It has a separate heap.
So you can't just pass an object reference from one to
the other, because they live in different memory spaces.
Probably even different process sandboxes.
So that wouldn't be very efficient, even if you could
pull it off.
But there still is a need for you to make calls from Dart to
JavaScript and vice versa.
There's no question about that.
There is a need to do that.
Like, you might want to interact with the Maps API
from Google, and there's no Dart Maps API yet.
And so there has to be a way to do this.
And fortunately, there is a way to do it.
There's an unofficial way--
quite a few, actually, which I'm going to show you.
And I'm going to make you a promise that we're actually
working on it, and actually, a real nice solution will be
coming later down the pipe.
So what are the ways we can do this?
Well one way is this postMessage() communication,
like I just discussed.
So what you could do is you could have JavaScript listen
for window.onmessage, and anything that basically comes
in through a message, you just run eval on it.
And then likewise, in the Dart world--
this is Dart code here--
you do postMessage, and in there you put JavaScript.
And then so the JavaScript event handler gets triggered
and it just runs eval.
So I've made a call from Dart to JavaScript in that way.
It's not pretty, but it works.
Another solution that people do, because you have a little
bit more control, is script tag injections.
So in Dart code, you could just create a script tag, set
its text attribute to be the JavaScript text, and insert it
into the body of the browser document, and it
will just be evaluated.
But that's only uni-directional communication,
and you can't build an API if you can't get any values back
after you evaluate the code.
You could have bi-directional messaging.
So I could send the message to JavaScript, and it'll say,
call this method on Google Maps for me.
Google Maps dot setCurrentLongitude = 10.
But the problem is, I can't get any return value from that
function back.
You could make the JavaScript then post the message back to
Dart and have Dart listen for a message, which then has the
return value in it.
And in that case, it would look very much like
asynchronous JSON-RPC back and forth between the server.
But the API that could be built around that would look
pretty nasty.
For example, every getter and setter would have to take a
closure that would be called back into with the return
value when it was ready.
You have got to remember, the browser isn't always
synchronous.
So if you ask the browser to do something, it could do it
immediately, or actually, it could do it
at next event loop.
And so you have to basically pass it a callback because it
could be executed at a later time.
And so this would lead to a really poor API experience.
But it turns out, there's actually an API in a browser.
It's one of the very few synchronous XHRs or another
that actually is synchronous, meaning it actually blocks
until it finishes executing.
And it's called dispatchEvent().
And what it allows you to do is to fire off an event, like
onClick or something like that, and it will be handled
immediately.
Not the next time the browser goes to the event loop, or
after all the set timeouts run, but right now.
And so that gives us a hack or sort of a doorway to get true
synchronous bi-directional messaging between Dart and
JavaScript.
And the essential way you'll do it is this.
You're going to invent a new custom event name.
And you can do that in JavaScript.
You can make your own events.
You don't have to just use onClick or mouseover.
And I'll call it 'dartjsni', just for GWT'S sake.
And then what you're going to do is you're going to register
an event listener in Dart via window.addEventListener and
look for this 'dartjsni' event to happen, and do something
when it does happen.
And then you're going to construct a serialization
format for RPC calls.
Maybe you just take the method name and all the arguments
that you want to call and you serialize them in a JSON
object or something.
And you have the callback that's looking for that
'dartjsni' event deserialize it and evaluate it.
Then you're going to invent another event name-- let's
call it 'returnjsni'--
and it's going to take the return value, serialize it,
and then fire via window.dispatchEvent this
'returnjsni' event.
And then in the Dart code, you're going to be looking for
window.OnDartjsni event handler, and that's going to
be the return value.
And what makes this all work is that when both sides use
dispatchEvent(), there is no asynchronicity.
You fire the event and it immediately evokes the
callback on the JavaScript side.
The JavaScript side does the evaluation and invokes
dispatchEvent for 'returnjsni' and it immediately runs the
Dart event handler, all in one synchronous loop.
This is just a picture of it.
It's probably not very useful for you.
But I tried to draw how it would work.

I'm just going to skip that picture for now.
So you could make the JSNI mappings even
more natural, right?
Like what if you just wanted to have a Dart object, and
when you refer on that Dart object to any field or any
method, it actually is kind of a mirror or a proxy directly
into JavaScript.
It kind of represents a JavaScript object on the other
side of the fence.
And so Dart has two features that actually almost make this
look completely natural and almost like the JavaScript's
not even involved.
The first is operator overloading.
So you can implement the operator[]--
and here I have a class called JsProxy--
and it takes a field name.
And then what you do is you make that synchronous call
over using that Dart JSNI method I just
described how you'd do.
And you index the field name on the object reference that
you're holding on to, that this proxy object represents.
Dart has another feature I haven't described yet.
Because it's a dynamic language, what I said earlier
was is that you can try to access or invoke anything on
an object, even though it's the wrong type, and it will
still try it.
And if it fails, it doesn't fail completely.
What it does is it invokes noSuchMethod.
So it's a magical method.
You could put it on a Dart class to override it, and it
will be called for any method that it can't find, that
someone tried to invoke.
And so in this way, you could make a JsProxy class that can
invoke any JavaScript method that exists in the JSVM by
defining a noSuchMethod.
It takes the name of the method someone's trying to
invoke and a list of the arguments, and then you just
make a synchronous call using what I just described in the
previous slide.
And it will return the value as if that method existed on
the JsProxy object by going to JavaScript and asking it to
evaluate it.
So that's another interesting idiom or
example you could use.
And if you wanted to invoke GWT code directly from Dart or
vice versa, I would advocate using a library I wrote called
GWT Exporter.
And what that allows you to do is to put @Export annotations
on your classes and Java methods.
And what it does is it manually declares JavaScript
exports in the top-level window object of the page.
And then once you've got those things exposed to JavaScript,
then you can use the Dart JSNI method technique I showed you
to just call directly into GWT.
Likewise, if you wanted to do it the other way around, you
could export Dart functions into JavaScript by writing a
JavaScript function which, when invoked, uses the Dart
JSNI mechanism to send a message over to Dart and say,
I'm invoking this method on this Dart class.
However what I've just shown you, it's really complicated
and it's kind of a hack.
And I would not advocate using it, except for specialized
scenarios like trying to create a really nice mapping
for, like, the Google Maps library or some other
JavaScript library, where it would be painful to have an
asynchronous approach.
Otherwise, I would suggest, just use postMessage.
It's the easiest thing and the least likely to fail.
And for the record, we actually don't know how much
longer dispatch will be around.
It could very well be that the HTML5 committee could say
tomorrow, we're removing that.

So in summary I just wanted to say that Dart is a cool new
dynamic language.
It takes some of the best things from JavaScript, which
is the ability to start up quickly without a compile
pass, to have the program run even though
the types are wrong.
So you can iterate on something, even
if you've got errors.
But also to allow the language to be tooled and tested with
compile-time static tool chains.
It offers a lightweight DOM programming library for now,
but later on, it will have a very rich library.
That's the whole point of having a structured
programming language.
They invented all of this new syntax for a type system.
They're going to build a really rich
library to support it.
It's not going to be very raw and basic like JavaScript.
Try converting some simple GWT libraries.
Get your feet wet.
Pick the simplest thing in your project and say, what
would this look like in Dart?
Just play around with it.
Have some fun.
Or integrate--
try to add a new page your app by basically writing it in
Dart and using the hashtag history routing to integrate
it into the page.
I would advocate, even if you're not going to use Dart,
to look at the GWT Activities and Places model if you're not
using it already.
Because it will help you in the future.
And finally, if you're really adventurous, try hacking a
Dart JSNI library.
You could probably release it, and if you do it quick enough,
everyone might use it.
So that's my presentation.
Hope you guys got something out of it.
And I'm open to taking some questions.
[APPLAUSE]
AUDIENCE: Yeah.
You mentioned internationalization and
string interpolation.
RAY CROMWELL: Yes.
AUDIENCE: I wonder, do you have an example of that, like
how it works in Dart?
I'm using it in GWT, but to migrate some stuff, I'm going
to need to move it do Dart.
RAY CROMWELL: Yeah, that's a good question for me.
[INAUDIBLE], do you happen to know the idiom for
doing that in Dart?
AUDIENCE: [INAUDIBLE]
RAY CROMWELL: What I was thinking of, when I wrote
that, was basically using the string interpolation to define
the templates like you would do it in a Messages class in
GWT and basically create the equivalent of a Dart
ResourceBundle but using JSON structures.
And then write in a little utility library to basically
perform the equivalent of what gets code generated in GWT,
which is to take the template and basically apply the JSON
to it to fill out the template.
Yeah, sorry.
I probably should have fleshed that out more.
I probably ran out of time, doing my slides.
AUDIENCE: That's fine.
And I'm looking for something a little bit more formal with
the Places and Activities.
Is there something like that planned for Dart?
Or is it just like window.on listening
for that native event?
RAY CROMWELL: Yeah I don't know the answer to that.
But I believe the Dart team is working on rich object models.
And they're probably looking at MBC or MBP.
Do you happen to know, Vijay?
VIJAY:MENON: [INAUDIBLE]
RAY CROMWELL: So just in case no one heard that, they built
a really nice application called Swarm.
And what they're doing is they're taking the lessons
learned from building that rich UI and the way they've
organized it and basically trying to extract the
libraries and the patterns out of it that they're going to
use for Dart.
And so I don't think that they have anything
today that's concrete.
But I do believe that-- because Seth Ladd is heavily
involved in interacting with the community who's
dealing with Dart.
And Seth is a really big fan of MBC and MBP stuff.
So there probably will be something that great.
But sorry, I don't know the answer.
AUDIENCE: That's OK.
Last question, I promise.
When I last looked at Dart, it said "Alpha" on it.
Do we know when it's going to be promoted?
RAY CROMWELL: Is Lars or Vijay here?
Vijay, do you want to take that?
VIJAY MENON: [INAUDIBLE]

RAY CROMWELL: I'll just repeat you.
VIJAY MENON: You can get an official answer from Lars.
[INAUDIBLE]

RAY CROMWELL: Ah.
VIJAY MENON: My understanding is that later this year,
there'll be more of an official release, but I'm not
exactly sure we've said what the date is
going to be on that.
AUDIENCE: OK.
RAY CROMWELL: So later this year, there will be an
official answer.
But if you go talk to Lars, just track him down--
he's kind of a very tall guy with glasses--
he could probably give you a more concrete answer.
But I do believe, at least from my own personal
experience, the language spec seems to be settling down very
nicely now.
And so it's probably going to exit the
Alpha phase very soon.
AUDIENCE: Great.
Thank you.
RAY CROMWELL: But that shouldn't dissuade you from
trying it, right?
Have some fun with it.
VIJAY MENON: OK.
Sorry.
Just to add in-- we do have teams in Google who are
starting to use Dart.
So even though we're still working on it, it's pretty
usable today.
They wouldn't be using it if it wasn't.

AUDIENCE: Hi there.
Are there any legs to the rumor that GWT is looking for
new intermediate language, and that intermediate language
might be Dart?
RAY CROMWELL: Yeah, there's nothing official.
There's been some talk about that.
I know I've thought about it personally, of building a Dart
back end for GWT.
So if and when Chrome actually has the Dart VM built into it,
it might be the case that either one of two
things might happen.
Either someone might build a back-end for GWT that emits
Dart code, compiles the Dart, just to take advantage of the
speed and start-up time improvements that the Dart VM
will have over V8.
The other option, actually, and I think this is probably
more likely, is that someone will build a tool that
actually will help migrate Java code to Dart in case you
want to basically port some code over.
There are some difficulties in compiling GWT code to Dart
because of JavaScript.
So you can imagine, any large GWT application at sort of the
leaves of the program, deepest down, is going to have JSNI
method calls to deal with the browser.
And so those would have to be replaced with the Dart library
equivalents.
So if someone's calling, like, dom.getElementById, rather
than making a JSNI call there, which would have to use this
hack, it would have to replace it with the equivalent
dart:html library and call the actual Dart method.
And it's certainly possible to do that, but it would actually
be a lot of mapping work.
But yeah.
We've talked about it.
If I have nothing official to say.
AUDIENCE: Thank you.
AUDIENCE: Do you think there's going to--
when they finally get to release, will
they have the widgets?
And will they be similar to what GWT has already?
RAY CROMWELL: They probably will be.
So I don't know, actually, the timeline on the widgets.
But I know what their philosophy and intention is.
And so their philosophy and intention is actually to
deliver widgets that probably go far beyond what GWT has.
So GWT, when it started, basically they wanted it to be
more like JavaScript.
We didn't want to be very opinionated about what the
widgets looked like, so the first GWT widgets were very
ugly out of the box.
They didn't provide very much styling at all.
Later, we got some sense knocked into us, and we
realized most programmers can't take the time to
actually style all their widgets.
We should provide some default that actually looks
reasonable.
And we did that.
But still, it's nothing compared to what Sencha has,
for example.
Right?
And so that was probably a mistake
early in the GWT design.
The Dart team, I think, is eyeing the fact that people
want to design apps and they want to design them to be
productive, and they want to wow their consumers.
And so you need not just a widget library.
You need a very sexy widget library out of the box.
And so they're actually aiming to make something that's very
lickable, something that you're going to
love out of the box.
And it's going to be very opinionated.
So the slider widget is going to look the way the Dart
user-interface designer wants it to look.
And it might not look the way you want it to look, but it's
probably going to look really sweet.
And so that's basically what they're looking at.
Am I summarizing correctly, Vijay?
OK.
I'm actually not part of the Dart team, so I don't want to
speak too much about it.
But I overheard some conversations.
OK?
You have another?
AUDIENCE: Also, I've got a lot of applications on App Engine.
And is there a pattern or something that I can use to
migrate it to that?
RAY CROMWELL: You're talking about App Engine?
AUDIENCE: App Engine using RequestFactory.
RAY CROMWELL: Oh, yeah.
I actually was going to discuss this in the
presentation, but I realized later I had too many slides
and I ran out of time.
But if you're using RequestFactory, actually--
I should take this offline.
There's an extra bonus.
Because RequestFactory's JSON-based, it's very possible
to make Dart client code work with JSON RequestFactory stuff
on the server.
It's not true for GWT-RPC.
GWT-RPC is very tightly tied in to the Java type system.
RequestFactory isn't.
So actually, it's possible to make a Dart code call
server-side Java RequestFactory code.
And so maybe I can catch you offline and discuss that.
AUDIENCE: Thank you.
AUDIENCE: OK.
So my question would be about GWT-RPC, so you already
answered it.
So there's some way to invoke GWT-RPC calls?
RAY CROMWELL: Yes.
That would be kind of difficult to pull off.
I could see you constructing something that would invoke
it, but I would see it being hard to actually deal with the
return value.
So there are Android clients that actually invoke GWT-RPC
because Android also is Java, so they can deal with the fact
that when the return value comes back and it says, like,
it's an array list of doubles or something, the classes for
decoding an array list of doubles are already present in
the runtime of Dalvik, right?
With Dart, if you invoke some server-side call and you get
back an array of things that are Java types, right, there's
not necessarily something to map to decode those and
demarshal them into on the Dart side.
So it's a little more difficult.
But invoking I could see.
As long as your API actually uses mostly primitive things,
like longs, and integers, and strings, and so on, or maybe
POJOs, I think you could pull it off.
But if you catch me outside, I might have some suggestions.
AUDIENCE: OK.
Cool.
Thanks.
RAY CROMWELL: OK.
AUDIENCE: Hello?
At [INAUDIBLE]
Google our [INAUDIBLE]
we have many talks about Google Web Toolkit and we have
a separate section in developers' handbooks about
Google Web Toolkit.
And now it seems [INAUDIBLE]
session, which mentioned Google Web Toolkit.
So I want to ask, is GWT is dead?
RAY CROMWELL: No.
I been asked this question a lot.
And if you look at Google, for example, a lot of Google's top
properties, actually, like AdWords--
97% of their revenue comes from the AdWords team.
And AdWords uses GWT for their campaign management tool.
And so it's impractical for us to say that GWT was dead,
first of all.
Second of all, Google is about choice.
The company's about choice.
You know, App Engine, for example.
We offer Java.
We offer Go.
We offer Python.
Well, we released Go recently, right?
Does that mean that Guido van Rossum is out of a job and
Python is dead?
No.
It just means that there's another option for developers.
And so what I would say for GWT is that we're not going to
take GWT away from you.
And we're still going to support JavaScript development
for V8, and we're still going to support GWT development.
But we're also offering this new option that might entice
some people, maybe some people who don't like JavaScript.
Or maybe they're people who like JavaScript, but they want
better tools for JavaScript.
They want a really nice IDE for something
that's a dynamic language.
There's Dart for you.
Or maybe they like Java, but maybe they're getting tired of
doing enterprise apps.
So nothing's changing with GWT.
In fact, if you attend my session on Friday, there is
actually some nice news that's going to be announced with
respect to GWT's future.
AUDIENCE: OK.
RAY CROMWELL: Anything else?
OK.
Thanks for coming, and--
[APPLAUSE]
RAY CROMWELL: You're welcome.
Be safe on your way down rushing to get your devices.
Don't trip and fall.