@@ -2,12 +2,26 @@ NOTE: This is work in progress
2
2
3
3
# const functions and methods for Dart
4
4
5
- ## Definition
5
+ ## Goal
6
6
7
- A ` const ` function/method (CFM) is a function/method whose result can be used as
8
- a fragment of a ` const ` expression.
7
+ Introduce syntax for ` const ` function/method (CFM). CFM is:
9
8
10
- ## Declaration syntax
9
+ * a function/method whose result can be used as a fragment of a ` const `
10
+ expression.
11
+
12
+ ## Non-goals
13
+
14
+ This proposal is simply syntactic sugar on top of the existing ` const `
15
+ expressions. The proposed expressions can be syntactically and lexically
16
+ transformed to the existing syntax that is accepted by current Dart
17
+ implementations. Anything that requires more than static transformation
18
+ is beyond the scope of this proposal. For example, this proposal does
19
+ not include:
20
+
21
+ * control flow in ` const ` expressions
22
+ * lazy evaluation
23
+
24
+ ## Syntax
11
25
12
26
A CFM is declared like a normal function/method and:
13
27
@@ -21,13 +35,100 @@ imposed on the _const constructors_.
21
35
22
36
Because CFMs are also normal functions they may be used in non-` const `
23
37
expressions. In ` const ` expressions, however, the following restrictions are
24
- imposed:
38
+ imposed (both means applied to both functions and methods) :
25
39
26
40
* (both) their arguments must be ` const ` expressions
27
- * (methods only) they may only be called on a ` const ` value
41
+ * (both) must be preceded by ` const ` (see also
42
+ [ optional const proposal] ( https://github.com/lrhn/dep-const/blob/master/proposal.md ) )
43
+ * (methods only) they may only be called on a ` const ` value (and therefore may
44
+ only be defined on classes with ` const ` constructors)
45
+
46
+ ## Motivating examples
47
+
48
+ Here's a very simplified
49
+ "[ fluent] ( http://en.wikipedia.org/wiki/Fluent_interface ) "
50
+ binding API for Angular 2 dependency injection:
51
+
52
+ ``` dart
53
+ class Binding {
54
+ final Type type;
55
+ final dynamic value;
56
+
57
+ const Binding(this.type, this.value);
58
+ }
59
+
60
+ class BindingBuilder {
61
+ final Type type;
62
+
63
+ /// Note that class declaring `const` method is itself `const`.
64
+ const BindingBuilder(this.type);
65
+
66
+ /// A const method.
67
+ ///
68
+ /// Body of a `const` method is a `const` expression.
69
+ const toValue(value) => const Binding(
70
+ this.type, // ok to refer to `this` as `this` is itself const
71
+ value // parameters are enforced to be `const` so can also be used
72
+ );
73
+ }
74
+
75
+ /// A const function.
76
+ ///
77
+ /// Body of a `const` function is a `const` expression.
78
+ const bind(Type t) => const BindingBuilder(t);
79
+
80
+ void main() {
81
+ const binding = const bind(String).toValue('hello, world!');
82
+ }
83
+
84
+ // In Angular 2 apps, this fluent syntax may be used to declare bindings in
85
+ // component annotations, e.g.:
86
+ @Component(
87
+ injector: const [
88
+ const bind(String).toValue('hello, world!')
89
+ ]
90
+ )
91
+ class MyComponent {
92
+ }
93
+ ```
28
94
29
95
## Semantics
30
96
31
97
A call to a ` const ` function in a ` const ` expression is semantically equivalent
32
98
to inlining the function into the expression.
33
- ==================================== 80 ========================================
99
+
100
+ ### Example
101
+
102
+ ``` dart
103
+ // the example expression from above:
104
+ const bind(String).toValue('hello, world!');
105
+
106
+ // is unwrapped by inlining functions and methods:
107
+
108
+ // Step 1: inline `bind`
109
+ const BindingBuilder(String).toValue('hello, world!');
110
+
111
+ // Step 2: inline `toValue`
112
+ const Binding(String, 'hello, world!');
113
+ ```
114
+
115
+ Note that the final unwrapped version of the expression is compiant with the
116
+ existing language spec.
117
+
118
+ ## Optional const
119
+
120
+ With optional ` const ` proposed
121
+ [ here] ( https://github.com/lrhn/dep-const/blob/master/proposal.md )
122
+ the syntax could be improved further:
123
+
124
+ ``` dart
125
+ @Component(
126
+ injector: [
127
+ bind(String).toValue('hello, world!')
128
+ ]
129
+ )
130
+ class MyComponent {
131
+ }
132
+ ```
133
+
134
+ <!-- - ============================ 80 chars ================================ -->
0 commit comments