Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: GENERIC_METHODS.md

Issue 1586803002: Add file documenting generic method prototype syntax (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Strong mode generic method prototype syntax
2
3 This is a summary of the current (as of January 2016) supported comment-based
4 generic method syntax supported by the analyzer strong mode and the Dart Dev
5 Compiler. The comment-based syntax essentially uses the proposed actual generic
6 method syntax, but wraps it in comments.
vsm 2016/01/13 22:01:29 Probably worth a line here that this allows devs t
Leaf 2016/01/13 22:28:39 Done.
7
8 ## Declaring generic method parameters
9
10 Generic method parameters are listed after the method or function name, inside
11 of angle brackets and comments.
12
13 ```dart
14 // This declares a function which takes two unused generic method parameters
15 int f/*<S, T>*/(int x) => 3;
16 ```
17
18 As with classes, you can put bounds on type parameters.
19
20 ```dart
21 // This declares a function which takes two unused generic method parameters
22 // The first parameter (S) must extend num
23 // The second parameter (T) must extend List<S>
24 int f/*<S extends num, T extends List<S>>*/(int x) => 3;
25 ```
26
27 Class methods (instance and static) can be declared to take generic parameters
28 in the same way.
29
30 ```dart
31 class C {
32 static int f/*<S, T>*/(int x) => 3;
33 int m/*<S, T>*/(int x) => 3;
34 }
35 ```
36
37 Function typed parameters, local functions, and function expressions can also be
38 declared to take generic parameters.
39
40 ```dart
41 // foo takes a generic method as a parameter
42 void foo(int f/*<S>*/(int x)) {}
43
44 // foo declares a local generic function
45 void foo() {
46 int f/*<S>*/(int x) => 3;
47 return;
48 }
49
50 // foo binds a generic function expression to a local variable.
51 void foo() {
52 var x = /*<S>*/(int x) => x;
53 }
54 ```
55
56 We do not currently support a way to declare a function as returning a generic
57 function. This will eventually be supported using something analogous to Dart
58 typedefs.
59
60 ## Using generic method parameters
61
62 The previous examples declared generic method parameters, but did not use them.
63 You can use a generic method parameter `T` anywhere that a type is expected in
64 Dart by writing a type followed by `/*=T*/`. So for example, `dynamic /*=T*/`
65 will be interpreted as `dynamic` by all non-strong mode tools, but will be
66 interpreted as `T` by strong mode. In places where it is valid to leave off a
67 type, simply writing `/*=T*/` will be interpreted as `dynamic` by non-strong
68 mode tools, but will be interpreted as `T` by strong mode. For example:
69
70 ```dart
71 // foo is a generic method which takes a single generic method parameter S.
72 // In strong mode, the parameter x will have type S, and the return type will
73 // be S
74 // In normal mode, the parameter x will have type dynamic, and the return
75 // type will be S.
76 dynamic/*=S*/ foo/*<S>*/(dynamic/*=S*/ x) { return x; }
77 ```
78
79 This can be written more concisely by leaving off the `dynamic`.
80
81 ```dart
82 /*=S*/ foo/*<S>*/(/*=S*/ x) {return x;}
83 ```
84
85 Note that the generic parameter is in scope in the return type of the function,
86 in the argument list of the function, and in the body of the function. When
87 declaring local variables and parameters, you can also use the `/*=T*/` syntax w ith `var`.
88
89 ```dart
90 // foo is a generic method that takes a single generic parameter S, and a value
91 // x of type S
92 void foo/*<S>*/(var /*=S*/ x) {
93 // In strong mode, y will also have type S
94 var /*=S*/ y = x;
95
96 // In strong mode, z will also have type S
97 dynamic /*=S*/ z = y;
98 }
99 ```
100
101 Anywhere that a type literal is expected, you can also use the `/*=T*/` syntax t o
102 produce a type literal from the generic method parameter.
103
104 ```dart
105 void foo/*<S>*/(/*=S*/ x) {
106 // In strong mode, s will get the type literal for S
107 Type s = dynamic /*=S*/;
108
109 // In strong mode, this attempts to cast 3 as type S
110 var y = (3 as dynamic /*=S*/);
111 }
112 ```
113
114 ## Instantiating generic classes with generic method parameters
115
116 You can use generic method parameters to instantiate generic classes using the
117 same `/*=T*/` syntax.
118
119 ```dart
120 // foo is a generic method which returns a List<S> in strong mode,
121 // but which returns List<dynamic> in normal mode.
122 List<dynamic /*=S*/> foo/*<S>*/(/*=S*/ x) {
123 // l0 is a list literal whose reified type will be List<S> in strong mode,
124 // and List<dynamic> in normal mode.
125 var l0 = <dynamic /*=S*/>[x];
126
127 // as above, but with a regular constructor.
128 var l1 = new List<dynamic /*=S*/>();
129 return l1;
130 }
131 ```
132
133 In most cases, the entire type argument list to the generic class can be
134 enclosed in parentheses, eliminating the need for explicitly writing `dynamic`.
135
136 ```dart
137 // This is another way of writing the same code as above
138 List/*<S>*/ foo/*<S>*/(/*=S*/ x) {
139 // The shorthand syntax is not yet supported for list and map literals
140 var l0 = <dynamic /*=S*/>[x];
141
142 // but with regular constructors you can use it
143 var l1 = new List/*<S>*/();
144 return l1;
145 }
146 ```
147
148 ## Instantiating generic methods
149
150 Generic methods can be called without passing type arguments. Strong mode will
151 attempt to infer the type arguments automatically. If it is unable to do so,
152 then the type arguments will be filled in with whatever their declared bounds
153 are (by default, `dynamic`).
154
155 ```dart
156 class C {
157 /*=S*/ inferableFromArgument/*<S>*/(/*=S*/ x) { return null;}
158 /*=S*/ notInferable/*<S>*/(int x) { return null;}
159 }
160
161 void main() {
162 C c = new C();
163 // This line will produce a type error, because strong mode will infer
164 // `int` as the generic argument to fill in for S
165 String x = c.inferableFromArgument(3);
166
167 // This line will not produce a type error, because string mode is unable
vsm 2016/01/13 22:01:29 s/string/strong/
Leaf 2016/01/13 22:28:39 Done.
168 // to infer a type and will fill in the type argument with `dynamic`.
169 String y = c.notInferable(3);
170 }
171 ```
172
173 In the case that strong mode cannot infer the generic type arguments, the same
174 syntax that was shown above for instantiating generic classes can be used to
175 instantiate generic methods explicitly.
176
177 ```dart
178 void main() {
179 C c = new C();
180 // This line will produce a type error, because strong mode will infer
181 // `int` as the generic argument to fill in for S
182 String x = c.inferableFromArgument(3);
183
184 // This line will produce a type error in strong mode, because `int` is
185 // explicitly passed in as the argument to use for S
186 String y = c.notInferable/*<int>*/(3);
187 }
188 ```
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698