ERIC ERNST: I'm Eric Ernst.
I'm on the language team, and I really enjoyed Leaf's talk
this morning.
But I wanted to interject a little bit extra here,
a little extra point of view that he didn't cover.
So there is this issue of how to specify the foundations
of this language.
How do we make sure that we understand what the language is
in the first place?
So for that, we have the language specification,
and the language specification was published as ECMA-408
last summer.
And we're working on the language specification,
and we have a lot of updates in the current version that's
in GitHub.
And then we have these feature specifications
that specify the new features, and they're all
going to be folded into the language specification proper.
But one element in the language specification
that is a little bit difficult to get an overview over
is the specification of the grammar
because what we have in the specification
there is a lot of snippets.
So basically, we have these snippets
all over the specification, and some of these snippets
have a couple of issues that we knew about.
For instance, there were some places
where metadata could be placed in two
locations in a declaration.
That was clearly not intended, so we
had a need to make sure that we knew that this specification
was actually correct.
So instead of having a lot of textual snippets
and then letting everybody who's working
on the implementation of a tool work based on these snippets
and rely on them 100%, we would want
to have some direct feedback on the correctness of the grammar
itself, the whole grammar.
So basically, I set out to create this specification
parser, which is a parser that has a complete Dart grammar,
and that Dart grammar is something
that we are going to use to feed back into the specification.
So we want to know that the grammar is, itself, consistent,
for instance, that it has ambiguity properties
that we know about.
We're not going to get rid of all the ambiguities.
We're going to say how to resolve them.
We also want to make sure that the specification
grammar matches the actual Dart source code,
so we can run this tool, which is
a parser that is generated by the ANTLR 3 tool, parser
generator.
And then we can see that the specification of the grammar,
as we specify it in this grammar file,
will actually match the source code out there.
This is, as I mentioned, a specification
in a particular tool, this ANTLR tool,
so that means that it is not something
that we're going to make the specification of the grammar
of the language because it has accidental properties.
It's an ANTLR V3 thing, but still, we're
going to use it as input.
So we have a couple of rules here
from this specification grammar.
That is what we're using to generate the specification
parser from.
So if you compare that with the previous version,
we had here a function body, and the function body
is very much the same.
Now, it's a little bit different in the syntax
because it's a specification that
fits ANTLR V3 instead of the ad hoc format that is used
in the language specification.
But if you look at the type, then it
used to be type name and type arguments,
and that's now a lot different because we've
integrated the inline function types that Leaf mentioned.
So we are able to write function of int
instead of writing a typedef and then referring to that typedef,
so that means that we have a number of constructs
that are considerably more complex now than they used
to be.
And for instance, down there, you
have something like a Type Not function, which is the old type
as you knew it, and then it has the function
keyword separately.
And the reason why we have that is that we cannot allow
function to be an ordinary type name because then you could
give it type arguments, and then it would be ambiguous whether
we were currently reading a function type or we're reading
something that just uses functions as the name
of a class.
So we have a number of cases where we need to disambiguate,
and this is something that happens
in different ways in the specification,
the big document, 150-page document.
So the symbol literal at the top is one good example.
So basically, if you have something like Foo
dot Bar dot To String, that could be a symbol that
has three elements, but it could also
be a symbol that's Foo dot Bar, and then
you run the To String tear-off process on that
to get something that will actually
be able to return the string that represents that symbol.
So you couldn't know which one it is, and there
is no syntactic way to say that because the grammar is simply
such that it is ambiguous.
So this is something that is handled in the specification
by actually saying that you continue as far as you can.
Then the second example is the function expression,
and I won't go into the details with that.
But the point is that you could actually
have something like this expression that is here--
x to 42 dot To String.
Again, you could parse that as the function,
and then you tear off the To String method
from the function itself, which is possible but never useful.
So we adjusted the grammar to make sure that it's never
parsed like that.
And finally, we have the example down below,
where you have something that is an invocation
of a generic method, but it also parses
as two arguments of type bool.
So basically, what's happening is that we
have the specification parser.
It's supposed to help us ensure that the grammar
of the language is internally consistent,
so we have a correct grammar.
It's consistent with itself.
Second, we want to make sure that we can actually
run this actual parser on the source code
out there to see that we are tracking the language as it is,
and it's consistent with the tools.
And finally, this specification grammar
is going to be used to take the grammar rules out
of this ANTLR formulation and put it into the language
specification in a way that's free
of these accidental properties and the extra detail.
That's it.
[APPLAUSE]