-
Notifications
You must be signed in to change notification settings - Fork 24
/
dartLangSpec.tex
6140 lines (4048 loc) · 344 KB
/
dartLangSpec.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass{article}
\usepackage{epsfig}
\usepackage{dart}
\usepackage{bnf}
\usepackage{hyperref}
\newcommand{\code}[1]{{\sf #1}}
\title{Dart Programming Language Specification \\
{\large Draft Version 0.71}}
\author{The Dart Team}
\begin{document}
\maketitle
\tableofcontents
\newpage
\pagestyle{myheadings}
\markright{{\bf Draft} Dart Programming Language Specification {\bf Draft}}
\section{Notes}
Expect the contents and language rules to change over time.
%Please mail comments to gbracha@google.com.
\subsection{Licensing}
\label{licensing}
Except as otherwise noted at http://code.google.com/policies.html\#restrictions, the content of this document is licensed under the Creative Commons Attribution 3.0 License available at:
http://creativecommons.org/licenses/by/3.0/
and code samples are licensed under the BSD license available at
http://code.google.com/google\_bsd\_license.html.
\subsection{Change Log}
\label{changes}
\subsubsection{Changes Since Version 0.02}
The following changes have been made in version 0.03 since version 0.02. In addition, various typographical errors have been corrected. The changes are listed by section number.
\ref{notation}: Expanded examples of grammar.
\ref{factories}: Corrected reference to undefined production {\em typeVariables} to {\em typeParameters}.
\ref{superinterfaces}: Removed static warning when imported superinterface of a class contains private members.
The former section on factories and constructors in interfaces (now removed): Removed redundant prohibition on default values.
\ref{interfaceSuperinterfaces}: Removed static warning when imported superinterface of an interface contains private members.
\ref{expressions}: Fixed typo in grammar.
\ref{new}, \ref{const} : made explicit accessibility requirement for class being constructed.
\ref{const}: make clear that referenced constructor must be marked \CONST{}.
\ref{superInvocation}: fixed botched sentence where superclass $S$ is introduced.
\ref{postfixExpressions}: qualified definition of $v++$ so it is clear that $v$ is an identifier.
\subsubsection{Changes Since Version 0.03}
\ref{instanceMethods}. The former section on interface methods (now removed): Added missing requirement that overriding methods have same number of required parameters and all optional parameters as overridden method, in same order.
\ref{generics}: Added prohibition against cyclic type hierarchy for type parameters.
\ref{instanceCreation}: Clarified requirements on use of parameterized types in instance creation expressions.
\ref{bindingActualsToFormals}: Added requirement that $q_i$ are distinct.
\ref{staticInvocation}. Static method invocation determines the function (which may involve evaluating a getter) before evaluating the arguments, so that static invocation and top-level function invocation agree.
\ref{typeTest}: Added missing test that type being tested against is in scope and is indeed a type.
\ref{forLoop}: Changed for loop to introduce fresh variable for each iteration.
\ref{parameterizedTypes}: Malformed parameterized types generate warnings, not errors(except when used in reified contexts like instance creation and superclasses/interfaces).
\subsubsection{Changes Since Version 0.04}
Added hyperlinks in PDF.
\ref{operators}: Removed unary plus operator. Clarified that operator formals must be required.
\ref{constantConstructors}: Filled in a lot of missing detail.
The former section on factories and constructors in interfaces (now removed): Allowed factory class to be declared via a qualified name.
\ref{numbers}: Changed production for $Number$.
\ref{const}: Added requirements that actuals be constant, rules for dealing with inappropriate types of actuals, and examples. Also explicitly prohibit type parameters.
\ref{functionExpressionInvocation}: Modified final bullet to keep it inline with similar clauses in other sections. Exact wording of these sections also tweaked slightly.
\ref{unaryExpressions}: Specified ! operator. Eliminated section on prefix expressions and moved contents to section on unary expressions.
\ref{lexicalRules}: Specified unicode form of Dart source.
\subsubsection{Changes Since Version 0.05}
\ref{generativeConstructors}: Clarified how initializing formals can act as optional parameters of generative constructors.
\ref{factories}: Treat factories as constructors, so type parameters are implicitly in scope.
The former section on factories and constructors in interfaces (now removed): Simplify rules for interface factory clauses. Use the keyword \DEFAULT{} instead of \FACTORY{}.
\ref{generics}: Mention that typedefs can have type parameters.
\ref{typeTest}: Added checked mode test that type arguments match generic type.
\ref{dynamicTypeSystem}: Added definition of malformed types, and requirement on their handling in checked mode.
\subsubsection{Changes Since Version 0.06}
\ref{variables}: library variable initializers must be constant.
\ref{classes}: Added \ABSTRACT{} modifier to grammar.
\ref{classes}, \ref{staticMethods}, \ref{staticVariables}, \ref{unqualifiedInvocation},\ref{identifierReference}: Superclass static members are not in scope in subclasses, and do not conflict with subclass members.
\ref{operators}: \code{[]=} must return \VOID{}. Operator \CALL{} added to support function emulation. Removed operator \code{$>>>$}. Made explicit restriction on methods named \CALL{} or \NEGATE{}.
\ref{constants}: Added \code{!$e$} as constant expression. Clarified what happens if evaluation of a constant fails.
\ref{maps}: Map keys need not be constants. However, they are always string literals.
\ref{this}: State restrictions on use of \THIS{}.
\ref{instanceCreation}, \ref{new}: Rules for bounds checking of constructor arguments when calling default constructors for interfaces refined.
\ref{ordinaryInvocation}: Revised semantics to account for function emulation.
\ref{staticInvocation}: Revised semantics to account for function emulation.
\ref{superInvocation}: Factory constructors cannot contain super invocations. Revised semantics to account for function emulation.
\ref{assignment}: Specified assignment involving \code{[]=} operator.
\ref{compoundAssignment}: Removed operator \code{$>>>$}.
\ref{shift}: Removed operator \code{$>>>$}.
\ref{postfixExpressions}: Postfix \code{-{}-} operator specified. Behavior of postfix operations on subscripted expressions specified.
\ref{identifierReference}: Added built-in identifier \CALL{}. Banned use of built-in identifiers as types made other uses warnings.
\ref{typeTest}: Moved specification of test that type arguments match generic type to \ref{dynamicTypeSystem}.
\ref{switch}: Corrected evaluation of case clauses so that case expression is the receiver of ==. Revised specification to correctly deal with blank statements in case clauses.
\ref{assert}: Fixed bug in \ASSERT{} specification that could lead to puzzlers.
\ref{dynamicTypeSystem}: Consolidated definition of malformed types.
\ref{functionTypes}: Revised semantics to account for function emulation.
\subsubsection{Changes Since Version 0.07}
\ref{variables}: Static variables are lazily initialized, but need not be constants. Orthogonal notion of constant variable introduced.
\ref{operators}: Added \EQUALS{} operator as part of revised \code{==} treatment.
\ref{generativeConstructors}: Initializing formals have the same type as the field they correspond to.
\ref{staticVariables}: Static variable getter rules revised to deal with lazy initialization.
\ref{expressions}: Modified syntax to support cascaded method invocations.
\ref{constants}: Removed support for + operator on Strings. Extended string constants to support certain cases of string interpolation. Revised constants to deal with constant variables.
\ref{strings}: Corrected definition of \code{HEX\_DIGIT\_SEQUENCE}. Support implicit concatenation of adjacent single line strings.
\ref{bindingActualsToFormals}: Centralized and corrected type rules for function invocation.
\ref{methodInvocation}: Moved rules for checking function/method invocations to \ref{bindingActualsToFormals}. Added definition of cascaded method invocations.
\ref{getterInvocation}, \ref{assignment}: Updated \code{noSuchMethod()} call for getters and setters to conform to planned API.
\ref{conditional}: Modified syntax to support cascaded method invocations.
\ref{equality}: Revised semantics for \code{==}.
\ref{identifierReference}: Removed \IMPORT{}, \LIBRARY{} and \SOURCE{} from list of built-in identifiers and added \EQUALS{}. Revised rules for evaluating identifiers to deal with lazy static variable initialization.
\ref{continue}: Fixed bug that allowed \CONTINUE{} labeled on non-loops.
\ref{librariesAndScripts}: Revised syntax so no space is permitted between \code{\#} and directives. Introduced \code{show:} combinator. Describe \code{prefix:} as a combinator. Added initial discussion of namespaces. Preclude string interpolation in arguments to directives.
\subsubsection{Changes Since Version 0.08}
\ref{instanceMethods}, \ref{abstractInstanceMembers}: Abstract methods may specify default values.
\ref{interfaces}, The former section on interface methods (now removed): Interface methods may specify default values.
\ref{constants}: The \code{\~{}/ } operator can apply to doubles.
\ref{instanceCreation}: Refined rules regarding abstract class instantiation, allowing factories to be used.
\ref{switch}: \SWITCH{} statement specification revised.
\ref{throw}: \THROW{} may not throw \NULL{}.
\ref{imports}: Imports introduce a scope separate from the library scope. Multiple libraries may share prefix.
\ref{typedef}: Recursive typedefs disallowed.
\subsubsection{Changes Since Version 0.09}
\ref{scoping}: Consolidated discussion of namespaces and scopes. Started to tighten up definitions of scopes.
\ref{classes}: Overriding of fields allowed.
\ref{operators}: \CALL{} is no longer an operator.
The former section on variables in interfaces (now removed): Added specification of variable declarations in interfaces.
\ref{constants}: Static methods and top-level functions are compile-time constants.
\ref{strings}: Multiline strings can be implicitly concatenated and contain interpolated expressions.
\ref{typeCast}: Type cast expression added.
\ref{expressionStatements}: Map literals cannot be expression statements.
\ref{try}, \ref{throw}: Clarified type of stack trace.
\ref{exports}, \ref{imports}: Added re-export facility.
\subsubsection{Changes Since Version 0.10}
\ref{overview}: Discuss reified runtime types.
\ref{scoping}: Removed shadowing warnings. Allow overloading of \code{-}.
\ref{variables}: Centralized discussion of implicit getters and setters.
\ref{externalFunctions}: External functions added.
\ref{classes}: Abstract classes must now be declared explicitly.
\ref{operators}: Eliminate \NEGATE{} in favor of overloaded unary minus. Eliminate \EQUALS{} in favor of operator \code{==}.
\ref{setters}: Setter syntax no longer includes = sign after the name.
\ref{abstractInstanceMembers}: Clarify that getters and setters may be abstract. Eliminate \ABSTRACT{} modifier for abstract members. Added static warning if abstract class has abstract member.
\ref{instanceVariables}: Instance variables can be initialized to non-constants. Moved discussion of implicit getters and setters to \ref{variables}.
\ref{generativeConstructors}: Clarify that finals can only be set once.
\ref{redirectingFactoryConstructors}: Added redirecting factories.
\ref{staticVariables}: Moved discussion of implicit getters and setters to \ref{variables}.
\ref{interfaces}: Eliminated interface declarations.
\ref{metadata}: Added metadata.
\ref{constants}: Refined definition constant identity/caching.
\ref{throw}: Stack traces moved to \ref{try}.
\ref{new}: Creating an instance via \NEW{} using an undefined class or constructor is a dynamic error and a static warning, not a compile-time error. Evaluation rules to allow instance variables with non-constant initializers. Instantiating an abstract class via a generative constructor is now a dynamic error.
\ref{equality}: Replaced \code{===} with built-in function \code{identical()}. Equality does not special case identity.
\ref{identifierReference}: Type names have meaning as expressions. \ASSERT{} is not a built-in identifier anymore, but \EXPORT{}, \IMPORT{}, \LIBRARY{} and \PART{} are. Removed warning on use of built-in identifiers as variable/function names.
\ref{typeCast}: type cast accepts \NULL{}.
\ref{argumentDefinitionTest}: Added operation to determine if optional argument was actually passed.
\ref{localFunctionDeclaration}: Added section on local functions.
\ref{switch}: Allow switch on compile-time constants of any one type.
\ref{try}: Revised syntax for \CATCH{} clauses. Specification of stack traces moved from \ref{throw}.
\ref{return}: Made explicit that checked mode tests returns.
\ref{assert}: \ASSERT{} is now a reserved word.
\ref{librariesAndScripts}: Revised library syntax and semantics.
\ref{typeDynamic}: Renamed {\bf Dynamic} to \DYNAMIC{}.
\ref{reservedWords}: \ASSERT{} is a reserved word.
\subsubsection{Changes Since Version 0.11}
\ref{notation}: Moved discussion of tokenization to section \ref{reference}.
\ref{numbers}: Removed unary plus.
\ref{librariesAndScripts}: Refined definition of show and hide to handle getters and setters in pairs.
\ref{functionTypes}: All function types are subtypes of \code{Function}.
\ref{reference}: Added discussion of tokenization.
\ref{reservedWords}: Defined meaning of reserved word.
\ref{comments}: Added initial discussion of dartdoc comments.
\subsubsection{Changes Since Version 0.12}
\ref{classes}: Removed \ABSTRACT{} modifier from grammar of members. Added grammar for \WITH{} clause.
\ref{superclasses}: Added discussion of new \WITH{} clause for mixins.
\ref{mixins}: Added specification of mixins.
\ref{constants}: Revised description of \code{identical()} so that it always returns \TRUE{} on numbers with the same class and value.
\ref{null}: Invocations on \NULL{} throw \code{NoSuchMethodError} only.
\ref{throw}: \THROW{} of \NULL{} raises \code{NullThrownError}.
\ref{instanceCreation} Using undefined types as type arguments to a constructor is a dynamic failure.
\ref{librariesAndScripts}: Added discussion of compilation units. Allow name clause to be optional for libraries, allow export clauses in scripts. Support fully qualified name for libraries. Allow different imports to share same prefix. Added mixin application as a top level declaration.
\ref{typedef}: Typedefs for mixin applications added.
\ref{interfaceTypes}: Add effects of mixin clause on subtyping.
\ref{leastUpperBounds}: Corrected definition of LUBs.
\ref{reservedWords}: Added keyword \WITH{}.
\subsubsection{Changes Since Version 0.20}
\ref{getters}: Getters cannot return \VOID{}.
\ref{superinterfaces}: Added requirement that superclass cannot appear in \IMPLEMENTS{} clause.
\ref{interfaceInheritanceAndOverriding}: Clarified status of getter/setter vs. method conflicts in multiple interface inheritance.
\ref{throw}: Separated \THROW{} into \code{\THROW{} e} and \code{\RETHROW{}}.
\ref{new}: Arguments to constructor are evaluated before allocating new object.
\ref{unqualifiedInvocation}: Calling an undeclared method in a static context is a dynamic error (and a static warning) not a compile-time one.
\ref{ordinaryInvocation}, \ref{superInvocation}, \ref{getterInvocation}, \ref{assignment}: Refined description of \code{InvocationMirror} instance passed to \code{noSuchMethod()}.
\ref{lexicalRules}: Abandoned requirement for Unicode Normalization Form C.
\subsubsection{Changes Since Version 0.30}
\ref{superclasses}, \ref{superinterfaces}: Clarified that super types with wrong number of type arguments cause a compilation error.
\subsubsection{Changes Since Version 0.31}
\ref{abstractInstanceMembers}: Abstract methods act as pure declarations.
\ref{mixins}: Mixin application has forwarding constructors for all superclass constructors.
\ref{instanceCreation}, \ref{new}: Revised so that wrong generic arity is a runtime error with static warning.
\ref{typeTest}, \ref{typeCast}: Eliminated special treatment of malformed types.
\ref{rethrow}: Rethrow is a statement, not an expression.
\ref{librariesAndScripts}: Semicolon required after top-level external declarations.
\ref{imports}: Removed requirement that library names be unique within an isolate.
\ref{dynamicTypeSystem}: Revised definition of malformed types. Revised behavior of checked and production modes wrt to malformed and malbounded types. Refined assignability rules wrt new function type subtyping.
\ref{interfaceTypes}: Corrected oversight wrt type variables and \cd{Object}.
\ref{functionTypes}: Liberalized function subtyping rules. Special assignability rules.
\ref{parameterizedTypes}: Out with misconstructed types, in with malbounded ones.
\subsubsection{Changes Since Version 0.40}
\ref{expressions}: Argument definition test construct dropped.
\ref{maps}: Map literals can be keyed by arbitrary expressions.
\ref{librariesAndScripts}: Implicitly named libraries are named `'. Script tags are allowed in all libraries. It is a warning to import or export two libraries with the same name.
\subsubsection{Changes Since Version 0.41}
\ref{variables}: Uninitialized final is now just a static warning.
\ref{typeOfAFunction}: Added details about the run time type of functions.
\ref{instanceVariables}: Disallowed const inst vars.
\ref{redirectingConstructors}: Uninitialized final is now just a static warning.
\ref{objectIdentity}, \ref{constants}: Clarified rules for double identity.
\ref{maps}: Adjusted rules for constant map literals.
\ref{propertyExtraction}: If the same method is extracted repeatedly from the same object, the results are equal. Furthermore, the type of the property extraction is based on the method being closurized. Also described handling of property extractions on \SUPER{} explicitly.
\ref{getterInvocation}: Explicitly described getter invocations on \SUPER{}.
\subsubsection{Changes Since Version 0.50}
% there was no public 0.50!
\ref{variables}: Final variables introduce setters that trap on execution. Not initializing a final is a warning, not an error. Initializing a final variable declared with an initializer is a warning, not an error.
\ref{requiredFormals}: Initializing formals can specify function types. These may not specify defaults.
\ref{instanceMethods}: Corrected override rules to fit with earlier relaxation of function subtype rules. Furthermore, bad overrides provoke warnings not errors. Also, methods and corresponding setters yield warnings.
\ref{generativeConstructors}: Initializing a final variable declared with an initializer is a warning, not an error.
\ref{staticMethods}: Corresponding setters yield warnings.
\ref{inheritanceAndOverriding}: Refined definitions of inheritance and overriding to correctly account for library privacy.
\ref{superinterfaces}: Suppress type warnings for unimplemented members of superinterfaces if the class declares \code{noSuchMethod()}.
\ref{interfaceInheritanceAndOverriding}: Refined definitions of inheritance and overriding to correctly account for library privacy.
\ref{constants}: Literal symbols are constants.
\ref{numbers}, \ref{booleans}, \ref{strings}: Specified the runtime type of numbers, booleans and strings.
\ref{strings}: Implicit concatenation works among all kinds of strings.
\ref{symbols}: Added literal symbols.
\ref{if}, \ref{for}, \ref{while}, \ref{do}: Single statements in control constructs implicitly introduce a block.
\ref{imports}: Introduced special treatment for imports conflicts with \code{dart:core}. Ambiguous names are treated as malformed types or \code{NoSuchMethodError}s.
\ref{typedef}: Tightened restrictions on recursive typedefs.
%\ref{typeDynamic}: Clarified that \DYNAMIC{} is not an expression.
\subsubsection{Changes Since Version 0.51}
\ref{classes}: Mixin applications are a kind of class definition.
\ref{generativeConstructors}: Clarify that executing repeated initialization of a final variable by an initializer or initializing formal is a run-time error.
\ref{mixins}: Mixin applications are defined using \CLASS{} rather than \TYPEDEF{}.
\ref{objectIdentity}: Refined definition of \code{identical()}.
\ref{propertyExtraction}: Abstract methods are ignored for purposes of property extraction.
\ref{bindingActualsToFormals}: Mismatched arguments lead to \cd{NoSuchMethodError}.
\ref{ordinaryInvocation}, \ref{superInvocation}: Correctly account for calls to \cd{noSuchMethod} due to mismatched arguments.
\ref{imports}, \ref{exports}: Provenance of declarations allowed to disambiguate imports and exports.
\ref{typedef}: Mixin applications are no longer defined via a \TYPEDEF{}.
\ref{functionTypes}: All functions must implement \CALL{}.
\ref{comments}: Doc comments details are unspecified.
\subsubsection{Changes Since Version 0.6}
\ref{variables}: Type promotion support added.
\ref{formalParameters}: refined scope rules.
\ref{classes}: Banned name clashes between type variables and members etc.
\ref{factories}: Banned default values in redirecting factories.
\ref{constants}: Added constant conditional expressions.
\ref{strings}: Allow adjacent single and multiline strings to concatenate. Allow escaped newlines in multiline strings.
\ref{const}: Allow parameterized types in const instance creation.
\ref{conditional}: Type promotion support added.
\ref{logicalBooleanExpressions}: Type promotion support added.
\ref{logicalBooleanExpressions} - \ref{bitwiseExpressions}, \ref{operatorPrecedence}: Increased precedence of bitwise operations to be higher than equality and relational expressions.
\ref{identifierReference}: Clarified static type rules. Type promotion support added.
\ref{typeTest}: Type promotion support added.
\ref{if}: Type promotion support added.
\ref{try}: \ON{} with no \CATCH{} implies \DYNAMIC{}, not \cd{Object}.
\ref{return}: Added warning if \RETURN{} without expression mixed with \RETURN{} with an expression.
\ref{exports}: Ensure that exports treat \code{dart:} libs specially, like imports do.
\ref{typePromotion}: Added notion of type promotion.
\ref{typedef}: Banned all recursion in typedefs.
\subsubsection{Changes Since Version 0.7}
\ref{new}: Instantiating subclasses of malbounded types is a dynamic error.
\ref{leastUpperBounds}: Extended LUBs to all types.
\section{Notation}
\label{notation}
We distinguish between normative and non-normative text. Normative text defines the rules of Dart. It is given in this font. At this time, non-normative text includes:
\begin{itemize}
\item[Rationale] Discussion of the motivation for language design decisions appears in italics. \rationale{Distinguishing normative from non-normative helps clarify what part of the text is binding and what part is merely expository.}
\item[Commentary] Comments such as ``\commentary{The careful reader will have noticed that the name Dart has four characters}'' serve to illustrate or clarify the specification, but are redundant with the normative text. \commentary{The difference between commentary and rationale can be subtle.} \rationale{ Commentary is more general than rationale, and may include illustrative examples or clarifications. }
\item[Open questions] (\Q{in this font}). Open questions are points that are unsettled in the mind of the author(s) of the specification; expect them (the questions, not the authors; precision is important in a specification) to be eliminated in the final specification. \Q{Should the text at the end of the previous bullet be rationale or commentary?}
\end{itemize}
Reserved words and built-in identifiers (\ref{identifierReference}) appear in {\bf bold}.
\commentary{
Examples would be \SWITCH{} or \CLASS{}.
}
Grammar productions are given in a common variant of EBNF. The left hand side of a production ends with a colon. On the right hand side, alternation is represented by vertical bars, and sequencing by spacing. As in PEGs, alternation gives priority to the left. Optional elements of a production are suffixed by a question mark like so: \code{anElephant?}. Appending a star to an element of a production means it may be repeated zero or more times. Appending a plus sign to a production means it occurs one or more times. Parentheses are used for grouping. Negation is represented by prefixing an element of a production with a tilde. Negation is similar to the not combinator of PEGs, but it consumes input if it matches. In the context of a lexical production it consumes a single character if there is one; otherwise, a single token if there is one.
\commentary{ An example would be:}
\begin{grammar}
{\sf
{\bf AProduction:}AnAlternative;
AnotherAlternative;
OneThing After Another;
ZeroOrMoreThings*;
OneOrMoreThings+;
AnOptionalThing?;
(Some Grouped Things);
\~{}NotAThing;
A\_LEXICAL\_THING
.
}
\end{grammar}
% need a match anything or a production that does that, so we can correct bugs wrt use
% ~. ~ does not actually parse stuff - it just looks ahead and checks. To get the effect of
% parsing anything but X, one needs ~X ANYTHING, not just ~X. There are bugs in the
% grammar related to this.
% The alternative is to define ~X as anything but X, or to introduce an anthingBut(X)
% combinator, such as !X
Both syntactic and lexical productions are represented this way. Lexical productions are distinguished by their names. The names of lexical productions consist exclusively of upper case characters and underscores. As always, within grammatical productions, whitespace and comments between elements of the production are implicitly ignored unless stated otherwise.
Punctuation tokens appear in quotes.
Productions are embedded, as much as possible, in the discussion of the constructs they represent.
A list $x_1, \ldots, x_n$ denotes any list of $n$ elements of the form $x_i, 1 \le i \le n$. Note that $n$ may be zero, in which case the list is empty. We use such lists extensively throughout this specification.
The notation $[x_1, \ldots, x_n/y_1, \ldots, y_n]E$ denotes a copy of $E$ in which all occurrences of $y_i, 1 \le i \le n$ have been replaced with $x_i$.
We sometimes abuse list or map literal syntax, writing $[o_1, \ldots, o_n]$ (respectively $\{k_1: o_1, \ldots, k_n: o_n\}$) where the $o_i$ and $k_i$ may be objects rather than expressions. The intent is to denote a list (respectively map) object whose elements are the $o_i$ (respectively, whose keys are the $k_i$ and values are the $o_i$).
The specifications of operators often involve statements such as $x$ $op$ $y$ is equivalent to the method invocation $x.op(y)$. Such specifications should be understood as a shorthand for:
\begin{itemize}
\item
$x$ $op$ $y$ is equivalent to the method invocation $x.op^\prime(y)$, assuming the class of $x$ actually declared a non-operator method named $op^\prime$ defining the same function as the operator $op$.
\end{itemize}
\rationale{This circumlocution is required because x.op(y), where op is an operator, is not legal syntax. However, it is painfully verbose, and we prefer to state this rule once here, and use a concise and clear notation across the specification.
}
When the specification refers to the order given in the program, it means the order of the program source code text, scanning left-to-right and top-to-bottom.
References to otherwise unspecified names of program entities (such as classes or functions) are interpreted as the names of members of the Dart core library.
\commentary{
Examples would be the classes \code{Object} and \code{Type} representing the root of the class hierarchy and the reification of runtime types respectively.
}
\section{Overview}
\label{overview}
Dart is a class-based, single-inheritance, pure object-oriented programming language. Dart is optionally typed (\ref{types}) and supports reified generics. The run-time type of every object is represented as an instance of class \code{Type} which can be obtained by calling the getter \code{runtimeType} declared in class \code{Object}, the root of the Dart class hierarchy.
Dart programs may be statically checked. The static checker will report some violations of the type rules, but such violations do not abort compilation or preclude execution.
Dart programs may be executed in one of two modes: production mode or checked mode. In production mode, static type annotations (\ref{staticTypes}) have absolutely no effect on execution with the exception of reflection and structural type tests.
\commentary{
Reflection, by definition, examines the program structure. If we provide reflective access to the type of a declaration, or to source code, it will inevitably produce results that depend on the types used in the underlying code.
Type tests also examine the types in a program explicitly. Nevertheless, in most cases, these will not depend on type annotations. The exceptions to this rule are type tests involving function types. Function types are structural, and so depend on the types declared for their parameters and on their return types.
}
In checked mode, assignments are dynamically checked, and certain violations of the type system raise exceptions at run time.
\commentary{
The coexistence between optional typing and reification is based on the following:
\begin{enumerate}
\item Reified type information reflects the types of objects at runtime and may always be queried by dynamic typechecking constructs (the analogs of instanceOf, casts, typecase etc. in other languages). Reified type information includes class declarations, the runtime type (aka class) of an object, and type arguments to constructors.
\item Static type annotations determine the types of variables and function declarations (including methods and constructors).
\item Production mode respects optional typing. Static type annotations do not affect runtime behavior.
\item Checked mode utilizes static type annotations and dynamic type information aggressively yet selectively to provide early error detection during development.
\end{enumerate}
}
Dart programs are organized in a modular fashion into units called {\em libraries} (\ref{librariesAndScripts}). Libraries are units of encapsulation and may be mutually recursive.
\commentary{However they are not first class. To get multiple copies of a library running simultaneously, one needs to spawn an isolate.
}
\subsection{Scoping}
\label{scoping}
A {\em namespace} is a mapping of identifiers to declarations. Let $NS$ be a namespace. We say that a name $n$ {\em is in }$NS$ if $n$ is a key of $NS$. We say a declaration $d$ {\em is in }$NS$ if a key of $NS$ maps to $d$.
A scope $S_0$ induces a namespace $NS_0$ that maps the simple name of each variable, type or function declaration $d$ declared in $S_0$ to $d$. Labels are not included in the induced namespace of a scope; instead they have their own dedicated namespace.
\commentary{It is therefore impossible, e.g., to define a class that declares a method and a field with the same name in Dart. Similarly one cannot declare a top-level function with the same name as a library variable or class.
}
It is a compile-time error if there is more than one entity with the same name declared in the same scope.
\commentary{
In some cases, the name of the declaration differs from the identifier used to declare it. Setters have names that are distinct from the corresponding getters because they always have an = automatically added at the end, and unary minus has the special name unary-.
}
Dart is lexically scoped. Scopes may nest. A name or declaration $d$ is {\em available in scope} $S$ if $d$ is in the namespace induced by $S$ or if $d$ is available in the lexically enclosing scope of $S$. We say that a name or declaration $d$ is {\em in scope} if $d$ is available in the current scope.
If a declaration $d$ named $n$ is in the namespace induced by a scope $S$, then $d$ {\em hides} any declaration named $n$ that is available in the lexically enclosing scope of $S$.
Names may be introduced into a scope by declarations within the scope or by other mechanisms such as imports or inheritance.
\rationale{
The interaction of lexical scoping and inheritance is a subtle one. Ultimately, the question is whether lexical scoping takes precedence over inheritance or vice versa. Dart chooses the former.
Allowing inherited names to take precedence over locally declared names can create unexpected situations as code evolves. Specifically, the behavior of code in a subclass can change without warning if a new name is introduced in a superclass. Consider:
}
\begin{dartCode}
\LIBRARY{} L1;
\CLASS{} S \{\}
\LIBRARY{} L2;
\IMPORT{} `L1.dart';
foo() =$>$ 42;
\CLASS{} C \EXTENDS{} S\{ bar() =$>$ foo();\}
\end{dartCode}
\rationale{Now assume a method \code{foo()} is added to \code{S}. }
\begin{dartCode}
\LIBRARY{} L1;
\CLASS{} S \{foo() =$>$ 91;\}
\end{dartCode}
\rationale{
If inheritance took precedence over the lexical scope, the behavior of \code{C} would change in an unexpected way. Neither the author of \code{S} nor the author of \code{C} are necessarily aware of this. In Dart, if there is a lexically visible method \code{foo()}, it will always be called.
Now consider the opposite scenario. We start with a version of \code{S} that contains \code{foo()}, but do not declare \code{foo()} in library \code{L2}. Again, there is a change in behavior - but the author of \code{L2} is the one who introduced the discrepancy that effects their code, and the new code is lexically visible. Both these factors make it more likely that the problem will be detected.
These considerations become even more important if one introduces constructs such as nested classes, which might be considered in future versions of the language.
Good tooling should of course endeavor to inform programmers of such situations (discretely). For example, an identifier that is both inherited and lexically visible could be highlighted (via underlining or colorization). Better yet, tight integration of source control with language aware tools would detect such changes when they occur.
}
\subsection{Privacy}
\label{privacy}
Dart supports two levels of privacy: {\em public} and {\em private}. A declaration is {\em private} iff its name begins with an underscore (the \_ character) otherwise it is {\em public.}
A declaration $m$ is {\em accessible to library $L$} if $m$ is declared in $L$ or if $m$ is public.
\commentary{
This means private declarations may only be accessed within the library in which they are declared.
}
Privacy applies only to declarations within a library, not to library declarations themselves.
\rationale{
Libraries do not reference each other by name and so the idea of a private library is meaningless.
Thus, if the name of a library begins with an underscore, it has no special significance.
}
\rationale{Privacy is, at this point, a static notion tied to a particular piece of code (a library). It is designed to support software engineering concerns rather than security concerns. Untrusted code should always run in an another isolate. It is possible that libraries will become first class objects and privacy will be a dynamic notion tied to a library instance.
Privacy is indicated by the name of a declaration - hence privacy and naming are not orthogonal. This has the advantage that both humans and machines can recognize access to private declarations at the point of use without knowledge of the context from which the declaration is derived.}
\subsection{Concurrency}
Dart code is always single threaded. There is no shared-state concurrency in Dart. Concurrency is supported via actor-like entities called {\em isolates}.
An isolate is a unit of concurrency. It has its own memory and its own thread of control. Isolates communicate by message passing (\ref{sendingMessages}). No state is ever shared between isolates. Isolates are created by spawning (\ref{spawningAnIsolate}).
\section{Errors and Warnings}
\label{errorsAndWarnings}
This specification distinguishes between several kinds of errors.
{\em Compile-time errors} are errors that preclude execution. A compile-time error must be reported by a Dart compiler before the erroneous code is executed.
\rationale{A Dart implementation has considerable freedom as to when compilation takes place. Modern programming language implementations often interleave compilation and execution, so that compilation of a method may be delayed, e.g., until it is first invoked. Consequently, compile-time errors in a method $m$ may be reported as late as the time of $m$'s first invocation.
As a web language, Dart is often loaded directly from source, with no intermediate binary representation. In the interests of rapid loading, Dart implementations may choose to avoid full parsing of method bodies, for example. This can be done by tokenizing the input and checking for balanced curly braces on method body entry. In such an implementation, even syntax errors will be detected only when the method needs to be executed, at which time it will be compiled (JITed).
In a development environment a compiler should of course report compilation errors eagerly so as to best serve the programmer.
}
If an uncaught compile-time error occurs within the code of a running isolate $A$, $A$ is immediately suspended. The only circumstance where a compile-time error could be caught would be via code run reflectively, where the mirror system can catch it.
\rationale{Typically, once a compile-time error is thrown and $A$ is suspended, $A$ will then be terminated. However, this depends on the overall environment.
A Dart engine runs in the context of an {\em embedder},
a program that interfaces between the engine and the surrounding computing environment. The embedder will often be a web browser, but need not be; it may be a C++ program on the server for example. When an isolate fails with a compile-time error as described above, control returns to the embedder, along with an exception describing the problem. This is necessary so that the embedder can clean up resources etc. It is then the embedder's decision whether to terminate the isolate or not.
}
{\em Static warnings} are those errors reported by the static checker. They have no effect on execution. Many, but not all, static warnings relate to types, in which case they are known as {\em static type warnings.} Static warnings must be provided by Dart compilers used during development such as those incorporated in IDEs or otherwise intended to be used by developers for developing code. Compilers that are part of runtime execution environments such as virtual machines should not issue static warnings.
{\em Dynamic type errors} are type errors reported in checked mode.
{\em Run-time errors} are exceptions raised during execution. Whenever we say that an exception $ex$ is {\em raised} or {\em thrown}, we mean that a throw expression (\ref{throw}) of the form: \code{\THROW{} $ex$;} was implicitly evaluated or that a rethrow statement (\ref{rethrow}) of the form \code{\RETHROW} was executed. When we say that {\em a} $C$ {\em is thrown}, where $C$ is a class, we mean that an instance of class $C$ is thrown.
If an uncaught exception is thrown by a running isolate $A$, $A$ is immediately suspended.
\section{Variables}
\label{variables}
Variables are storage locations in memory.
\begin{grammar}
{\bf variableDeclaration:}
declaredIdentifier (`,' identifier)*
.
{\bf declaredIdentifier:}
metadata finalConstVarOrType identifier
.
{\bf finalConstVarOrType:}\FINAL{} type?;
\CONST{} type?;
varOrType
.
{\bf varOrType:}\VAR{};
type
.
{\bf initializedVariableDeclaration:}
declaredIdentifier (`=' expression)? (`,' initializedIdentifier)* % could do top level here
.
{\bf initializedIdentifier:}
identifier (`=' expression)? % could do top-level here
.
{\bf initializedIdentifierList:}
initializedIdentifier (`,' initializedIdentifier)*
.
\end{grammar}
A variable that has not been initialized has the initial value \NULL{} (\ref{null}).
A variable declared at the top-level of a library is referred to as either a {\em library variable} or simply a top-level variable.
A {\em static variable} is a variable that is not associated with a particular instance, but rather with an entire library or class. Static variables include library variables and class variables. Class variables are variables whose declaration is immediately nested inside a class declaration and includes the modifier \STATIC{}. A library variable is implicitly static. It is a compile-time error to preface a top-level variable declaration with the built-in identifier (\ref{identifierReference}) \STATIC{}.
Static variable declarations are initialized lazily. When a static variable $v$ is read, iff it has not yet been assigned, it is set to the result of evaluating its initializer. The precise rules are given in section \ref{evaluationOfImplicitVariableGetters}.
\rationale{The lazy semantics are given because we do not want a language where one tends to define expensive initialization computations, causing long application startup times. This is especially crucial for Dart, which must support the coding of client applications.
}
A {\em final variable} is a variable whose binding is fixed upon initialization; a final variable $v$ will always refer to the same object after $v$ has been initialized. The declaration of a final variable must include the modifier \FINAL{}.
It is a static warning if a final instance variable that has been initialized at its point of declaration is also initialized in a constructor.
% It is a static warning if a final instance variable that has been initialized by means of an initializing formal of a constructor is also initialized elsewhere in the same constructor.
It is a compile-time error if a local variable $v$ is final and $v$ is not initialized at its point of declaration.
\commentary{
A library or static variable is guaranteed to have an initializer at its declaration by the grammar.
Attempting to assign to a final variable anywhere except in its declaration or in a constructor header will cause a runtime error to be thrown as discussed below. The assignment will also give rise to a static warning. Any repeated assignment to a final variable will also lead to a runtime error.
Taken as a whole, the rules ensure that any attempt to execute multiple assignments to a final variable will yield static warnings and repeated assignments will fail dynamically.
}
A {\em constant variable} is a variable whose declaration includes the modifier \CONST{}. A constant variable is always implicitly final. A constant variable must be initialized to a compile-time constant (\ref{constants}) or a compile-time error occurs.
We say that a variable $v$ is {\em potentially mutated} in some scope $s$ if $v$ is not final or constant and an assignment to $v$ occurs in $s$.
If a variable declaration does not explicitly specify a type, the type of the declared variable(s) is \DYNAMIC{}, the unknown type (\ref{typeDynamic}).
Static and instance variable declarations always induce implicit getters and setters.
The scope into which the implicit getters and setters are introduced depends on the kind of variable declaration involved.
A library variable introduces a getter and a setter into the top level scope of the enclosing library. A static class variable introduces a static getter and a static setter into the immediately enclosing class. An instance variable introduces an instance getter and an instance setter into the immediately enclosing class.
Local variables are added to the innermost enclosing scope. They do not induce getters and setters. A local variable may only be referenced at a source code location that is after its initializer, if any, is complete, or a a compile-time error occurs.
\commentary{
The example below illustrates the expected behavior. A variable $x$ is declared at the library level, and another $x$ is declared inside the function $f$.
}
\begin{dartCode}
\VAR{} x = 0;
f(y) \{
\VAR{} z = x; // compile-time error
if (y) \{
x = x + 1; // two compile time errors
print(x); // compile time error
\}
\VAR{} x = x++; // compile time error
print(x);
\}
\end{dartCode}
\commentary{
The declaration inside $f$ hides the enclosing one. So all references to $x$ inside $f$ refer to the inner declaration of $x$. However, many of these references are illegal, because they appear before the declaration. The assignment to $z$ is one such case. The assignment to $x$ in the \IF{} statement suffers from multiple problems. The right hand side reads $x$ before its declaration, and the left hand side assigns to $x$ before its declaration. Each of these are, independently, compile time errors. The print statement inside the \IF{} is also illegal.
The inner declaration of $x$ is itself erroneous because its right hand side attempts to read $x$ before the declaration has terminated. The left hand side is not, technically, a reference or an assignment but a declaration and so is legal. The last print statement is perfectly legal as well.
}
\commentary {
As another example \code{var x = 3, y = x;} is legal, because \code{x} is referenced after its initializer.
}
% the grammar does not support local getters and setters. The local var discussion does not seem to mention getters and setters based semantics. It simply discusses the creation of the variable, not its access. Access is either assignment or identifiers. Identifiers ignore the getter story.
The following rules apply to all static and instance variables.
A variable declaration of one of the forms \code{$T$ $v$;}, \code{$T$ $v$ = $e$;} , \code{\CONST{} $T$ $v$ = $e$;}, \code{\FINAL{} $T$ $v$;} or \code{\FINAL{} $T$ $v$ = $e$;} always induces an implicit getter function (\ref{getters}) with signature
$T$ \GET{} $v$
whose invocation evaluates as described below (\ref{evaluationOfImplicitVariableGetters}).
A variable declaration of one of the forms \code{\VAR{} $v$;}, \code{\VAR{} $v$ = $e$;} , \code{\CONST{} $v$ = $e$;}, \code{\FINAL{} $v$;} or \code{\FINAL{} $v$ = $e$;} always induces an implicit getter function with signature
\GET{} $v$
whose invocation evaluates as described below (\ref{evaluationOfImplicitVariableGetters}).
A non-final variable declaration of the form \code{{} $T$ $v$;} or the form \code{$T$ $v$ = $e$;} always induces an implicit setter function (\ref{setters}) with signature
\VOID{} \SET{} $v=(T$ $x)$
whose execution sets the value of $v$ to the incoming argument $x$.
A non-final variable declaration of the form \code{\VAR{} $v$;} or the form \code{\VAR{} $v$ = $e$;} always induces an implicit setter function with signature
\SET{} $v=(x)$
whose execution sets the value of $v$ to the incoming argument $x$.
% A final variable introduces a setter that throws and causes a type warning
A final or constant variable declaration of the form \code{\FINAL{} $T$ $v$;}, \code{\FINAL{} $T$ $v$ = $e$;} or the form \code{\CONST{} $T$ $v$ = $e$;} always induces an implicit setter function (\ref{setters}) with signature
\VOID{} \SET{} $v=(T$ $x)$
whose execution causes a runtime exception. It is a static warning to invoke such a setter.
A final variable declaration of the form \code{\FINAL{} $v$;}, \code{\FINAL{} $v$ = $e$;} or the form \code{\CONST{} $v$ = $e$;} always induces an implicit setter function with signature
\SET{} $v=(x)$
whose execution causes a runtime exception. It is a static warning to invoke such a setter. % maybe redundant with rules for assignment?
\rationale{
Creating a setter that may not be used may seem pointless, but it prevents situations where a setter from an enclosing scope might be accidentally accessed from a scope that defines an immutable variable.
}
\subsection{Evaluation of Implicit Variable Getters}
\label{evaluationOfImplicitVariableGetters}
Let $d$ be the declaration of a static or instance variable $v$. If $d$ is an instance variable, then the invocation of the implicit getter of $v$ evaluates to the value stored in $v$.
If $d$ is a static or library variable then the implicit getter method of $v$ executes as follows:
\begin{itemize}
\item {\bf Non-constant variable declaration with initializer}. If $d$ is of one of the forms \code{\VAR{} $v$ = $e$;} , \code{$T$ $v$ = $e$;} , \code{\FINAL{} $v$ = $e$;} , \code{\FINAL{} $T$ $v$ = $e$;}, \code{\STATIC{} $v$ = $e$; }, \code{\STATIC{} $T$ $v$ = $e$; }, \code{\STATIC{} \FINAL{} $v$ = $e$; } or \code{\STATIC{} \FINAL{} $T$ $v$ = $e$;} and no value has yet been stored into $v$ then the initializer expression $e$ is evaluated. If, during the evaluation of $e$, the getter for $v$ is invoked, a \code{CyclicInitializationError} is thrown. If the evaluation succeeded yielding an object $o$, let $r = o$, otherwise let $r = \NULL{}$. In any case, $r$ is stored into $v$. The result of executing the getter is $r$.
\item {\bf Constant variable declaration}. If $d$ is of one of the forms \code{\CONST{} $v$ = $e$; } , \code{\CONST{} $T$ $v$ = $e$; }, \code{\STATIC{} \CONST{} $v$ = $e$; } or \code{\STATIC{} \CONST{} $T$ $v$ = $e$;} the result of the getter is the value of the compile time constant $e$. \commentary{Note that a compile time constant cannot depend on itself, so no cyclic references can occur.}
Otherwise
\item {\bf Variable declaration without initializer}. The result of executing the getter method is the value stored in $v$.
\end{itemize}
\section{Functions}
\label{functions}
Functions abstract over executable actions.
\begin{grammar}
{\bf functionSignature:}
metadata returnType? identifier formalParameterList
.
{\bf returnType:}
\VOID{};
type
.
{\bf functionBody:}`={\escapegrammar \gt}' expression `{\escapegrammar ;}';
block
.
{\bf block:}
`\{' statements `\}'
.
\end{grammar}
Functions include function declarations (\ref{functionDeclarations}), methods (\ref{instanceMethods}, \ref{staticMethods}), getters (\ref{getters}), setters (\ref{setters}), constructors (\ref{constructors}) and function literals (\ref{functionExpressions}).
All functions have a signature and a body. The signature describes the formal parameters of the function, and possibly its name and return type. A function body is either:
\begin{itemize}
\item A block statement (\ref{blocks}) containing the statements (\ref{statements}) executed by the function. In this case, if the last statement of a function is not a return statement, the statement \code{\RETURN{};} is implicitly appended to the function body.
\rationale{
Because Dart is optionally typed, we cannot guarantee that a function that does not return a value will not be used in the context of an expression. Therefore, every function must return a value. A \RETURN{} without an expression returns \NULL{}. See further discussion in section \ref{return}.
}
OR
\item of the form \code{=$>$ $e$} which is equivalent to a body of the form \code{\{\RETURN{} $e$;\}}.
\end{itemize}
% A function has a formal parameter scope and a body scope. The enclosing scope of a function's body scope is its formal parameter scope. The enclosing scope of the formal parameter scope of a function is the enclosing scope of the function.
% The body of a function $f$ is processed within the body scope of $f$.
%\rationale{This may seem obvious, but needs to be stated.}
% \commentary{It follows from the above rules that the formal parameters of a function may be referenced within its body. }
\subsection{Function Declarations}
\label{functionDeclarations}
A {\em function declaration} is a function that is neither a member of a class nor a function literal. Function declarations include {\em library functions}, which are function declarations
%(including getters and setters)
at the top level of a library, and {\em local functions}, which are function declarations declared inside other functions. Library functions are often referred to simply as top-level functions.
A function declaration consists of an identifier indicating the function's name, possibly prefaced by a return type. The function name is followed by a signature and body. For getters, the signature is empty. The body is empty for functions that are external.
The scope of a library function is the scope of the enclosing library. The scope of a local function is described in section \ref{localFunctionDeclaration}. In both cases, the name of the function is in scope in its formal parameter scope (\ref{formalParameters}).
%A function declaration of the form $T_0$ $id(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{s\}$ is equivalent to a variable declaration of the form \code{\FINAL{} $F$ $id$ = $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k}= d_k])\{s\}$}, where $F$ is the function type alias (\ref{typedef}) \code{\TYPEDEF{} $T_0$ $F(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}])$}. Likewise, a function declaration of the form $id(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{s\}$ is equivalent to a variable declaration of the form \code{\FINAL{} $F$ $id$ = $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{s\}$}, where $F$ is the function type alias \code{\TYPEDEF{} $F(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}])$}.
%\Q{We need to cover library getters as well.}
%\Q{ The definition in terms of variables is untrue, because the code would be illegal. The initializer cannot refer to the function name in this case. I believe the best fix is to relax this
%requirement in the case of closures. See bug 315.
%}
%\commentary{
%Some obvious conclusions:
%A function declaration of the form $id(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k]) => e$ is equivalent to a variable declaration of the form \code{\FINAL{} $id$ = ($(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])=> e$}.
%A function literal of the form $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k]) => e$ is equivalent to a function literal of the form \code{$(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{$ \RETURN{} $e$;\}}.
%}
%A function declaration of the form $T_0$ $id(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\})\{s\}$ is equivalent to a variable declaration of the form \code{\FINAL{} $F$ $id$ = $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\})\{s\}$}, where $F$ is the function type alias (\ref{typedef}) \code{\TYPEDEF{} $T_0$ $F(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]\}$}. Likewise, a function declaration of the form $id(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\})\{s\}$ is equivalent to a variable declaration of the form \code{\FINAL{} $F$ $id$ = $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\})\{s\}$}, where $F$ is the function type alias \code{\TYPEDEF{} $F(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\})$}.
It is a compile-time error to preface a function declaration with the built-in identifier \STATIC{}.
\subsection{Formal Parameters}
\label{formalParameters}
Every function includes a {\em formal parameter list}, which consists of a list of required positional parameters (\ref{requiredFormals}), followed by any optional parameters (\ref{optionalFormals}). The optional parameters may be specified either as a set of named parameters or as a list of positional parameters, but not both.
The formal parameter list of a function introduces a new scope known as the function`s {\em formal parameter scope}. The formal parameter scope of a function $f$ is enclosed in the scope where $f$ is declared. Every formal parameter introduces a local variable into the formal parameter scope. However, the scope of a function's signature is the function's enclosing scope, not the formal parameter scope.
The body of a function introduces a new scope known as the function`s {\em body scope}. The body scope of a function $f$ is enclosed in the scope introduced by the formal parameter scope of $f$.