blob: 131d3ce6f4c4cd7d0601ab6dd5704fd9b888e89c [file] [log] [blame]
:orphan:
===============================
Swift Language Reference Manual
===============================
.. contents::
Introduction
============
.. warning:: This document has not been kept up to date.
.. admonition:: 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 like this one to clarify what is normative and
what is discussion.
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.
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).
Basic Goals
-----------
.. admonition:: 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.
In no particular order, and not explained well:
* Support building great frameworks and applications, with a specific focus on
permitting rich and powerful APIs.
* Get the defaults right: this reduces the barrier to entry and increases the
odds that the right thing happens.
* Through our support for building great APIs, we aim to provide an expressive
and productive language that is fun to program in.
* 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.
* Provide really great tools, like an IDE, debugger, profiling, etc.
* 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.
* 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 disableable for people
who want ultimate performance in production builds.
* 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.
* Interoperate as transparently as possible with C, Objective-C, and C++
without having to write an equivalent of "extern C" for every referenced
definition.
* Great support for efficient by-value types.
* 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).
* Lots of other stuff too.
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.
Basic Approach
--------------
.. admonition:: 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.
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.
One major aspect that dovetails with expressivity, learnability, and focus on
API development is that much of the language is implemented in a :ref:`standard
library <langref.stdlib>` (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.
Phases of Translation
=====================
.. admonition:: 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.
Swift has a strict separation between its phases of translation, and the
compiler follows a conceptually simple design. The phases of translation
are:
* :ref:`Lexing <langref.lexical>`: A source file is broken into tokens
according to a (nearly, ``/**/`` comments can be nested) regular grammar.
* 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 module
(and eventually namespace) scope are bound.
* :ref:`Name Binding <langref.namebind>`: At this phase, references to
non-local types and values are bound, and :ref:`import directives
<langref.decl.import>` are both validated and searched. Name binding can
cause recursive compilation of modules that are referenced but not yet built.
* :ref:`Type Checking <langref.typecheck>`: During this phase all types are
resolved within value definitions, :ref:`function application
<langref.expr.call>` and <a href="#expr-infix">binary expressions</a> are
found and formed, and overloaded functions are resolved.
* Code Generation: The AST is converted the LLVM IR, optimizations are
performed, and machine code generated.
* Linking: runtime libraries and referenced modules are linked in.
FIXME: "import Swift" implicitly added as the last import in a source file.
.. _langref.lexical:
Lexical Structure
=================
.. admonition:: 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.
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.
.. _langref.lexical.whitespace:
Whitespace and Comments
-----------------------
.. admonition:: Commentary
Nested block comments are important because we don't have the nestable ``#if
0`` hack from C to rely on.
.. code-block:: none
whitespace ::= ' '
whitespace ::= '\n'
whitespace ::= '\r'
whitespace ::= '\t'
whitespace ::= '\0'
comment ::= //.*[\n\r]
comment ::= /* .... */
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 *spaced*)
from one which does not (called *unspaced*). A '``(``' or '``[``' at the
beginning of a file is spaced.
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.
.. _langref.lexical.reserved_punctuation:
Reserved Punctuation Tokens
---------------------------
.. admonition:: Commentary
Note that ``->`` is used for function types ``() -> Int``, not pointer
dereferencing.
.. code-block:: none
punctuation ::= '('
punctuation ::= ')'
punctuation ::= '{'
punctuation ::= '}'
punctuation ::= '['
punctuation ::= ']'
punctuation ::= '.'
punctuation ::= ','
punctuation ::= ';'
punctuation ::= ':'
punctuation ::= '='
punctuation ::= '->'
punctuation ::= '&' // unary prefix operator
These are all reserved punctuation that are lexed into tokens. Most other
non-alphanumeric characters are matched as :ref:`operators
<langref.lexical.operator>`. Unlike operators, these tokens are not
overloadable.
.. _langref.lexical.keyword:
Reserved Keywords
-----------------
.. admonition:: 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.
.. code-block:: none
// Declarations and Type Keywords
keyword ::= 'class'
keyword ::= 'destructor'
keyword ::= 'extension'
keyword ::= 'import'
keyword ::= 'init'
keyword ::= 'func'
keyword ::= 'enum'
keyword ::= 'protocol'
keyword ::= 'struct'
keyword ::= 'subscript'
keyword ::= 'Type'
keyword ::= 'typealias'
keyword ::= 'var'
keyword ::= 'where'
// Statements
keyword ::= 'break'
keyword ::= 'case'
keyword ::= 'continue'
keyword ::= 'default'
keyword ::= 'do'
keyword ::= 'else'
keyword ::= 'if'
keyword ::= 'in'
keyword ::= 'for'
keyword ::= 'return'
keyword ::= 'switch'
keyword ::= 'then'
keyword ::= 'while'
// Expressions
keyword ::= 'as'
keyword ::= 'is'
keyword ::= 'new'
keyword ::= 'super'
keyword ::= 'self'
keyword ::= 'Self'
keyword ::= 'type'
keyword ::= '__COLUMN__'
keyword ::= '__FILE__'
keyword ::= '__LINE__'
These are the builtin keywords. Keywords can still be used as names via
`escaped identifiers <langref.lexical.escapedident>`.
Contextual Keywords
-------------------
Swift uses several contextual keywords at various parts of the language.
Contextual keywords are not reserved words, meaning that they can be used as
identifiers. However, in certain contexts, they act as keywords, and are
represented as such in the grammar below. The following identifiers act as
contextual keywords within the language:
.. code-block:: none
get
infix
mutating
nonmutating
operator
override
postfix
prefix
set
.. _langref.lexical.integer_literal:
Integer Literals
----------------
.. code-block:: none
integer_literal ::= [0-9][0-9_]*
integer_literal ::= 0x[0-9a-fA-F][0-9a-fA-F_]*
integer_literal ::= 0o[0-7][0-7_]*
integer_literal ::= 0b[01][01_]*
Integer literal tokens represent simple integer values of unspecified
precision. They may be expressed in decimal, binary with the '``0b``' prefix,
octal with the '``0o``' prefix, or hexadecimal with the '``0x``' prefix.
Unlike C, a leading zero does not affect the base of the literal.
Integer literals may contain underscores at arbitrary positions after the first
digit. These underscores may be used for human readability and do not affect
the value of the literal.
::
789
0789
1000000
1_000_000
0b111_101_101
0o755
0b1111_1011
0xFB
.. _langref.lexical.floating_literal:
Floating Point Literals
-----------------------
.. admonition:: 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.
.. code-block:: none
floating_literal ::= [0-9][0-9_]*\.[0-9][0-9_]*
floating_literal ::= [0-9][0-9_]*\.[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*
floating_literal ::= [0-9][0-9_]*[eE][+-]?[0-9][0-9_]*
floating_literal ::= 0x[0-9A-Fa-f][0-9A-Fa-f_]*
(\.[0-9A-Fa-f][0-9A-Fa-f_]*)?[pP][+-]?[0-9][0-9_]*
Floating point literal tokens represent floating point values of unspecified
precision. Decimal and hexadecimal floating-point literals are supported.
The integer, fraction, and exponent of a floating point literal may each
contain underscores at arbitrary positions after their first digits. These
underscores may be used for human readability and do not affect the value of
the literal. Each part of the floating point literal must however start with a
digit; ``1._0`` would be a reference to the ``_0`` member of ``1``.
::
1.0
1000000.75
1_000_000.75
0x1.FFFFFFFFFFFFFp1022
0x1.FFFF_FFFF_FFFF_Fp1_022
.. _langref.lexical.character_literal:
Character Literals
------------------
.. code-block:: none
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]
``character_literal`` tokens represent a single character, and are surrounded
by single quotes.
The ASCII and Unicode character escapes:
.. code-block:: none
\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)
.. _langref.lexical.string_literal:
String Literals
---------------
.. admonition:: Commentary
FIXME: Forcing ``+`` to concatenate strings is somewhat gross, a proper protocol
would be better.
.. code-block:: none
string_literal ::= ["]([^"\\\n\r]|character_escape|escape_expr)*["]
escape_expr ::= [\]escape_expr_body
escape_expr_body ::= [(]escape_expr_body[)]
escape_expr_body ::= [^\n\r"()]
``string_literal`` tokens represent a string, and are surrounded by double
quotes. String literals cannot span multiple lines.
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.
In addition to these lexical rules, an interpolated expression must satisfy the
:ref:`expr <langref.expr>` 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.
::
// Simple string literal.
"Hello world!"
// Interpolated expressions.
"\(min)...\(max)" + "Result is \((4+i)*j)"
.. _langref.lexical.identifier:
Identifier Tokens
-----------------
.. code-block:: none
identifier ::= id-start id-continue*
// An identifier can start with an ASCII letter or underscore...
id-start ::= [A-Za-z_]
// or a Unicode alphanumeric character in the Basic Multilingual Plane...
// (excluding combining characters, which can't appear initially)
id-start ::= [\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-00BA]
id-start ::= [\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]
id-start ::= [\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]
id-start ::= [\u1E00-\u1FFF]
id-start ::= [\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]
id-start ::= [\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]
id-start ::= [\u2C00-\u2DFF\u2E80-\u2FFF]
id-start ::= [\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]
id-start ::= [\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-FE44]
id-start ::= [\uFE47-\uFFFD]
// or a non-private-use, valid code point outside of the BMP.
id-start ::= [\u10000-\u1FFFD\u20000-\u2FFFD\u30000-\u3FFFD\u40000-\u4FFFD]
id-start ::= [\u50000-\u5FFFD\u60000-\u6FFFD\u70000-\u7FFFD\u80000-\u8FFFD]
id-start ::= [\u90000-\u9FFFD\uA0000-\uAFFFD\uB0000-\uBFFFD\uC0000-\uCFFFD]
id-start ::= [\uD0000-\uDFFFD\uE0000-\uEFFFD]
// After the first code point, an identifier can contain ASCII digits...
id-continue ::= [0-9]
// and/or combining characters...
id-continue ::= [\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]
// in addition to the starting character set.
id-continue ::= id-start
identifier-or-any ::= identifier
identifier-or-any ::= '_'
The set of valid identifier characters is consistent with WG14 N1518,
"Recommendations for extended identifier characters for C and C++". This
roughly corresponds to the alphanumeric characters in the Basic Multilingual
Plane and all non-private-use code points outside of the BMP. It excludes
mathematical symbols, arrows, line and box drawing characters, and private-use
and invalid code points. An identifier cannot begin with one of the ASCII
digits '0' through '9' or with a combining character.
The Swift compiler does not normalize Unicode source code, and matches
identifiers by code points only. Source code must be normalized to a consistent
normalization form before being submitted to the compiler.
.. code-block:: none
// Valid identifiers
foo
_0
swift
vernissé
闪亮
מבריק
😄
// Invalid identifiers
☃ // Is a symbol
0cool // Starts with an ASCII digit
́foo // Starts with a combining character (U+0301)
 // Is a private-use character (U+F8FF)
.. _langref.lexical.operator:
Operator Tokens
---------------
.. code-block:: none
<a name="operator">operator</a> ::= [/=-+*%<>!&|^~]+
<a name="operator">operator</a> ::= \.+
<a href="#reserved_punctuation">Reserved for punctuation</a>: '.', '=', '->', and unary prefix '&'
<a href="#whitespace">Reserved for comments</a>: '//', '/*' and '*/'
operator-binary ::= operator
operator-prefix ::= operator
operator-postfix ::= operator
left-binder ::= [ \r\n\t\(\[\{,;:]
right-binder ::= [ \r\n\t\)\]\},;:]
<a name="any-identifier">any-identifier</a> ::= identifier | operator
``operator-binary``, ``operator-prefix``, and ``operator-postfix`` are
distinguished by immediate lexical context. An operator token is called
*left-bound* if it is immediately preceded by a character matching
``left-binder``. An operator token is called *right-bound* if it is
immediately followed by a character matching ``right-binder``. An operator
token is an ``operator-prefix`` if it is right-bound but not left-bound, an
``operator-postfix`` if it is left-bound but not right-bound, and an
``operator-binary`` in either of the other two cases.
As an exception, an operator immediately followed by a dot ('``.``') is only
considered right-bound if not already left-bound. This allows ``a!.prop`` to
be parsed as ``(a!).prop`` rather than as ``a ! .prop``.
The '``!``' operator is postfix if it is left-bound.
The '``?``' operator is postfix (and therefore not the ternary operator) if it
is left-bound. The sugar form for ``Optional`` types must be left-bound.
When parsing certain grammatical constructs that involve '``<``' and '``>``'
(such as <a href="#type-composition">protocol composition types</a>), an
``operator`` 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 ``operator`` or ``punctuation`` token that may itself be further
split. This rule allows us to parse nested constructs such as ``A<B<C>>``
without requiring spaces between the closing '``>``'s.
.. _langref.lexical.dollarident:
Implementation Identifier Token
-------------------------------
.. code-block:: none
dollarident ::= '$' id-continue+
Tokens that start with a ``$`` are separate class of identifier, which are
fixed purpose names that are defined by the implementation.
.. _langref.lexical.escapedident:
Escaped Identifiers
-------------------
.. code-block:: none
identifier ::= '`' id-start id-continue* '`'
An identifier that would normally be a `keyword <langref.lexical.keyword>` may
be used as an identifier by wrapping it in backticks '``\```', for example::
func `class`() { /* ... */ }
let `type` = 0.type
Any identifier may be escaped, though only identifiers that would normally be
parsed as keywords are required to be. The backtick-quoted string must still
form a valid, non-operator identifier::
let `0` = 0 // Error, "0" doesn't start with an alphanumeric
let `foo-bar` = 0 // Error, '-' isn't an identifier character
let `+` = 0 // Error, '+' is an operator
.. _langref.namebind:
Name Binding
============
.. _langref.typecheck:
Type Checking
=============
.. _langref.decl:
Declarations
============
...
.. _langref.decl.import:
Import Declarations
-------------------
...
.. _langref.decl.var:
``var`` Declarations
--------------------
.. code-block:: none
decl-var-head-kw ::= ('static' | 'class')? 'override'?
decl-var-head-kw ::= 'override'? ('static' | 'class')?
decl-var-head ::= attribute-list decl-var-head-kw? 'var'
decl-var ::= decl-var-head pattern initializer? (',' pattern initializer?)*
// 'get' is implicit in this syntax.
decl-var ::= decl-var-head identifier ':' type brace-item-list
decl-var ::= decl-var-head identifier ':' type '{' get-set '}'
decl-var ::= decl-var-head identifier ':' type initializer? '{' willset-didset '}'
// For use in protocols.
decl-var ::= decl-var-head identifier ':' type '{' get-set-kw '}'
get-set ::= get set?
get-set ::= set get
get ::= attribute-list ( 'mutating' | 'nonmutating' )? 'get' brace-item-list
set ::= attribute-list ( 'mutating' | 'nonmutating' )? 'set' set-name? brace-item-list
set-name ::= '(' identifier ')'
willset-didset ::= willset didset?
willset-didset ::= didset willset?
willset ::= attribute-list 'willSet' set-name? brace-item-list
didset ::= attribute-list 'didSet' set-name? brace-item-list
get-kw ::= attribute-list ( 'mutating' | 'nonmutating' )? 'get'
set-kw ::= attribute-list ( 'mutating' | 'nonmutating' )? 'set'
get-set-kw ::= get-kw set-kw?
get-set-kw ::= set-kw get-kw
``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 :ref:`fully-typed <langref.types.fully_typed>`,
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.
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.
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 ``T``). The getter function, whose
body is provided as part of the ``var-get`` clause, has type ``() -> T``.
Similarly, the setter function, whose body is part of the ``var-set`` clause
(if provided), has type ``(T) -> ()``.
If the ``var-set`` or ``willset`` clause contains a ``set-name`` clause, the
identifier of that clause is used as the name of the parameter to the setter or
the observing accessor. Otherwise, the parameter name is ``newValue``. Same
applies to ``didset`` clause, but the default parameter name is ``oldValue``.
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)?
Like all other declarations, ``var``\ s can optionally have a list of
:ref:`attributes <langref.decl.attribute_list>` applied to them.
The type of a variable must be :ref:`materializable
<langref.types.materializable>`. A variable is an lvalue unless it has a
``var-get`` clause but not ``var-set`` clause.
Here are some examples of ``var`` declarations:
::
// Simple examples.
var a = 4
var b: Int
var c: Int = 42
// This decodes the tuple return value into independently named parts
// and both 'val' and 'err' are in scope after this line.
var (val, err) = foo()
// Variable getter/setter
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
}
}
Note that ``get``, ``set``, ``willSet`` and ``didSet`` are context-sensitive
keywords.
``static`` keyword is allowed inside structs and enums, and extensions of
those.
``class`` keyword is allowed inside classes, class extensions, and
protocols.
.. admonition:: Ambiguity 1
The production for implicit ``get`` makes this grammar ambiguous. For example:
::
class A {
func get(_: () -> Int) {}
var a: Int {
get { return 0 } // Getter declaration or call to 'get' with a trailing closure?
}
// But if this was intended as a call to 'get' function, then we have a
// getter without a 'return' statement, so the code is invalid anyway.
}
We disambiguate towards ``get-set`` or ``willset-didset`` production if the
first token after ``{`` is the corresponding keyword, possibly preceded by
attributes. Thus, the following code is rejected because we are expecting
``{`` after ``set``:
::
class A {
var set: Foo
var a: Int {
set.doFoo()
return 0
}
}
.. admonition:: Ambiguity 2
The production with ``initializer`` and an accessor block is ambiguous. For
example:
::
func takeClosure(_: () -> Int) {}
struct A {
var willSet: Int
var a: Int = takeClosure {
willSet {} // A 'willSet' declaration or a call to 'takeClosure'?
}
}
We disambiguate towards ``willget-didset`` production if the first token
after ``{`` is the keyword ``willSet`` or ``didSet``, possibly preceded by
attributes.
.. admonition:: Rationale
Even though it is possible to do further checks and speculatively parse more,
it introduces unjustified complexity to cover (hopefully rare) corner cases.
In ambiguous cases users can always opt-out of the trailing closure syntax by
using explicit parentheses in the function call.
.. _langref.decl.func:
``func`` Declarations
---------------------
.. code-block:: none
// Keywords can be specified in any order.
decl-func-head-kw ::= ( 'static' | 'class' )? 'override'? ( 'mutating' | 'nonmutating' )?
decl-func ::= attribute-list decl-func-head-kw? 'func' any-identifier generic-params? func-signature brace-item-list?
``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.
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 ``()``. All of
the argument and return value names are injected into the <a
href="#namebind_scope">scope</a> of the function body.</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 ``self`` argument with these rules ... [todo]
``static`` and ``class`` 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 its implicit ``self`` argument is actually of
metatype type.
``static`` keyword is allowed inside structs and enums, and extensions of those.
``class`` keyword is allowed inside classes, class extensions, and protocols.
TODO: Func should be an immutable name binding, it should implicitly add an
attribute immutable when it exists.
TODO: Incoming arguments should be readonly, result should be implicitly
writeonly when we have these attributes.
.. _langref.decl.func.signature:
Function signatures
^^^^^^^^^^^^^^^^^^^
...
An argument name is a keyword argument if:
- It is an argument to an initializer, or
- It is an argument to a method after the first argument, or
- It is preceded by a back-tick (`), or
- Both a keyword argument name and an internal parameter name are specified.
.. _langref.decl.subscript:
``subscript`` Declarations
---------------------------
.. code-block:: none
subscript-head ::= attribute-list 'override'? 'subscript' pattern-tuple '->' type
decl-subscript ::= subscript-head '{' get-set '}'
// 'get' is implicit in this syntax.
decl-subscript ::= subscript-head brace-item-list
// For use in protocols.
decl-subscript ::= subscript-head '{' get-set-kw '}'
A subscript declaration provides support for <a href="#expr-subscript">
subscripting</a> an object of a particular type via a getter and (optional)
setter. Therefore, subscript declarations can only appear within a type
definition or extension.
The ``pattern-tuple`` of a subscript declaration provides the indices that
will be used in the subscript expression, e.g., the ``i`` in ``a[i]``. This
pattern must be fully-typed. The ``type`` following the arrow provides the
type of element being accessed, which must be materializable. Subscript
declarations can be overloaded, so long as either the ``pattern-tuple`` or
``type`` differs from other declarations.
The ``get-set`` clause specifies the getter and setter used for subscripting.
The getter is a function whose input is the type of the ``pattern-tuple`` and
whose result is the element type. Similarly, the setter is a function whose
result type is ``()`` and whose input is the type of the ``pattern-tuple``
with a parameter of the element type added to the end of the tuple; the name
of the parameter is the ``set-name``, if provided, or ``value`` otherwise.
::
// Simple bit vector with storage for 64 boolean values
struct BitVector64 {
var bits: Int64
// Allow subscripting with integer subscripts and a boolean result.
subscript (bit : Int) -> Bool {
// Getter tests the given bit
get {
return bits & (1 << bit)) != 0
}
// Setter sets the given bit to the provided value.
set {
var mask = 1 << bit
if value {
bits = bits | mask
} else {
bits = bits & ~mask
}
}
}
}
var vec = BitVector64()
vec[2] = true
if vec[3] {
print("third bit is set")
}
.. _langref.decl.attribute_list:
Attribute Lists
---------------
...
.. _langref.types:
Types
=====
...
.. _langref.types.fully_typed:
Fully-Typed Types
-----------------
...
.. _langref.types.materializable:
Materializable Types
--------------------
...
.. _langref.pattern:
Patterns
========
.. admonition:: Commentary
The pattern grammar mirrors the expression grammar, or to be more specific,
the grammar of literals. This is because the conceptual algorithm for
matching a value against a pattern is to try to find an assignment of values
to variables which makes the pattern equal the value. So every expression
form which can be used to build a value directly should generally have a
corresponding pattern form.
.. code-block:: none
pattern-atom ::= pattern-var
pattern-atom ::= pattern-any
pattern-atom ::= pattern-tuple
pattern-atom ::= pattern-is
pattern-atom ::= pattern-enum-element
pattern-atom ::= expr
pattern ::= pattern-atom
pattern ::= pattern-typed
A pattern represents the structure of a composite value. Parts of a value can
be extracted and bound to variables or compared against other values by
*pattern matching*. Among other places, pattern matching occurs on the
left-hand side of :ref:`var bindings <langref.decl.var>`, in the arguments of
:ref:`func declarations <langref.decl.func>`, and in the <tt>case</tt> labels
of :ref:`switch statements <langref.stmt.switch>`. Some examples::
var point = (1, 0, 0)
// Extract the elements of the "point" tuple and bind them to
// variables x, y, and z.
var (x, y, z) = point
print("x=\(x) y=\(y) z=\(z)")
// Dispatch on the elements of a tuple in a "switch" statement.
switch point {
case (0, 0, 0):
print("origin")
// The pattern "_" matches any value.
case (_, 0, 0):
print("on the x axis")
case (0, _, 0):
print("on the y axis")
case (0, 0, _):
print("on the z axis")
case (var x, var y, var z):
print("x=\(x) y=\(y) z=\(z)")
}
A pattern may be "irrefutable", meaning informally that it matches all values
of its type. Patterns in declarations, such as :ref:`var <langref.decl.var>`
and :ref:`func <langref.decl.func>`, are required to be irrefutable. Patterns
in the ``case`` labels of :ref:`switch statements <langref.stmt.switch>`,
however, are not.
The basic pattern grammar is a literal "atom" followed by an optional type
annotation. Type annotations are useful for documentation, as well as for
coercing a matched expression to a particular kind. They are also required
when patterns are used in a :ref:`function signature
<langref.decl.func.signature>`. Type annotations are currently not allowed in
switch statements.
A pattern has a type. A pattern may be "fully-typed", meaning informally that
its type is fully determined by the type annotations it contains. Some
patterns may also derive a type from their context, be it an enclosing pattern
or the way it is used; this set of situations is not yet fully determined.
.. _langref.pattern.typed:
Typed Patterns
--------------
.. code-block:: none
pattern-typed ::= pattern-atom ':' type
A type annotation constrains a pattern to have a specific type. An annotated
pattern is fully-typed if its annotation type is fully-typed. It is
irrefutable if and only if its subpattern is irrefutable.
Type annotations are currently not allowed in the ``case`` labels of ``switch``
statements; case patterns always get their type from the subject of the switch.
.. _langref.pattern.any:
Any Patterns
------------
.. code-block:: none
pattern-any ::= '_'
The symbol ``_`` in a pattern matches and ignores any value. It is irrefutable.
.. _langref.pattern.var:
'var' and 'let' Patterns
------------------------
.. code-block:: none
pattern-var ::= 'let' pattern
pattern-var ::= 'var' pattern
The ``var`` and ``let`` keywords within a pattern introduces variable bindings.
Any identifiers within the subpattern bind new named variables to their
matching values. 'var' bindings are mutable within the bound scope, and 'let'
bindings are immutable.
::
var point = (0, 0, 0)
switch point {
// Bind x, y, z to the elements of point.
case (var x, var y, var z):
print("x=\(x) y=\(y) z=\(z)")
}
switch point {
// Same. 'var' distributes to the identifiers in its subpattern.
case var (x, y, z):
print("x=\(x) y=\(y) z=\(z)")
}
Outside of a <tt>var</tt> pattern, an identifier behaves as an :ref:`expression
pattern <langref.pattern.expr>` referencing an existing definition.
::
var zero = 0
switch point {
// x and z are bound as new variables.
// zero is a reference to the existing 'zero' variable.
case (var x, zero, var z):
print("point off the y axis: x=\(x) z=\(z)")
default:
print("on the y axis")
}
The left-hand pattern of a :ref:`var declaration <langref.decl.var>` and the
argument pattern of a :ref:`func declaration <langref.decl.func>` are
implicitly inside a ``var`` pattern; identifiers in their patterns always bind
variables. Variable bindings are irrefutable.
The type of a bound variable must be :ref:`materializable
<langref.types.materializable>` unless it appears in a :ref:`func-signature
<langref.decl.func.signature>` and is directly of a ``inout``\ -annotated type.
.. _langref.pattern.tuple:
Tuple Patterns
--------------
.. code-block:: none
pattern-tuple ::= '(' pattern-tuple-body? ')'
pattern-tuple-body ::= pattern-tuple-element (',' pattern-tuple-body)* '...'?
pattern-tuple-element ::= pattern
A tuple pattern is a list of zero or more patterns. Within a :ref:`function
signature <langref.decl.func.signature>`, patterns may also be given a
default-value expression.
A tuple pattern is irrefutable if all its sub-patterns are irrefutable.
A tuple pattern is fully-typed if all its sub-patterns are fully-typed, in
which case its type is the corresponding tuple type, where each
``type-tuple-element`` has the type, label, and default value of the
corresponding ``pattern-tuple-element``. A ``pattern-tuple-element`` has a
label if it is a named pattern or a type annotation of a named pattern.
A tuple pattern whose body ends in ``'...'`` is a varargs tuple. The last
element of such a tuple must be a typed pattern, and the type of that pattern
is changed from ``T`` to ``[T]``. The corresponding tuple type for a varargs
tuple is a varargs tuple type.
As a special case, a tuple pattern with one element that has no label, has no
default value, and is not varargs is treated as a grouping parenthesis: it has
the type of its constituent pattern, not a tuple type.
.. _langref.pattern.is:
``is`` Patterns
---------------
.. code-block:: none
pattern-is ::= 'is' type
``is`` patterns perform a type check equivalent to the ``x is T`` <a
href="#expr-cast">cast operator</a>. The pattern matches if the runtime type of
a value is of the given type. ``is`` patterns are refutable and thus cannot
appear in declarations.
::
class B {}
class D1 : B {}
class D2 : B {}
var bs : [B] = [B(), D1(), D2()]
for b in bs {
switch b {
case is B:
print("B")
case is D1:
print("D1")
case is D2:
print("D2")
}
}
.. _langref.pattern.enum_element:
Enum Element Patterns
---------------------
.. code-block:: none
pattern-enum-element ::= type-identifier? '.' identifier pattern-tuple?
Enum element patterns match a value of <a href="#type-enum">enum type</a> if
the value matches the referenced ``case`` of the enum. If the ``case`` has a
type, the value of that type can be matched against an optional subpattern.
::
enum HTMLTag {
case A(href: String)
case IMG(src: String, alt: String)
case BR
}
switch tag {
case .BR:
print("<br>")
case .IMG(var src, var alt):
print("<img src=\"\(escape(src))\" alt=\"\(escape(alt))\">")
case .A(var href):
print("<a href=\"\(escape(href))\">")
}
Enum element patterns are refutable and thus cannot appear in declarations.
(They are currently considered refutable even if the enum contains only a
single ``case``.)
.. _langref.pattern.expr:
Expressions in Patterns
-----------------------
Patterns may include arbitrary expressions as subpatterns. Expression patterns
are refutable and thus cannot appear in declarations. An expression pattern is
compared to its corresponding value using the ``~=`` operator. The match
succeeds if ``expr ~= value`` evaluates to true. The standard library provides
a default implementation of ``~=`` using ``==`` equality; additionally, range
objects may be matched against integer and floating-point values. The ``~=``
operator may be overloaded like any function.
::
var point = (0, 0, 0)
switch point {
// Equality comparison.
case (0, 0, 0):
print("origin")
// Range comparison.
case (-10...10, -10...10, -10...10):
print("close to the origin")
default:
print("too far away")
}
// Define pattern matching of an integer value to a string expression.
func ~=(pattern:String, value:Int) -&gt; Bool {
return pattern == "\(value)"
}
// Now we can pattern-match strings to integers:
switch point {
case ("0", "0", "0"):
print("origin")
default:
print("not the origin")
}
The order of evaluation of expressions in patterns, including whether an
expression is evaluated at all, is unspecified. The compiler is free to
reorder or elide expression evaluation in patterns to improve dispatch
efficiency. Expressions in patterns therefore cannot be relied on for side
effects.
.. _langref.expr:
Expressions
===========
...
.. _langref.expr.call:
Function Application
--------------------
...
.. _langref.stmt:
Statements
==========
...
.. _langref.stmt.break:
``break`` Statement
-------------------
.. code-block:: none
stmt-return ::= 'break'
The 'break' statement transfers control out of the enclosing 'for' loop or
'while' loop.
.. _langref.stmt.continue:
``continue`` Statement
----------------------
.. code-block:: none
stmt-return ::= 'continue'
The 'continue' statement transfers control back to the start of the enclosing
'for' loop or 'while' loop.
...
.. _langref.stmt.switch:
``switch`` Statement
--------------------
.. code-block:: none
stmt-switch ::= 'switch' expr-basic '{' stmt-switch-case* '}'
stmt-switch-case ::= (case-label | default-label) brace-item+
stmt-switch-case ::= (case-label | default-label) ';'
case-label ::= 'case' pattern ('where' expr)? (',' pattern ('where' expr)?)* ':'
default-label ::= 'default' ':'
'switch' statements branch on the value of an expression by :ref:`pattern
matching <langref.pattern>`. The subject expression of the switch is evaluated
and tested against the patterns in its ``case`` labels in source order. When a
pattern is found that matches the value, control is transferred into the
matching ``case`` block. ``case`` labels may declare multiple patterns
separated by commas. Only a single ``case`` labels may precede a block of
code. Case labels may optionally specify a *guard* expression, introduced by
the ``where`` keyword; if present, control is transferred to the case only if
the subject value both matches the corresponding pattern and the guard
expression evaluates to true. Patterns are tested "as if" in source order; if
multiple cases can match a value, control is transferred only to the first
matching case. The actual execution order of pattern matching operations, and
in particular the evaluation order of :ref:`expression patterns
<langref.pattern.expr>`, is unspecified.
A switch may also contain a ``default`` block. If present, it receives control
if no cases match the subject value. The ``default`` block must appear at the
end of the switch and must be the only label for its block. ``default`` is
equivalent to a final ``case _`` pattern. Switches are required to be
exhaustive; either the contained case patterns must cover every possible value
of the subject's type, or else an explicit ``default`` block must be specified
to handle uncovered cases.
Every case and default block has its own scope. Declarations within a case or
default block are only visible within that block. Case patterns may bind
variables using the :ref:`var keyword <langref.pattern.var>`; those variables
are also scoped into the corresponding case block, and may be referenced in the
``where`` guard for the case label. However, if a case block matches multiple
patterns, none of those patterns may contain variable bindings.
Control does not implicitly 'fall through' from one case block to the next.
:ref:`fallthrough statements <langref.stmt.fallthrough>` may explicitly
transfer control among case blocks. :ref:`break <langref.stmt.break>` and
:ref:`continue <langref.stmt.continue>` within a switch will break or continue
out of an enclosing 'while' or 'for' loop, not out of the 'switch' itself.
At least one ``brace-item`` is required in every case or default block. It is
allowed to be a no-op. Semicolon can be used as a single no-op statement in
otherwise empty cases in switch statements.
::
func classifyPoint(_ point: (Int, Int)) {
switch point {
case (0, 0):
print("origin")
case (_, 0):
print("on the x axis")
case (0, _):
print("on the y axis")
case (var x, var y) where x == y:
print("on the y = x diagonal")
case (var x, var y) where -x == y:
print("on the y = -x diagonal")
case (var x, var y):
print("length \(sqrt(x*x + y*y))")
}
}
switch x {
case 1, 2, 3:
print("x is 1, 2 or 3")
default:
;
}
.. _langref.stmt.fallthrough:
``fallthrough`` Statement
-------------------------
.. code-block:: none
stmt-fallthrough ::= 'fallthrough'
``fallthrough`` transfers control from a ``case`` block of a :ref:`switch
statement <langref.stmt.switch>` to the next ``case`` or ``default`` block
within the switch. It may only appear inside a ``switch``. ``fallthrough``
cannot be used in the final block of a ``switch``. It also cannot transfer
control into a ``case`` block whose pattern contains :ref:`var bindings
<langref.pattern.var>`.
.. _langref.stdlib:
Standard Library
================
.. admonition:: Commentary
It would be really great to have literate swift code someday, that way this
could be generated directly from the code. This would also be powerful for
Swift library developers to be able to depend on being available and
standardized.
This describes some of the standard swift code as it is being built up. Since
Swift is designed to give power to the library developers, much of what is
normally considered the "language" is actually just implemented in the
library.
All of this code is published by the '``swift``' module, which is implicitly
imported into each source file, unless some sort of pragma in the code
(attribute on an import?) is used to change or disable this behavior.
.. _langref.stdlib.builtin:
Builtin Module
==============
In the initial Swift implementation, a module named ``Builtin`` is imported
into every file. Its declarations can only be found by <a href="#expr-dot">dot
syntax</a>. It provides access to a small number of primitive representation
types and operations defined over them that map directly to LLVM IR.
The existence of and details of this module are a private implementation detail
used by our implementation of the standard library. Swift code outside the
standard library should not be aware of this library, and an independent
implementation of the swift standard library should be allowed to be
implemented without the builtin library if it desires.
For reference below, the description of the standard library uses the
"``Builtin.``" namespace to refer to this module, but independent
implementations could use another implementation if they so desire.
.. _langref.stdlib.simple-types:
Simple Types
------------
Void
^^^^
::
// Void is just a type alias for the empty tuple.
typealias Void = ()
.. _langref.stdlib.int:
Int, Int8, Int16, Int32, Int64
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. admonition:: Commentary
Having a single standardized integer type that can be used by default
everywhere is important. One advantage Swift has is that by the time it is
in widespread use, 64-bit architectures will be pervasive, and the LLVM
optimizer should grow to be good at shrinking 64-bit integers to 32-bit in
many cases for those 32-bit architectures that persist.
::
// Fixed size types are simple structs of the right size.
struct Int8 { value : Builtin.Int8 }
struct Int16 { value : Builtin.Int16 }
struct Int32 { value : Builtin.Int32 }
struct Int64 { value : Builtin.Int64 }
struct Int128 { value : Builtin.Int128 }
// Int is just an alias for the 64-bit integer type.
typealias Int = Int64
.. _langref.stdlib.float:
Int, Int8, Int16, Int32, Int64
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
struct Float { value : Builtin.FPIEEE32 }
struct Double { value : Builtin.FPIEEE64 }
.. _langref.stdlib.bool:
Bool, true, false
^^^^^^^^^^^^^^^^^
::
// Bool is a simple enum.
enum Bool {
true, false
}
// Allow true and false to be used unqualified.
var true = Bool.true
var false = Bool.false
.. _langref.stdlib.oper:
Arithmetic and Logical Operations
---------------------------------
.. _langref.stdlib.oper.arithmetic:
Arithmetic Operators
^^^^^^^^^^^^^^^^^^^^
::
func * (lhs: Int, rhs: Int) -> Int
func / (lhs: Int, rhs: Int) -> Int
func % (lhs: Int, rhs: Int) -> Int
func + (lhs: Int, rhs: Int) -> Int
func - (lhs: Int, rhs: Int) -> Int
.. _langref.stdlib.oper.comparison:
Relational and Equality Operators
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
func < (lhs : Int, rhs : Int) -> Bool
func > (lhs : Int, rhs : Int) -> Bool
func <= (lhs : Int, rhs : Int) -> Bool
func >= (lhs : Int, rhs : Int) -> Bool
func == (lhs : Int, rhs : Int) -> Bool
func != (lhs : Int, rhs : Int) -> Bool
.. _langref.stdlib.oper.short-circuit-logical:
Short Circuiting Logical Operators
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
func && (lhs: Bool, rhs: () -> Bool) -> Bool
func || (lhs: Bool, rhs: () -> Bool) -> Bool
Swift has a simplified precedence levels when compared with C. From highest to
lowest:
::
"exponentiative:" <<, >>
"multiplicative:" *, /, %, &
"additive:" +, -, |, ^
"comparative:" ==, !=, <, <=, >=, >
"conjunctive:" &&
"disjunctive:" ||