-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
Copy pathLangRef.html
3238 lines (2572 loc) · 130 KB
/
LangRef.html
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
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Swift Language Reference Manual</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="author" content="Chris Lattner">
<meta name="description"
content="Swift Language Reference Manual.">
<link rel="stylesheet" href="_static/swift.css" type="text/css">
<script type="text/javascript" src="toc.js"></script>
</head>
<body>
<h1>Swift Language Reference</h1>
<p>
<!-- The Table of Contents is automatically inserted in this <div>.
Do not delete this <div>. -->
<div id="nav"></div>
</p>
<!-- ********************************************************************* -->
<h2>Introduction</h2>
<!-- ********************************************************************* -->
<div class="commentary">
In addition to the main spec, there are lots of open ended questions,
justification, and ideas of what best practices should be. That random
discussion is placed in boxes to the right side of the main text (like this
one) to clarify what is normative and what is discussion.
</div>
<p>This is the language reference manual for the Swift language, which is
highly volatile and constantly under development. As the prototype evolves,
this document should be kept up to date with what is actually implemented.</p>
<p>The grammar and structure of the language is defined in BNF form in yellow
boxes. Examples are shown in gray boxes, and assume that the standard library
is in use (unless otherwise specified).</p>
<!-- ===================================================================== -->
<h3>Basic Goals</h3>
<!-- ===================================================================== -->
<div class="commentary">
A non-goal of the Swift project in general is to become some amazing
research project. We really want to focus on delivering a real product,
and having the design and spec co-evolve.
</div>
<p>In no particular order, and not explained well:</p>
<ol>
<li>Support building great frameworks and applications, with a specific focus
on permiting rich and powerful APIs.</li>
<li>Get the defaults right: this reduces the barrier to entry and increases
the odds that the right thing happens.</li>
<li>Through our support for building great APIs, we aim to provide an
expressive and productive language that is fun to program in.</li>
<li>Support low-level system programming. We should want to write compilers,
operating system kernels, and media codecs in Swift. This means that being
able to obtain high performance is really quite important.</li>
<li>Provide really great tools, like an IDE, debugger, profiling, etc.</li>
<li>Where possible, steal great ideas instead of innovating new things that
will work out in unpredictable ways. It turns out that there are a lot
of good ideas already out there.</li>
<li>Memory safe by default: array overrun errors, uninitialized values,
and other problems endemic to C should not occur in Swift, even if it
means some amount of runtime overhead. Eventually these checks will be
disablable for people who want ultimate performance in production
builds.</li>
<li>Efficiently implementable with a static compiler: runtime compilation is
great technology and Swift may eventually get a runtime optimizer, but it
is a strong goal to be able to implement swift with just a static
compiler.</li>
<li>Interoperate as transparently as possible with C, Objective-C, and
C++ without having to write an equivalent of "extern C" for every
referenced definition.</li>
<li>Great support for efficient by-value types.</li>
<li>Elegant and natural syntax, aiming to be familiar and easy to transition
to for "C" people. Differences from the C family should only be done when
it provides a significant win (e.g. eliminate declarator syntax).</li>
<li>Lots of other stuff too.</li>
</ol>
<p>A smaller wishlist goal is to support embedded sub-languages in swift, so
that we don't get the OpenCL-is-like-C-but-very-different-in-many-details
problem.</p>
<!-- ===================================================================== -->
<h3>Basic Approach</h3>
<!-- ===================================================================== -->
<div class="commentary">
Pushing as much of the language as realistic out of the compiler and into
the library is generally good for a few reasons: 1) we end up with a smaller
core language. 2) we force the language that is left to be highly
expressive and extensible. 3) this highly expressive language core can then
be used to build a lot of other great libraries, hopefully many we can't
even anticipate at this point.
</div>
<p>The basic approach in designing and implementing the Swift prototype was to
start at the very bottom of the stack (simple expressions and the trivial
bits of the type system) and incrementally build things up one brick at a
time. There is a big focus on making things as simple as possible and
having a clean internal core. Where it makes sense, sugar is added on top
to make the core more expressive for common situations.</p>
<p>One major aspect that dovetails with expressivity, learnability, and focus
on API development is that much of the language is implemented in a <a
href="#stdlib">standard library</a> (inspired in part by the Haskell
Standard Prelude). This means that things like 'Int' and 'Void' are not
part of the language itself, but are instead part of the standard library.
</p>
<!-- ********************************************************************* -->
<h2>Phases of Translation</h2>
<!-- ********************************************************************* -->
<div class="commentary">
Because Swift doesn't rely on a C-style "lexer hack" to know what is a type
and what is a value, it is possible to fully parse a file without resolving
import declarations.
</div>
<p>Swift has a strict separation between its phases of translation, and the
compiler follows a conceptually simple design. The phases of translation
are:</p>
<ul>
<li><a href="#lexical">Lexing</a>: A translation unit is broken into tokens
according to a (nearly, /**/ comments can be nested) regular grammar.</li>
<li>Parsing and AST Building: The tokens are parsed according to the grammar
set out below. The grammar is context free and does not require any "type
feedback" from the lexer or later stages. During parsing, name binding for
references to local variables and other declarations that are not at
translation unit (and eventually namespace) scope are bound.
</li>
<li><a href="#namebind">Name Binding</a>: At this phase, references to
non-local types and values are bound, and <a href="#decl-import">import
directives</a> are both validated and searched. Name binding can cause
recursive compilation of modules that are referenced but not yet built.
</li>
<li><a href="#typecheck">Type Checking</a>: During this phase all types are
resolved within value definitions, <a href="#expr-call">function
application</a> and <a href="#expr-infix">binary expressions</a> are found
and formed, and overloaded functions are resolved.</li>
<li>Code Generation: The AST is converted the LLVM IR, optimizations are
performed, and machine code generated.</li>
<li>Linking: runtime libraries and referenced modules are linked in.</li>
</ul>
<p>
FIXME: "import swift" implicitly added as the last import in translation unit.
</p>
<!-- ********************************************************************* -->
<h2 id="lexical">Lexical Structure</h2>
<!-- ********************************************************************* -->
<div class="commentary">
Not all characters are "taken" in the language, this is because it is still
growing. As there becomes a reason to assign things into the identifier or
punctuation bucket, we will do so as swift evolves.
</div>
<p>The lexical structure of a Swift file is very simple: the files are
tokenized according to the following productions and categories. As is
usual with most languages, tokenization uses the maximal munch rule and
whitespace separates tokens. This means that "a b" and "ab" lex into
different token streams and are therefore different in the grammar.</p>
<!-- ===================================================================== -->
<h3 id="whitespace">Whitespace and Comments</h3>
<!-- ===================================================================== -->
<div class="commentary">
Nested block comments are important because we don't have the nestable
"#if 0" hack from C to rely on.
</div>
<pre class="grammar">
whitespace ::= ' '
whitespace ::= '\n'
whitespace ::= '\r'
whitespace ::= '\t'
whitespace ::= '\0'
comment ::= //.*[\n\r]
comment ::= /* .... */
</pre>
<p>Space, newline, tab, and the nul byte are all considered whitespace and are
discarded, with one exception: a '(' or '[' which does not follow a
non-whitespace character is different kind of token (called
<em>spaced</em>) from one which does not (called <em>unspaced</em>).
A '(' or '[' at the beginning of a file is spaced.</p>
<p>Comments may follow the BCPL style, starting with a "//" and running to the
end of the line, or may be recursively nested /**/ style comments. Comments
are ignored and treated as whitespace.</p>
<!-- ===================================================================== -->
<h3 id="reserved_punctuation">Reserved Punctuation Tokens</h3>
<!-- ===================================================================== -->
<div class="commentary">
The difference between reserved punctuation and identifiers is that you
can't "overload an operator" with one of these names.<br><br>
Note that -> is used for function types "() -> Int", not pointer
dereferencing.
</div>
<pre class="grammar">
lparen-following ::= '(' // immediately (no white space) preceded by an
// identifier, or an identfier-like keyword, or
// a literal, or ')', or ']', or '}'
lparen-starting ::= '(' // any '(' that is not lparen-following
lparen-any ::= lparen-following
lparen-any ::= lparen-starting
lsquare-following ::= '[' // immediately (no white space) preceded by an
// identifier, or an identfier-like keyword, or
// a literal, or ')', or ']', or '}'
lsquare-starting ::= '[' // any '[' that is not lsquare-following
lsquare-any ::= lsquare-following
lsquare-any ::= lsquare-starting
punctuation ::= lparen-following
punctuation ::= lparen-starting
punctuation ::= ')'
punctuation ::= '{'
punctuation ::= '}'
punctuation ::= lsquare-following
punctuation ::= lsquare-starting
punctuation ::= ']'
punctuation ::= '.'
punctuation ::= ','
punctuation ::= ';'
punctuation ::= ':'
punctuation ::= '='
punctuation ::= '->'
punctuation ::= '...'
punctuation ::= '&' // unary prefix operator
</pre>
<p>These are all reserved punctuation that are lexed into tokens. Most other
punctuation is matched as <a href="#identifier">identifiers</a>.
</p>
<!-- ===================================================================== -->
<h3>Reserved Keywords</h3>
<!-- ===================================================================== -->
<div class="commentary">
The number of keywords is reduced by pushing most functionality
into the library (e.g. "builtin" datatypes like 'Int' and 'Bool'). This
allows us to add new stuff to the library in the future without worrying
about conflicting with the user's namespace.
</div>
<pre class="grammar">
// Declarations and Type Keywords
keyword ::= 'class'
keyword ::= 'constructor'
keyword ::= 'destructor'
keyword ::= 'extension'
keyword ::= 'import'
keyword ::= 'func'
keyword ::= 'oneof'
keyword ::= 'protocol'
keyword ::= 'requires'
keyword ::= 'static'
keyword ::= 'struct'
keyword ::= 'subscript'
keyword ::= 'typealias'
keyword ::= 'var'
// Statements
keyword ::= 'break'
keyword ::= 'case'
keyword ::= 'continue'
keyword ::= 'default'
keyword ::= 'do'
keyword ::= 'else'
keyword ::= 'if'
keyword ::= 'for'
keyword ::= 'return'
keyword ::= 'switch'
keyword ::= 'then'
keyword ::= 'while'
// Expressions
keyword ::= 'new'
keyword ::= 'as'
keyword ::= 'is'
// Identifier-Like Keywords
keyword ::= 'metatype'
keyword ::= 'super'
keyword ::= 'this'
keyword ::= 'This'
</pre>
<p>These are the builtin keywords.</p>
<!-- ===================================================================== -->
<h3 id="integer_literal">Integer Literals</h3>
<!-- ===================================================================== -->
<pre class="grammar">
integer_literal ::= [0-9]+
integer_literal ::= 0x[0-9a-fA-F]+
integer_literal ::= 0o[0-7]+
integer_literal ::= 0b[01]+
</pre>
<p>integer_literal tokens represent simple integer values of unspecified
precision.</p>
<!-- ===================================================================== -->
<h3 id="floating_literal">Floating Point Literals</h3>
<!-- ===================================================================== -->
<div class="commentary">
We require a digit on both sides of the dot to allow lexing "4.km" as
"4 . km" instead of "4. km" and for a series of dots to be an operator (for
ranges). The regex for decimal literals is same as Java, and the one for
hex literals is the same as C99, except that we do not allow a trailing
suffix that specifies a precision.
</div>
<pre class="grammar">
floating_literal ::= [0-9]+\.[0-9]+
floating_literal ::= [0-9]+\.[0-9]+[eE][+-]?[0-9]+
floating_literal ::= [0-9]+[eE][+-]?[0-9]+
floating_literal ::= 0x[0-9A-Fa-f]+(\.[0-9A-Fa-f]+)?[pP][+-]?[0-9]+
</pre>
<p>floating_literal tokens represent floating point values of unspecified
precision. Decimal and hexadecimal floating-point literals are supported.</p>
<!-- ===================================================================== -->
<h3 id="character_literal">Character Literals</h3>
<!-- ===================================================================== -->
<pre class="grammar">
character_literal ::= '[^'\\\n\r]|character_escape'
character_escape ::= [\]0 [\][\] | [\]t | [\]n | [\]r | [\]" | [\]'
character_escape ::= [\]x hex hex
character_escape ::= [\]u hex hex hex hex
character_escape ::= [\]U hex hex hex hex hex hex hex hex
hex ::= [0-9a-fA-F]
</pre>
<p>character_literal tokens represent a single character, and are surrounded
by single quotes.</p>
<p>The ASCII and Unicode character escapes:</p>
<pre>
\0 == nul
\n == new line
\r == carriage return
\t == horizontal tab
\u == small Unicode code points
\U == large Unicode code points
\x == raw ASCII byte (less than 0x80)
</pre>
<!-- ===================================================================== -->
<h3 id="string_literal">String Literals</h3>
<!-- ===================================================================== -->
<div class="commentary">
FIXME: Forcing + to concatenate strings is somewhat gross, a proper protocol
would be better.
</div>
<pre class="grammar">
string_literal ::= ["]([^"\\\n\r]|character_escape|escape_expr)*["]
escape_expr ::= [\]escape_expr_body
escape_expr_body ::= [(]escape_expr_body[)]
escape_expr_body ::= [^\n\r"()]
</pre>
<p>string_literal tokens represent a string, and are surrounded by double
quotes. String literals cannot span multiple lines.</p>
<p>String literals may contain embedded expressions in them (known as
"interpolated expressions") subject to some specific lexical constraints:
the expression may not contain a double quote ["], newline [\n], or carriage
return [\r]. All parentheses must be balanced.</p>
<p>In addition to these lexical rules, an interpolated expression must satisfy
the <a href="#expr">expr</a> production of the general swift grammar. This
expression is evaluated, and passed to the constructor for the inferred type
of the string literal. It is concatenated onto any fixed portions of the
string literal with a global "+" operator that is found through normal name
lookup.</p>
<pre class="example">
// Simple string literal.
"Hello world!"
// Interpolated expressions.
"\(min)..\(max)" + "Result is \((4+i)*j)"
</pre>
<!-- ===================================================================== -->
<h3 id="identifier">Identifier Tokens</h3>
<!-- ===================================================================== -->
<div>
<div class="commentary">
FIXME: We need to support unicode identifiers.
<br><br><b>[1]</b> The '=' token is explicitly handled in the grammar elsewhere,
and in general users cannot provide custom definitions for the '=' operator.
This distinctly differs from C++, which allows '=' to be overloaded.
<br><br><b>[2]</b> The '->' token is <a href="#reserved_punctuation">reserved punctuation</a>,
and cannot be used as an operator identifier.
<br><br><b>[3]</b> The unary prefix '&' token is <a href="#reserved_punctuation">reserved punctuation</a>,
and cannot be used as an operator identifier.
<br><br><b>[4]</b> The '//', '/*', and '*/' tokens are <a href="#whitespace">reserved for comments</a>,
and cannot be used as operator identifiers.
</div>
<pre class="grammar">
identifier ::= [a-zA-Z_][a-zA-Z_$0-9]*
<a name="operator">operator</a> ::= [/=-+*%<>!&|^~]+
<a name="operator">operator</a> ::= \.\.
Note: excludes '=', see <b>[1]</b>
excludes '->', see <b>[2]</b>
excludes unary '&', see <b>[3]</b>
excludes '//', '/*', and '*/', see <b>[4]</b>
'..' is an operator, not two '.'s.
operator-binary ::= operator
operator-prefix ::= operator
operator-postfix ::= operator
left-binder ::= [ \r\n\t\(\[\{,;]
any-identifier ::= identifier | operator
</pre>
<p><tt>operator-binary</tt>, <tt>operator-prefix</tt>, and
<tt>operator-postfix</tt> are distinguished by immediate lexical
context. An operator token is called <i>left-bound</i> if it
is immediately preceded by a character matching <tt>left-binder</tt>.
An operator token is called <i>right-bound</i> if it is immediately
followed by a character matching <tt>right-binder</tt>. An operator
token is an <tt>operator-prefix</tt> if it is right-bound but not
left-bound, an <tt>operator-postfix</tt> if it is left-bound but
not right-bound, and an <tt>operator-binary</tt> in either of the
other two cases.
</p>
<p>When parsing certain grammatical constructs that involve '<' and
'>' (such as <a href="#type-composition">protocol composition
types</a>), an <tt>operator</tt> with a leading '<' or '>' may
be split into two or more tokens: the leading '<' or '>' and
the remainder of the token, which may be an <tt>operator</tt> or
<tt>punctuation</tt> token that may itself be further split. This
rule allows us to parse nested constructs such as
<code>A<B<C>></code> without requiring spaces between
the closing '>'s.</p>
</div>
<!-- ===================================================================== -->
<h3 id="dollarident">Implementation Identifier Token</h3>
<!-- ===================================================================== -->
<pre class="grammar">
dollarident ::= $[0-9a-zA-Z_$]*
</pre>
<p>Tokens that start with a $ are separate class of identifier, which are
fixed purpose names that are defined by the implementation.
</p>
<!-- ********************************************************************* -->
<h2 id="decl">Declarations</h2>
<!-- ********************************************************************* -->
<pre class="grammar">
decl ::= <a href="#decl-class">decl-class</a>
decl ::= <a href="#decl-constructor">decl-constructor</a>
decl ::= <a href="#decl-destructor">decl-destructor</a>
decl ::= <a href="#decl-extension">decl-extension</a>
decl ::= <a href="#decl-func">decl-func</a>
decl ::= <a href="#decl-import">decl-import</a>
decl ::= <a href="#decl-oneof">decl-oneof</a>
decl ::= <a href="#decl-protocol">decl-protocol</a>
decl ::= <a href="#decl-struct">decl-struct</a>
decl ::= <a href="#decl-typealias">decl-typealias</a>
decl ::= <a href="#decl-var">decl-var</a>
decl ::= <a href="#decl-subscript">decl-subscript</a>
</pre>
<!-- ===================================================================== -->
<h3 id="decl-translation-unit">Translation Unit</h3>
<!-- ===================================================================== -->
<pre class="grammar">
translation-unit ::= <a href="#stmt-brace">stmt-brace-item</a>*
</pre>
<p>The top level of a swift source file is grammatically identical to the
contents of a <a href="#stmt-brace">brace statement</a>. Some declarations
have semantic restrictions that only allow them within a translation unit
though.
</p>
<!-- ===================================================================== -->
<h3 id="decl-import">import Declarations</h3>
<!-- ===================================================================== -->
<pre class="grammar">
decl-import ::= 'import' <a href="#attribute-list">attribute-list</a> any-identifier ('.' any-identifier)*
</pre>
<p>'import' declarations allow named values and types to be accessed with
local names, even when they are defined in other modules and namespaces. See
the section on <a href="#namebind">name binding</a> for more
information on how these work. import declarations are only allowed at
translation unit scope.</p>
<p>'import' directives only impact a single translation unit: imports in one
swift file do not affect name lookup in another file. import directives can
only occur at the top level of a file, not within a function or namespace.</p>
<p>If a single identifier is specified for the import declaration, then the
entire module is imported in its entirety into the current scope. If a
scope (such as a namespace) is named, then all entities in the namespace are
imported. If a specific type or variable is named (e.g. "import swift.Int")
then only the one type and/or value is imported. If the named value is
overloaded, then the entire overload set is imported.</p>
<pre class="example">
<i>// Import all of the top level symbols and types in a package.</i>
import swift
<i>// Import all of the symbols within a namespace.</i>
import swift.io
<i>// Import a single variable, function, type, etc.</i>
import swift.io.bufferedstream
<i>// Import all multiplication overloads.</i>
import swift.*
</pre>
<!-- ===================================================================== -->
<h3 id="decl-extension">extension Declarations</h3>
<!-- ===================================================================== -->
<div class="commentary">
Eventually allow extending classes, even adding data members.
</div>
<pre class="grammar">
decl-extension ::= 'extension' <a href="#type-identifier">type-identifier</a> <a href="#inheritance">inheritance</a>? '{' <a href="#decl">decl</a>* '}'
</pre>
<p>'extension' declarations allow adding member declarations to existing
types, even in other translation units and modules. There are different
semantic rules for each type that is extended.
</p>
<!-- _____________________________________________________________________ -->
<h4 id="decl-extension-oneof-struct"><a href="#decl-oneof">oneof</a>, <a
href="#decl-struct">struct</a>, and <a href="#decl-class">class</a>
declaration extensions</h4>
<p>FIXME: Write this section.</p>
<!-- ===================================================================== -->
<h3 id="decl-var">var Declarations</h3>
<!-- ===================================================================== -->
<pre id="value-specifier" class="grammar">
decl-var ::= 'var' <a href="#attribute-list">attribute-list</a> <a href="#pattern">pattern</a> initializer? (',' pattern initializer?)*
decl-var ::= 'var' <a href="#attribute-list">attribute-list</a> <a href="#identifier">identifier</a> ':' <a href="#type">type-annotation</a> <a href="#stmt-brace">stmt-brace</a>
decl-var ::= 'var' <a href="#attribute-list">attribute-list</a> <a href="#identifier">identifier</a> ':' <a href="#type">type-annotation</a> '{' get-set '}'
initializer ::= '=' <a href="#expr">expr</a>
<a name="get-set"></a>get-set ::= get set?
get-set ::= set get
get ::= 'get:' <a href="#stmt-brace">stmt-brace-item*</a>
set ::= 'set' set-name? ':' <a href="#stmt-brace">stmt-brace-item*</a>
set-name ::= '(' <a href="#identifier">identifier</a> ')'
</pre>
<p>'var' declarations form the backbone of value declarations in Swift. A var
declaration takes a pattern and an optional initializer, and declares all the
pattern-identifiers in the pattern as variables. If there is an initializer
and the pattern is <a href="#fully_typed_types">fully-typed</a>, the
initializer is converted to the type of the pattern. If there is an
initializer and the pattern is not fully-typed, the type of initializer is
computed independently of the pattern, and the type of the pattern is derived
from the initializer. If no initializer is specified, the pattern must be
fully-typed, and the values are default-initialized.</p>
<p>If there is more than one pattern in a 'var' declaration, they are each
considered independently, as if there were multiple declarations. The
initial attribute-list is shared between all the declared variables.
<p>A var declaration may contain a getter and (optionally) a setter,
which will be used when reading or writing the variable, respectively.
Such a variable does not have any associated storage. A var
declaration with a getter or setter must have a type (call it
<code>T</code>). The getter function, whose body is provided as part
of the <code>var-get</code> clause, has type <code>() -> T</code>.
Similarly, the setter function, whose body is part of the
<code>var-set</code> clause (if provided), has type <code>(T)
-> ()</code>. If the <code>var-set</code> clause contains a <code>var-set-name</code>
clause, the identifier of that clause is used as the name of the
parameter to the setter. Otherwise, the parameter name is "value".</p>
<p>FIXME: Should the type of a pattern which isn't fully typed affect the
type-checking of the expression (i.e. should we compute a structured
dependent type)?</p>
<p>Like all other declarations, var's can optionally have a list of <a
href="#attribute-list">attributes</a> applied to them.</p>
<p>The type of a variable must be
<a href="#materializable"><i>materializable</i></a>. A variable is
an lvalue unless it has a <code>var-get</code> clause but not
<code>var-set</code> clause. </p>
<p>Here are some examples of var declarations:</p>
<pre class="example">
<i>// Simple examples.</i>
var a = 4
var b : Int
var c : Int = 42
<i>// This decodes the tuple return value into independently named parts</i>
<i>// and both 'val' and 'err' are in scope after this line.</i>
var (val, err) = foo()
<i>// Variable getter/setter</i>
var _x : Int = 0
var x_modify_count : Int = 0
var x1 : Int {
return _x
}
var x2 : Int {
get:
return _x
set:
x_modify_count = x_modify_count + 1
_x = value
}
</pre>
<p>Note that both 'get' and 'set' are context-sensitive keywords.</p>
<!-- ===================================================================== -->
<h3 id="decl-func">func Declarations</h3>
<!-- ===================================================================== -->
<pre class="grammar">
decl-func ::= 'static'? 'func' <a href="#attribute-list">attribute-list</a> <a href="#identifier">any-identifier</a> <a href="#func-signature">func-signature</a> <a href="#stmt-brace">stmt-brace</a>?
</pre>
<p>'func' is a declaration for a function. The argument list and
optional return value are specified by the type production of the function,
and the body is either a brace expression or elided. Like all other
declarations, functions are can have attributes.</p>
<p>If the type is not syntactically a function type (i.e., has no -> in it
at top-level), then the return value is implicitly inferred to be
"<tt>()</tt>". All of the argument and return value names are injected into
the <a href="#namebind_scope">scope</a> of the function body.</p>
<p>A function in an <a href="#decl-extension">extension</a> of some type (or
in other places that are semantically equivalent to an extension) implicitly
get a 'this' argument with these rules ... [todo]</p>
<p>'static' functions are only allowed in an <a
href="#decl-extension">extension</a> of some type (or in other places
that are semantically equivalent to an extension). They indicate that
the function is actually defined on the <a href="#metatype">metatype</a>
for the type, not on the
type itself. Thus it does not implicitly get a first 'this' argument, and
can be used with dot syntax on the metatype.</p>
<p>TODO: Func should be an immutable name binding, it should implicitly add
an attribute immutable when it exists.</p>
<p>TODO: Incoming arguments should be readonly, result should be implicitly
writeonly when we have these attributes.</p>
<!-- _____________________________________________________________________ -->
<h4 id="func-signature">Function signatures</h4>
<pre class="grammar">
func-signature ::= func-arguments func-signature-result?
func-arguments ::= <a href="#pattern-tuple">pattern-tuple</a>+
func-arguments ::= selector-tuple
selector-tuple ::= '(' <a href="#pattern-tuple">pattern-tuple-element</a> ')' (<a href="#identifier">identifier</a> '(' pattern-tuple-element ')')+
func-signature-result ::= '->' <a href="#type">type</a>
</pre>
<p>A function signature specifies one or more sets of parameter
patterns, plus an optional result type.</p>
<p>When a result type is not written, it is implicitly the empty tuple type,
<tt>()</tt>.</p>
<p>In the body of the function described by a particular signature,
all the variables bound by all of the parameter patterns are in
scope, and the function must return a value of the result type.</p>
<p>An outermost pattern in a function signature must be <a
href="#fully_typed_types">fully-typed</a> and irrefutable. If a result type is
given, it must also be fully-typed.</p>
<p>The type of a function with signature <tt>(P<sub>0</sub>)(P<sub>1</sub>)..(P<sub><i>n</i></sub>) -> R</tt>
is <tt>T<sub>0</sub> -> T<sub>1</sub> -> .. -> T<sub><i>n</i></sub> -> R</tt>,
where <tt>T<sub><i>i</i></sub></tt> is the bottom-up type of the pattern
<tt>P<sub><i>i</i></sub></tt>. This is called "currying". The
behavior of all the intermediate functions (those which do not
return <tt>R</tt>) is to capture their arguments, plus any
arguments from prior patterns, and returns a function which takes
the next set of arguments. When the "uncurried" function is
called (the one taking <tt>T<sub><i>n</i></sub></tt> and returning
<tt>R</tt>), all of the arguments are then available and the
function body is finally evaluated as normal.</p>
<p>A function declared with a selector-style signature
<tt>func(a<sub>0</sub>:T<sub>0</sub>) name<sub>1</sub>(a<sub>1</sub>:T<sub>1</sub>) .. name<sub><i>n</i></sub>(a<sub><i>n</i></sub>:T<sub><i>n</i></sub>) -> R</tt>
has the type <tt>(_:T<sub>0</sub>, name<sub>1</sub>:T<sub>1</sub>, .. name<sub><i>n</i></sub>:T<sub><i>n</i></sub>) -> R</tt>,
that is, the names of the fields in the argument tuple are the
<tt>name<sub><i>n</i></sub></tt> identifiers preceding each argument
pattern. However, in the body of a function
described by a signature, those arguments will be bound using the
corresponding
<tt>a<sub><i>n</i></sub></tt> patterns inside
the arguments. This allows for Cocoa-style keyword function
names such as <tt>doThing(x, withThing:y)</tt> to be defined without
requiring that an awkward keyword name be the same as the
variable name.
<p>Here are some examples of func definitions:</p>
<pre class="example">
<i>// Implicitly returns (), aka <a href="#stdlib-Void">Void</a></i>
func a() {}
<i>// Same as 'a'</i>
func a1() -> Void {}
<i>// Function pointers to a function expression.</i>
var a2 = func ()->() {}
var a3 = func () {}
var a4 = func {}
<i>// Really simple function</i>
func c(arg : Int) -> Int { return arg+4 }
<i>// Simple operators.</i>
func [infix_left=190] + (lhs : Int, rhs : Int) -> Int
func [infix_left=160] == (lhs : Int, rhs : Int) -> Bool
<i>// Curried function with multiple return values:</i>
func d(a : Int) (b : Int) -> (res1 : Int, res2 : Int) {
return (a,b)
}
<i>// A more realistic example on a trivial type.</i>
struct bankaccount {
amount : Int
static func bankaccount() -> bankaccount {
// Custom 'constructor' logic goes here.
}
func deposit(arg : Int) {
amount = amount + arg
}
static func someMetaTypeMethod() {}
}
<i>// Dot syntax on metatype.</i>
bankaccount.someMetaTypeMethod()
<i>// A function with selector-style signature.</i>
oneof PersonOfInterest {ColonelMustard, MissScarlet}
oneof Room {Conservatory, Ballroom}
oneof Weapon {Candlestick, LeadPipe}
func accuseSuspect(suspect:PersonOfInterest)
inRoom(room:Room)
withWeapon(weapon:Weapon) {
println("It was " + suspect + " in the " + room + " with the " +
weapon);
}
<i>// Calling a selector-style function.</i>
accuseSuspect(.ColonelMustard, inRoom:.Ballroom, withWeapon:.LeadPipe)
</pre>
<!-- ===================================================================== -->
<h3 id="decl-typealias">typealias Declarations</h3>
<!-- ===================================================================== -->
<div class="commentary">
We use the keyword "typealias" instead of "typedef" because it really is an
alias for an existing type, not a "definition" of a new type.
</div>
<pre class="grammar">
decl-typealias ::= typealias-head '=' <a href="#type">type</a>
<a name="typealias-head"></a>typealias-head ::= 'typealias' <a href="#identifier">identifier</a> <a href="#inheritance">inheritance</a>?
</pre>
<p>'typealias' makes a named alias of a type, like a typedef in C. From that
point on, the alias may be used in all situations the specified name is. If an <a href="#inheritance">inheritance</a> clause is provided, it specifies protocols to which the aliased type shall conform.</p>
<p>Here are some examples of type aliases:</p>
<pre class="example">
<i>// location is an alias for a tuple of ints.</i>
typealias location = (x : Int, y : Int)
<i>// pair_fn is a function that takes two ints and returns a tuple.</i>
typealias pair_fn = (Int) -> (Int) -> (first : Int, second : Int)
</pre>
<!-- ===================================================================== -->
<h3 id="decl-oneof">oneof Declarations</h3>
<!-- ===================================================================== -->
<div class="commentary">
In actual practice, we expect oneof to be commonly used for "enums" and
"struct" below to be used for data declarations. The use of "oneof" for
discriminated unions will be much less common than its use for "enums". If
there is a compelling reason to, we could add an "enum" sugar for
oneof's.
</div>
<pre class="grammar">
decl-oneof ::= 'oneof' <a href="#attribute-list">attribute-list</a> <a href="#identifier">identifier</a> <a href="#inheritance">inheritance</a>? oneof-body
oneof-body ::= '{' (oneof-element (',' oneof-element)*)? decl* '}'
oneof-element ::= <a href="#identifier">identifier</a>
oneof-element ::= <a href="#identifier">identifier</a> ':' <a href="#type">type-annotation</a>
</pre>
<p>A oneof declaration provides direct access to <a
href="#type-oneof">oneof</a> types with a <a
href="#decl-typealias">typealias</a> declaration specifying a name. Please
see <a href="#type-oneof">oneof types</a> for more information about their
capabilities.</p>
<p>A 'oneof' may include a list of decls after its member types, which is
syntactic sugar for defining an <a href="#decl-extension">extension</a> of
the type. The limitations of an <a
href="#decl-extension-oneof-struct">oneof extensions</a> apply here as
well.</p>
<p>Here are some examples of oneof declarations:</p>
<pre class="example">
<i>// Declare discriminated union with oneof decl.</i>
oneof SomeInts {
None,
One : Int,
Two : (Int, Int)
}
<i>// Declares three "enums".</i>
oneof DataSearchFlags {
None, Backward, Anchored
}
func f1(searchpolicy : DataSearchFlags) <i>// DataSearchFlags is a valid type name</i>
func test1() {
f1(DataSearchFlags.None) <i>// Use of constructor with qualified identifier</i>
f1(.None) <i>// Use of constructor with context sensitive type inference</i>
<i>// "None" has no type argument, so the constructor's type is "DataSearchFlags".</i>
var a : DataSearchFlags = .None
}
oneof SomeMoreInts {
None, <i>// Doesn't conflict with previous "None".</i>
One : Int,
Two : (Int, Int)
}
func f2(a : SomeMoreInts)
func test2() {
<i>// Constructors for oneof element can be used in the obvious way.</i>
f2(.None)
f2(.One(4))
f2(.Two(1, 2))
<i>// Constructor for None has type "SomeMoreInts".</i>
var a : SomeMoreInts = SomeMoreInts.None
<i>// Constructor for One has type "(Int) -> SomeMoreInts".</i>
var b : (Int) -> SomeMoreInts = SomeMoreInts.One
<i>// Constructor for Two has type "(Int,Int) -> SomeMoreInts".</i>
var c : (Int,Int) -> SomeMoreInts = SomeMoreInts.Two
}
</pre>
<!-- ===================================================================== -->
<h3 id="decl-struct">struct Declarations</h3>
<!-- ===================================================================== -->
<pre class="grammar">
decl-struct ::= 'struct' <a href="#attribute-list">attribute-list</a> <a href="#identifier">identifier</a> <a href="#inheritance">inheritance</a>? '{' decl-struct-body '}'
decl-struct-body ::= <a href="#decl">decl</a>*
</pre>
<p>A struct declares a simple value type that can contain data members and
have methods.</p>
<p>The body of a 'struct' is a list of decls. Non-property 'var' decls
declare members with storage in the struct. Other declarations act like
they would in an <a href="#decl-extension">extension</a> of the
struct type.</p>
<p>Here are a few simple examples:</p>
<pre class="example">
struct S1 {
var a : Int, b : Int
}
struct S2 {
var a : Int
func f() -> Int { return b }
var b : Int
}
</pre>
<p>Here are some more realistic examples of structs:</p>
<pre class="example">
struct Point { x : Int, y : Int }
struct Size { width : Int, height : Int }
struct Rect {
origin : Point,
size : Size
typealias CoordinateType = Int
func area() -> Int { return size.width*size.height }
}
func test4() {
var a : Point
var b = Point.Point(1, 2) // Silly but fine.
var c = Point(y = 1, x = 2) // Using metatype.
var x1 = Rect(a, Size(42, 123))
var x2 = Rect(size = Size(width = 42, height=123), origin = a)
var x1_area = x1.width*x1.height
var x1_area2 = x1.area()
}
</pre>
<!-- ===================================================================== -->
<h3 id="decl-class">class Declarations</h3>