mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
1115 lines
44 KiB
HTML
1115 lines
44 KiB
HTML
<!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="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. It is my (Chris') intention
|
|
to keep this up to date as the prototype evolves.</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>
|
|
|
|
<ol>
|
|
<li>Support building great frameworks and applications, making it easier to
|
|
do the right thing by default and reducing the barrier of entry to our
|
|
systems.</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 really important.</li>
|
|
<li>Provide really great tools.</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>Lots of other stuff too.</li>
|
|
</ol>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3>Basic Approach</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<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 some sugar (e.g. "func"
|
|
and "struct") 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
|
|
standard library (inspired by the Haskell Standard Prelude). By pushing
|
|
much of the boring parts of the language out of the compiler into the
|
|
library, we end up with a smaller core language and we force the language
|
|
that is left to be highly expressive and extensible, which we hope will
|
|
allow for great libraries to be built on top of it.
|
|
</p>
|
|
|
|
<p>More later.</p>
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h2>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>Whitespace and Comments</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
TODO: /**/ comments will be supported when I get around to it.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
whitespace ::= ' '
|
|
whitespace ::= '\n'
|
|
whitespace ::= '\r'
|
|
whitespace ::= '\t'
|
|
whitespace ::= '\0'
|
|
comment ::= //.*[\n\r]
|
|
</pre>
|
|
|
|
<p>Space, newline, tab, and the nul byte are all considered whitespace and are
|
|
discarded.</p>
|
|
|
|
<p>Comments follow the BCPL style, starting with a "//" and running to the end
|
|
of the file. Comments are ignored as whitespace.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3>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">
|
|
punctuation ::= '('
|
|
punctuation ::= ')'
|
|
punctuation ::= '{'
|
|
punctuation ::= '}'
|
|
punctuation ::= '['
|
|
punctuation ::= ']'
|
|
punctuation ::= '.'
|
|
punctuation ::= ','
|
|
punctuation ::= ';'
|
|
punctuation ::= ':'
|
|
punctuation ::= '::'
|
|
punctuation ::= '='
|
|
punctuation ::= '->'
|
|
</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 control flow and other
|
|
stuff into the library. This allows us to add new stuff to the library in
|
|
the future without worrying about conflicting with the user's namespace.
|
|
Because 'if' is just a library function, you can shadow "if" with your own
|
|
variable (though this is an example of a silly thing that is not a good
|
|
practice of course).<br><br>
|
|
|
|
Idea: Should _foo be "private" and "foo" be public?
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
keyword ::= '__builtin_int32_type'
|
|
keyword ::= 'oneof'
|
|
keyword ::= 'struct'
|
|
keyword ::= 'var'
|
|
keyword ::= 'func'
|
|
keyword ::= 'typealias'
|
|
</pre>
|
|
|
|
<p>These are the builtin keywords. Swift intentionally tries to reduce the
|
|
number of keywords where possible.</p>
|
|
|
|
<p>FIXME: __ should be considered the compiler/languages reserved namespace,
|
|
any use of an unknown identifier here should be an error.</p>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="numeric_constant">Numeric Constant</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
numeric_constant ::= [0-9]+
|
|
</pre>
|
|
|
|
<p>Numeric constant tokens represent simple integer values.</p>
|
|
<p>TODO: Obviously need a floating point constant when we have a fp type.</p>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="identifier">Identifier Tokens</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
identifier ::= [a-zA-Z_][a-zA-Z_$0-9]*
|
|
identifier ::= [/=-+*%<>!&|^]+
|
|
</pre>
|
|
|
|
<p>There are two different regular expressions for identifiers, one for normal
|
|
identifiers and one for "punctuation identifiers". This ensures that
|
|
something like "foo+bar" gets lexed into three identifiers, not one. Aside
|
|
from the regex that controls lexing behavior, there is no other difference
|
|
between these two forms of identifiers.
|
|
</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<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">
|
|
translation-unit ::= decl-top-level*
|
|
decl-top-level ::= ';'
|
|
decl-top-level ::= <a href="#decl-var">decl-var</a>
|
|
decl-top-level ::= <a href="#decl-func">decl-func</a>
|
|
decl-top-level ::= <a href="#decl-typealias">decl-typealias</a>
|
|
decl-top-level ::= <a href="#decl-oneof">decl-oneof</a>
|
|
decl-top-level ::= <a href="#decl-struct">decl-struct</a>
|
|
</pre>
|
|
|
|
<p>A source file in Swift is parsed as a list of top level declarations.
|
|
Extraneous semi colons are allowed at top level, as are a number of other
|
|
declarations.</p>
|
|
|
|
<p>TODO: Need to define the module system, which will give us 'import' and
|
|
'module'.</p>
|
|
|
|
<p>FIXME: Code should be definable at the top level of a file as well, this
|
|
becomes a static constructor for a library and is the "main" for an
|
|
executable.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-var">var</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
decl-var ::= 'var' <a href="#attribute-list">attribute-list</a>? var-name <a href="#value-specifier">value-specifier</a>
|
|
|
|
value-specifier ::= ':' <a href="#type">type</a>
|
|
value-specifier ::= ':' <a href="#type">type</a> '=' <a href="#expr">expr</a>
|
|
value-specifier ::= '=' <a href="#expr">expr</a>
|
|
</pre>
|
|
<!--
|
|
Note that the initializer can't be expr-singular. If it were we would fail
|
|
to handle dependent cases like "var x : somestruct = :foo(4)
|
|
-->
|
|
|
|
|
|
<p>'var' declarations form the backbone of value declarations in Swift and
|
|
are the core semantic model for these values. The <a
|
|
href="#decl-func">func declaration</a> is just syntactic sugar for a var
|
|
declaration.</p>
|
|
|
|
<p>Syntactically var declarations come in three forms from the value-specifier
|
|
production. In the first form,
|
|
a type is specified and the value is default initialized. In the second
|
|
form the type is elided but a value is specified, the declaration gets the
|
|
specified value and has the same type as its initializer. In the third
|
|
form, the values type is as specified and the initializer is <a
|
|
href="#sema_conversions">converted to</a> that type if required.</p>
|
|
|
|
<p>Var declarations can optionally have a list of <a
|
|
href="#attribute-list">attributes</a> applied to them.</p>
|
|
|
|
<pre class="grammar">
|
|
var-name ::= <a href="#identifier">identifier</a>
|
|
var-name ::= '(' ')'
|
|
var-name ::= '(' var-name (',' var-name)* ')'
|
|
</pre>
|
|
|
|
<p>The name given to the var can have structure that allows fields of the
|
|
returned value to be directly named and accessed in later code. The
|
|
structure of the name is required to match up with the type being matched.
|
|
An single identifier is always valid to capture the entire value
|
|
(potentially as an aggregate).</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>// Declaring a function like value with 'var', using an attribute.</i>
|
|
<i>// The name here is "==", the type is a function that takes a tuple</i>
|
|
<i>// and returns an int.</i>
|
|
var [infix=120] == : (lhs : int, rhs : int) -> int
|
|
|
|
<i>// This decodes the tuple return value into indendently named parts</i>
|
|
<i>// and both 'val' and 'err' are in scope after this line.</i>
|
|
var (val, err) = foo();
|
|
</pre>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-func">func</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
decl-func ::= 'func' <a href="#attribute-list">attribute-list</a>? <a href="#identifier">identifier</a> <a href="#type">type</a> '=' <a href="#expr">expr</a>
|
|
decl-func ::= 'func' <a href="#attribute-list">attribute-list</a>? <a href="#identifier">identifier</a> <a href="#type">type</a> <a href="#brace-expr">brace-expr</a>
|
|
decl-func ::= 'func' <a href="#attribute-list">attribute-list</a>? <a href="#identifier">identifier</a> <a href="#type">type</a>
|
|
</pre>
|
|
|
|
<p>A 'func' declaration is just shorthand syntax for the (extremely) common
|
|
case of a declaration of function value. The argument list and optional
|
|
return value are specified by the type production of the function, and the
|
|
body is either not specified or is an arbitrary expression. If the argument
|
|
type is not a function type, then the return value is implicitly inferred to
|
|
be "()". All of the argument and return value names are injected into the
|
|
<a href="#sema_scope">scope</a> of the function body.</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>
|
|
|
|
<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 b() -> void {}
|
|
|
|
<i>// Really simple function</i>
|
|
func c(arg : int) -> void = arg+4
|
|
|
|
<i>// Simple operator.</i>
|
|
func [infix=120] + (lhs: int, rhs: int) -> int;
|
|
|
|
<i>// Function with multiple return values:</i>
|
|
func d(a : int) -> (b : int) -> (res1 : int, res2 : int);
|
|
</pre>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-typealias">typealias</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
decl-typealias ::= 'typealias' <a href="#identifier">identifier</a> ':' <a href="#type">type</a>
|
|
</pre>
|
|
|
|
<p>Type alias makes a named alias of a type. From that point on, the alias
|
|
may be used in all situations the specified name is. This is the same thing
|
|
as a typedef in C. It is named "typealias" because it really is an alias, not
|
|
a "new" type.</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 ins and returns a tuple.</i>
|
|
typealias pair_fn : int -> int -> (first : int, second : int)
|
|
</pre>
|
|
|
|
<p>FIXME: It's not "from that point on", you should be able to declare a type
|
|
alias after using it. Need to separate name binding from parsing logic.
|
|
Without this, mutually dependent component members can't exist.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-oneof">oneof</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 (but is still very important)
|
|
than its use for "enums".
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
decl-oneof ::= 'oneof' <a href="#attribute-list">attribute-list</a>? <a href="#identifier">identifier</a> '{' oneof-element-list '}'
|
|
|
|
oneof-element-list ::= oneof-element ','?
|
|
oneof-element-list ::= oneof-element ',' oneof-element-list
|
|
|
|
oneof-element ::= <a href="#identifier">identifier</a>
|
|
oneof-element ::= <a href="#identifier">identifier</a> ':' <a href="#type">type</a>
|
|
|
|
</pre>
|
|
|
|
<p>A oneof declaration consists of a comma-separated list of elements,
|
|
which are each either an identifier or an identifier with a type. The runtime
|
|
representation of a value of oneof type only has one of the specified oneof
|
|
elements at a time: a oneof value is a simple discriminated union. Oneof
|
|
declarations are known as <a
|
|
href="http://en.wikipedia.org/wiki/Algebraic_data_type">algebraic data
|
|
types</a> by the broader programming language community.</p>
|
|
|
|
<p>A oneof declaration declares two things: 1) the name of the data
|
|
declaration
|
|
is defined as a new type name, and 2) each of the oneof elements declares a
|
|
constructor value which create a value of the oneof type with the specified
|
|
element kind.</p>
|
|
|
|
<p>The type of oneof declaration is injected into the current scope, so it may
|
|
be used as a type name immediately. The constructor values are defined in a
|
|
nested scope within the oneof descriptor type, so they must be accessed with
|
|
either a <a href="#expr-identifier">qualified identifier</a> or through
|
|
<a href="#expr-delayed-identifier">delayed identifier resolution</a>
|
|
with <a href="#sema_context">context sensitive type inference</a>.
|
|
</p>
|
|
|
|
<p>If the oneof element has no type specified with it, then the type of the
|
|
constructor is the type of the oneof declaration. If a oneof element has a
|
|
type "T" associated with it, then the type of the constructor is a function
|
|
that takes "T" and returns the type of the oneof declaration.</p>
|
|
|
|
<p>Here are some examples of oneof declarations:</p>
|
|
|
|
<pre class="example">
|
|
<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 SomeInts {
|
|
None, <i>// Doesn't conflict with previous "None".</i>
|
|
One int, <i>// Argument type is simple int.</i>
|
|
Two (:int, :int) <i>// Argument type is simple tuple.</i>
|
|
}
|
|
|
|
func f2(a : SomeInts);
|
|
|
|
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 "SomeInts".</i>
|
|
var a : SomeInts = SomeInts::None;
|
|
|
|
<i>Constructor for One has type "int -> SomeInts".</i>
|
|
var b : int -> SomeInts = SomeInts::One;
|
|
|
|
<i>Constructor for Two has type "(:int,:int) -> SomeInts".</i>
|
|
var c : (:int,:int) -> SomeInts = SomeInts::Two;
|
|
}
|
|
</pre>
|
|
|
|
<p>TODO: Should attributes be allowed on oneof elements?
|
|
TODO: Eventually, with generics we'll have equality and inequality operators.
|
|
Oneof decls should implicitly define these for their types.
|
|
TODO: Need pattern matching and element extraction.
|
|
</p>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="decl-struct">struct</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
decl-struct ::= 'struct' <a href="#attribute-list">attribute-list</a>? <a href="#identifier">identifier</a> <a href="#type">type</a>
|
|
</pre>
|
|
|
|
<p>A struct declaration is syntactic sugar for a oneof declaration of a single
|
|
element. It requires that a type be specified, and declares a oneof with a
|
|
single constructor value of the same name as the struct.</p>
|
|
|
|
<p>Note that unlike oneof, struct does inject this constructor value into the
|
|
global scope. This means that you don't need to use qualified lookup to get
|
|
access to the constructor for a struct.</p>
|
|
|
|
<p>These two declarations are equivalent (but have different names):</p>
|
|
|
|
<pre class="example">
|
|
struct S1 (a : int, b : int)
|
|
|
|
oneof S2 {
|
|
S2 (a : int, b : int)
|
|
}
|
|
var S2 = S2::S2; <i>// Constructor injected into global scope.</i>
|
|
</pre>
|
|
|
|
|
|
<p>Here are some 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)
|
|
|
|
func test4() {
|
|
var a : Point;
|
|
var b = Point::Point(1, 2); // Silly but fine.
|
|
var c = Point(.y = 1, .x = 2); // Using injected name.
|
|
|
|
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;
|
|
}
|
|
</pre>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="attribute-list">Attribute Lists</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
attribute-list ::= '[' ']'
|
|
attribute-list ::= '[' attribute (',' attribute)* ']'
|
|
|
|
attribute ::= attribute-infix
|
|
</pre>
|
|
|
|
<p>An attribute is a (possibly empty) comma separated list of attributes.</p>
|
|
|
|
<h4 id="attribute-infix">Infix Attribute</h4>
|
|
|
|
<pre class="grammar">
|
|
attribute-infix ::= 'infix' '=' <a href="#numeric_constant">numeric_constant</a>
|
|
</pre>
|
|
|
|
<p>The only attribute supported so far is the 'infix' attribute.
|
|
FIXME: Describe requirements on function/var it is applied to, must be binary
|
|
etc.</p>
|
|
|
|
<p>TODO: Add support for a bunch more attributes.</p>
|
|
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h2 id="type">Simple Data Types</h2>
|
|
<!-- ********************************************************************* -->
|
|
|
|
<pre class="grammar">
|
|
type ::= type-simple
|
|
type ::= <a href="#type-function">type-function</a>
|
|
type ::= <a href="#type-array">type-array</a>
|
|
|
|
type-simple ::= <a href="#type-builtin">type-builtin</a>
|
|
type-simple ::= <a href="#type-identifier">type-identifier</a>
|
|
type-simple ::= <a href="#type-tuple">type-tuple</a>
|
|
</pre>
|
|
|
|
<p>Swift has a small collection of core datatypes that are built into the
|
|
compiler. Most datatypes that the user is exposed are defined by the
|
|
<a href="#stdlib">standard library</a> or declared as a user defined
|
|
type.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="type-builtin">Builtin and Named Types</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
type-builtin ::= '__builtin_int32_type'
|
|
</pre>
|
|
|
|
<p>'__builtin_int32_type' is the name of the 32-bit integer type.</p>
|
|
|
|
<p>TODO: Support builtin int8, int16, int64, bool, float and double.</p>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="type-identifier">Named Types</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
type-identifier ::= <a href="#identifier">identifier</a>
|
|
</pre>
|
|
|
|
<p>Types may also be named, through a <a href="#decl-oneof">oneof</a>
|
|
declaration, a <a href="#decl-typealias">typealias</a> etc.</p>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="type-tuple">Tuple Types</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
type-tuple ::= '(' ')'
|
|
type-tuple ::= '(' type-tuple-element (',' type-tuple-element)* ')'
|
|
</pre>
|
|
|
|
<p>Syntactically, tuple types are simply a possibly empty list of tuple
|
|
elements.</p>
|
|
|
|
<p>Tuples are the primary form of data aggregation in Swift, and are used as
|
|
the building block of <a href="#type-function">function</a> argument lists,
|
|
multiple return values, <a href="#decl-struct">struct</a> and
|
|
<a href="#decl-oneof">oneof</a> bodies, etc. Because tuples are widely
|
|
accessible and available everywhere in the language, aggregate data access and
|
|
transformation is uniform and powerful.</p>
|
|
|
|
<pre class="grammar">
|
|
type-tuple-element ::= <a href="#identifier">identifier</a>? ':' <a href="#type">type</a>
|
|
</pre>
|
|
|
|
<p>Each element of a tuple contains an optional name followed by a required
|
|
type. The name affects swizzling of elements in the tuple when <a
|
|
href="#sema_conversions">tuple conversions</a> are performed.</p>
|
|
|
|
<p>FIXME: Tuples should allow initializers (like var) unifying the production
|
|
for var and tuple elements as well as making tuples far more powerful
|
|
(supporting default values throughout swift).</p>
|
|
|
|
<pre class="example">
|
|
<i>// Variable definitions.</i>
|
|
var a : ()
|
|
var b : (:int, :int)
|
|
var c : (x : (), y : int)
|
|
|
|
<i>// Inferred types.</i>
|
|
var d = () <i>// Type = ()</i>
|
|
var e = (.x = 1, .y = 2) <i>// Type = (x : int, y : int)</i>
|
|
var f = (1, 2, 3) <i>// Type = (:int, :int, :int)</i>
|
|
|
|
<i>// Function argument and result is a tuple type.</i>
|
|
func foo(x : int, y : int) -> (val : int, err : int);
|
|
|
|
<i>// oneof and struct declarations with tuple values.</i>
|
|
struct S (a : int, b : int)
|
|
oneof Vertex {
|
|
Point2 (x : int, y : int),
|
|
Point3 (x : int, y : int, z : int),
|
|
Point4 (w : int, x : int, y : int, z : int)
|
|
}
|
|
</pre>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="type-function">Function Types</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
type-function ::= <a href="#type">type-simple</a> '->' <a href="#type">type</a>
|
|
</pre>
|
|
|
|
<p>Function types have a single input and single result type, separated by
|
|
an arrow. Because each of the types is allowed to be a tuple, we do
|
|
support multiple argument lists and multiple results. "Function" types are
|
|
more properly known as a "closure" type, because they can embody any
|
|
context captured when the function variable was formed.</p>
|
|
|
|
<p>Because of the grammar structure, a nested function like "a -> b ->
|
|
c" is parsed as "a -> (b -> c)". This means that if you declare this
|
|
that you can pass it one argument to get a function that "takes b and
|
|
returns c" or you can pass two arguments to "get a c". For example:
|
|
</p>
|
|
|
|
<pre class="example">
|
|
<i>// A simple function that takes a tuple and returns int:</i>
|
|
var a : (a : int, b : int) -> int
|
|
|
|
<i>// A simple function that returns multiple values:</i>
|
|
var a : (a : int, b : int) -> (val: int, err: int)
|
|
|
|
<i>// Declare a function that returns a function:</i>
|
|
var x : int -> int -> int;
|
|
|
|
<i>// y has type int -> int</i>
|
|
var y = x 1;
|
|
|
|
<i>// z1 and z2 both has type int, and both have the same value (assuming
|
|
// the function had no side effects).</i>
|
|
var z1 = x 1 2;
|
|
var z2 = y 2;
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="type-array">Array Types</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
type-array ::= <a href="#type">type</a> '[' ']'
|
|
type-array ::= <a href="#type">type</a> '[' <a href="#expr">expr</a> ']'
|
|
</pre>
|
|
|
|
<p>Array types include a base type and an optional size. Array types indicate
|
|
a linear sequence of elements stored consequtively memory. Array elements may
|
|
be efficiently indexed in constant time. All array indexes are bounds checked
|
|
and out of bound accesses are diagnosed with either a compile time or
|
|
runtime failure (TODO: runtime failure mode not specified).</p>
|
|
|
|
<p>While they look syntactically very similar, an array type with a size has
|
|
very different semantics than an array without. In the former case, the type
|
|
indicates a declaration of actual storage space. In the later case, the type
|
|
indicates a <em>reference</em> to storage space allocated elsewhere of
|
|
runtime-specified size.
|
|
</p>
|
|
|
|
<p>For an array with a size, the size must be more than zero (no
|
|
indices would be valid). For now, the array size must be a literal integer.
|
|
TODO: Define a notion like C's integer-constant-expression for how constant
|
|
folding works.</p>
|
|
|
|
<p>FIXME: int[][] not valid because the element type isn't sized. We need
|
|
some constraint to reject this.</p>
|
|
|
|
<p>Some example array types:</p>
|
|
|
|
<pre class="example">
|
|
<i>// A simple array declaration:</i>
|
|
var a : int[4];
|
|
|
|
<i>// A reference to another array:</i>
|
|
var b : int[] = a;
|
|
|
|
<i>// Declare a two dimensional array:</i>
|
|
var c : int[4][4];
|
|
|
|
<i>// Declare a reference to another array, two dimensional:</i>
|
|
var d : int[4][];
|
|
|
|
<i>// Declare an array of function pointers:</i>
|
|
var array_fn_ptrs : (: int -> int)[42];
|
|
var g = array_fn_ptrs[12](4);
|
|
|
|
<i>// Without parens, this is a function that returns a fixed size array:</i>
|
|
var fn_returning_array : int -> int[42];
|
|
var h : int[42] = fn_returning_array(4);
|
|
|
|
<i>// You can even have arrays of tuples and other things, these work right
|
|
// through composition:</i>
|
|
var array_of_tuples : (a : int, b : int)[42];
|
|
var tuple_of_arrays : (a : int[42], b : int[42]);
|
|
|
|
array_of_tuples[12].a = array_of_tuples[13].b;
|
|
tuple_of_arrays.a[12] = array_of_tuples.b[13];
|
|
</pre>
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h2 id="expr">Expressions</h2>
|
|
<!-- ********************************************************************* -->
|
|
|
|
<div class="commentary">
|
|
The goal of semicolon elision is to clean up the common case where ;'s are
|
|
just clutter. While they allow people to write confusing and obfuscated
|
|
code, any language feature can be abused. We'll encourage good practices in
|
|
the documentation and frameworks.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
expr ::= <a href="#expr-single">expr-single</a>+
|
|
</pre>
|
|
|
|
<p>At the top level, a sequence of "singular" expressions are allowed anytime
|
|
an expression is allowed. The value of the expr is the result of the last
|
|
singular expression. This grammar rule allows semicolons between expressions
|
|
to be elided.</p>
|
|
|
|
<pre class="example">
|
|
<i>// A silly, but valid, example:</i>
|
|
4 4 (4+5) 4 4
|
|
|
|
<i>// A more reasonable example.</i>
|
|
foo()
|
|
x = 12
|
|
bar(49+1)
|
|
baz()
|
|
</i>
|
|
</pre>
|
|
|
|
<p>This grammar production is ambiguous with the <a
|
|
href="#expr-apply">expr-apply</a> production, but binds very loosely.</p>
|
|
|
|
<p>NOTE: The application logic in ParseExpr is here for the case when the
|
|
first expr has dependent type that later resolves to be a function.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-single">Singular Expressions</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-single ::= expr-primary (binary-operator expr-primary)*
|
|
binary-operator ::= identifier
|
|
</pre>
|
|
|
|
<p>Singular expressions are a binary-operator-separated list of primary
|
|
expressions. A "binary operator" is any identifier which name lookup resolves
|
|
to a declaration with the <a href="#attribute-infix">infix</a> attribute.
|
|
The order of evaluation of the various subexpressions is defined by the
|
|
precedence of the infix attribute.
|
|
</p>
|
|
|
|
<p>TODO: Should this use the expr-identifier production to allow qualified
|
|
identifiers? Oneof members cannot be declared infix, but future module
|
|
scopes seem worth accessing :)</p>
|
|
|
|
<p>A simple example is:</p>
|
|
|
|
<pre class="example">
|
|
4 + 5 * 123 min 42
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-primary">Primary Expressions</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-primary ::= <a href="#expr-literal">expr-literal</a>
|
|
expr-primary ::= <a href="#expr-identifier">expr-identifier</a>
|
|
expr-primary ::= <a href="#expr-apply">expr-apply</a>
|
|
expr-primary ::= <a href="#expr-paren">expr-paren</a>
|
|
expr-primary ::= <a href="#expr-brace">expr-brace</a>
|
|
expr-primary ::= <a href="#expr-delayed-identifier">expr-delayed-identifier</a>
|
|
expr-primary ::= <a href="#expr-field">expr-field</a>
|
|
expr-primary ::= <a href="#expr-subscript">expr-subscript</a>
|
|
</pre>
|
|
|
|
<p>Primary expressions are the root of most simple expressions.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-literal">Simple Literals</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<div class="commentary">
|
|
In the short-term, this works, but this isn't satisfactory: The whole idea
|
|
of having 'int' be defined in the library is that we want the runtime to
|
|
define it. Having literals fixed to a specific type defeats this. This
|
|
also breaks things like 64-bit integers etc. There are a couple of ways to
|
|
handle this, such as C++'0x user defined literal suffixes, go's approach of
|
|
treating them as arbitrary precision integers that are resolved to a type
|
|
later, etc. We must return to this at some point.
|
|
</div>
|
|
|
|
<pre class="grammar">
|
|
expr-literal ::= <a href="#numeric_constant">numeric_constant</a>
|
|
</pre>
|
|
|
|
<p>The only literal currently supported are integer constants. These
|
|
have '__builtin_int32_type' type.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-identifier">Identifiers</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-identifier ::= <a href="#identifier">identifier</a>
|
|
</pre>
|
|
|
|
<p>A raw identifier refers to a value visible in the current <a
|
|
href="#sema_scope">scope</a>, and has the type of the declaration returned
|
|
by name lookup. Value declarations are installed with
|
|
<a href="#decl-var">var</a> and <a href="decl-func">func</a>
|
|
declarations.</p>
|
|
|
|
<pre class="grammar">
|
|
expr-identifier ::= <a href="#dollarident">dollarident</a>
|
|
</pre>
|
|
|
|
<p>A use of an implementation identifier whose name fits the "$[0-9]+" regular
|
|
expression is a reference to an anonymous closure argument that is formed when
|
|
the containing expression is <a href="#sema_anondecls">coerced into a closure
|
|
context</a>. All other implementation identifiers are invalid.</p>
|
|
|
|
<pre class="grammar">
|
|
expr-identifier ::= <a href="#type-identifier">type-identifier</a> '::' <a href="#identifier">identifier</a>
|
|
</pre>
|
|
|
|
<p>Qualified identifiers look up a member of a <a href="decl-oneof">oneof</a>
|
|
or <a href="decl-struct">struct</a> declaration. The first identifier is
|
|
looked up as a type name.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-delayed-identifier">Delayed Identifier Resolution</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-delayed-identifier ::= ':' <a href="#identifier">identifier</a>
|
|
</pre>
|
|
|
|
<p>Qualified reference waits for context sensitive type inference.
|
|
TODO: explain more, give examples. Some examples in the <a
|
|
href="#decl-oneof">oneof</a> section.</p>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-field">Field Expressions</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-field ::= <a href="#expr-primary">expr-primary</a> '.' <a href="#identifier">identifier</a>
|
|
expr-field ::= <a href="#expr-primary">expr-primary</a> '.' <a href="#dollarident">dollarident</a>
|
|
</pre>
|
|
|
|
<p>If the base expression is a tuple, then the identifier is either a named
|
|
field of the tuple, or it is the magic identifier "$[0-9]+" that
|
|
accesses the specified anonymous member of the tuple.</p>
|
|
|
|
<p>If the base expression is a oneof record with one element, which has
|
|
an associated type of tuple (which is true of all struct declarations that
|
|
have tuple body type), then the field access directly accesses the
|
|
underlying tuple.</p>
|
|
|
|
<p>No other field accesses are currently allowed.</p>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-subscript">Subscript Expressions</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-subscript ::= <a href="#expr-primary">expr-primary</a> '[' <a href="#expr-single">expr-single</a> ']'
|
|
</pre>
|
|
|
|
<p>FIXME: Array subscript should just be an overloaded operator like any
|
|
other. a[x] should just call a function subscript(a, x). This will allow
|
|
natural support for arrays and dictionaries, whose implementation of subscript
|
|
comes from the stdlib.</p>
|
|
|
|
<p>FIXME2: Two problems with this: 1) we need support for lvalue function
|
|
calls e.g. f(a, x) = 4, otherwise we can't use an array subscript as an
|
|
lvalue. 2) we want overloading in the long term to get non-array types.</p>
|
|
|
|
|
|
<!--
|
|
<p>On an array, the subscript expression accesses the specified element number
|
|
of the array, where the first element is numbered zero. The index expression
|
|
is required to convert to an integer type. All array accesses
|
|
are bounds checked and out-of-bounds array accesses are detected at either
|
|
compile time or run time.</p>
|
|
|
|
<p>TODO: Eventually support map operations etc.</p> -->
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-apply">Function Application</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-apply ::= expr-primary-fn <a href="#expr-primary">expr-primary</a>
|
|
expr-primary-fn ::= <a href="#expr-primary">expr-primary</a>
|
|
</pre>
|
|
|
|
<p>Juxtaposition of two expressions, when the former is of function type, is
|
|
application of a function to its argument. This production is ambiguous with
|
|
the top level <a href="#expr">expr</a> production, but this binds very
|
|
tightly.</p>
|
|
|
|
<p>A simple example:</p>
|
|
|
|
<pre class="example">
|
|
<i>// Application of an empty tuple to the function f.</i>
|
|
f ()
|
|
<i>// Application of 4 to the function f, both are equivalent.</i>
|
|
g 4
|
|
g (4)
|
|
|
|
<i>// Application of 4 to the function returned by h().</i>
|
|
h () 4
|
|
|
|
<i>// Application of "{}" to the function returned by the result of</i>
|
|
<i>// applying "(x)" to "if".</i>
|
|
if (x) {}
|
|
</pre>
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-paren">Parenthesized Expressions</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-paren ::= '(' ')'
|
|
expr-paren ::= '(' expr-paren-element (',' expr-paren-element)* ')'
|
|
expr-paren-element ::= ('.' <a href="#identifier">identifier</a> '=')? <a href="#expr">expr</a>
|
|
</pre>
|
|
|
|
<p>Parentheses expressions contain an (optionally empty) list of optionally
|
|
named values. Parentheses in an expression context denote one of two
|
|
things: 1) grouping parentheses, or 2) a tuple literal.</p>
|
|
|
|
<p>Grouping parentheses occur when there is exactly one value in the list and
|
|
that value does not have a name. In this case, the type of the parenthesis
|
|
expression is the type of the single value.</p>
|
|
|
|
<p>All other cases are tuple literals. The type of the expression is a tuple
|
|
type whose elements and order match that of the initializer. If there are
|
|
any named elements, those elements become names for the tuple type. A
|
|
parenthesis expression with no value has a type of the empty tuple.
|
|
</p>
|
|
|
|
<p>Some examples:</p>
|
|
|
|
<pre class="example">
|
|
<i>// Simple grouping parenthesis.</i>
|
|
var a = (4); <i>// Type = int</i>
|
|
var b = (4+a); <i>// Type = int</i>
|
|
|
|
<i>// Tuple literals.</i>
|
|
var c = () <i>// Type = ()</i>
|
|
var d = (4, 5) <i>// Type = (:int,:int)</i>
|
|
var e = (c, d) <i>// Type = ((), (:int, :int))</i>
|
|
|
|
var f = (.x = 4, .y = 5) <i>// Type = (x : int, y : int)</i>
|
|
var g = (4, .y = 5, 6) <i>// Type = (:int, y : int, :int)</i>
|
|
|
|
<i>// Named arguments to functions.</i>
|
|
func foo(a : int, b : int);
|
|
foo (.b = 4, .a = 1)
|
|
</pre>
|
|
|
|
|
|
<!-- ===================================================================== -->
|
|
<h3 id="expr-brace">Brace Literals</h3>
|
|
<!-- ===================================================================== -->
|
|
|
|
<pre class="grammar">
|
|
expr-brace ::= '{' expr-brace-item* '}'
|
|
expr-brace-item ::= ';'
|
|
expr-brace-item ::= <a href="#expr">expr</a>
|
|
expr-brace-item ::= <a href="#decl-var">decl-var</a>
|
|
</pre>
|
|
|
|
|
|
<p>FIXME: Need to kill off "the result of {} is the result of the last expr if
|
|
it doesn't have a ; at the end.</p>
|
|
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h2 id="sema">Language Semantics</h2>
|
|
<!-- ********************************************************************* -->
|
|
|
|
<h3 id="sema_scope">Scope</h3>
|
|
|
|
<p>identifier namespaces: tuple elements, types, values.
|
|
Scope within oneof decls.</p>
|
|
|
|
<h3 id="sema_conversions">Standard Conversions</h3>
|
|
<h3 id="sema_anondecls">Anonymous Argument Resolution</h3>
|
|
<h3 id="sema_context">Context Sensitive Type Resolution</h3>
|
|
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h2>Protocols</h2>
|
|
<!-- ********************************************************************* -->
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h2>Objects</h2>
|
|
<!-- ********************************************************************* -->
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h2>Generics</h2>
|
|
<!-- ********************************************************************* -->
|
|
|
|
|
|
<!-- ********************************************************************* -->
|
|
<h2 id="stdlib">Standard Library</h2>
|
|
<!-- ********************************************************************* -->
|
|
|
|
<h3 id="stdlib-alias">Standard Type Aliases</h3>
|
|
<h4 id="stdlib-void">void</h4>
|
|
|
|
<pre class="stdlib">
|
|
<i>// void is just a type alias for the empty tuple.</i>
|
|
typealias void : ()
|
|
</pre>
|
|
|
|
|
|
<h4 id="stdlib-int">int</h4>
|
|
<pre class="stdlib">
|
|
<i>// int is just a type alias for the 32-bit integer type.</i>
|
|
typealias int : __builtin_int32_type
|
|
</pre>
|
|
|
|
|
|
|
|
<!-- *********************************************************************** -->
|
|
<hr>
|
|
<address>
|
|
<a href="http://jigsaw.w3.org/css-validator/check/referer"><img
|
|
src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS"></a>
|
|
<a href="http://validator.w3.org/check/referer"><img
|
|
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
|
|
|
|
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
|
</address>
|
|
|
|
</body>
|
|
</html> |