@@ -10,54 +10,161 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10
10
11
11
## Table of contents
12
12
13
- - [ TODO] ( #todo )
14
- - [ Basic functions] ( #basic-functions )
13
+ - [ Overview] ( #overview )
14
+ - [ Function definitions] ( #function-definitions )
15
+ - [ Return clause] ( #return-clause )
16
+ - [ ` return ` statements] ( #return-statements )
17
+ - [ Function declarations] ( #function-declarations )
18
+ - [ Function calls] ( #function-calls )
19
+ - [ Functions in other features] ( #functions-in-other-features )
20
+ - [ Alternatives considered] ( #alternatives-considered )
21
+ - [ References] ( #references )
15
22
16
23
<!-- tocstop -->
17
24
18
- ## TODO
25
+ ## Overview
19
26
20
- This is a skeletal design, added to support [ the overview] ( README.md ) . It should
21
- not be treated as accepted by the core team; rather, it is a placeholder until
22
- we have more time to examine this detail. Please feel welcome to rewrite and
23
- update as appropriate.
27
+ Functions are the core building block for applications. Carbon's basic function
28
+ syntax is:
24
29
25
- ## Basic functions
30
+ - _ parameter_ : _ identifier_ ` : ` _ expression_
31
+ - _ parameter-list_ : _ [ parameter_ ` , ` _ parameter_ ` , ` _ ... ] _
32
+ - _ return-clause_ : _ [ _ ` -> ` _ < expression |_ ` auto ` _ > ] _
33
+ - _ signature_ : ` fn ` _ identifier_ ` ( ` _ parameter-list_ ` ) ` _ return-clause_
34
+ - _ function-definition_ : _ signature_ ` { ` _ statements_ ` } `
35
+ - _ function-declaration_ : _ signature_ ` ; `
36
+ - _ function-call_ : _ identifier_ ` ( ` _ [ expression_ ` , ` _ expression_ ` , ` _ ...
37
+ ] _ ` ) `
26
38
27
- Programs written in Carbon, much like those written in other languages, are
28
- primarily divided up into "functions" (or "procedures", "subroutines", or
29
- "subprograms"). These are the core unit of behavior for the programming
30
- language. Let's look at a simple example to understand how these work:
39
+ A function with only a signature and no body is a function declaration, or
40
+ forward declaration. When the body is a present, it's a function definition. The
41
+ body introduces nested scopes which may contain local variable declarations.
31
42
43
+ ## Function definitions
44
+
45
+ A basic function definition may look like:
46
+
47
+ ``` carbon
48
+ fn Add(a: i64, b: i64) -> i64 {
49
+ return a + b;
50
+ }
32
51
```
33
- fn Sum(a: Int, b: Int) -> Int;
52
+
53
+ This declares a function called ` Add ` which accepts two ` i64 ` parameters, the
54
+ first called ` a ` and the second called ` b ` , and returns an ` i64 ` result. It
55
+ returns the result of adding the two arguments.
56
+
57
+ C++ might declare the same thing:
58
+
59
+ ``` cpp
60
+ std::int64_t Add (std::int64_t a, std::int64_t b) {
61
+ return a + b;
62
+ }
63
+
64
+ // Or with trailing return type syntax:
65
+ auto Add(std::int64_t a, std::int64_t b) -> std::int64_t {
66
+ return a + b;
67
+ }
34
68
```
35
69
36
- This declares a function called ` Sum ` which accepts two ` Int ` parameters, the
37
- first called ` a ` and the second called ` b ` , and returns an ` Int ` result. C++
38
- might declare the same thing:
70
+ ### Return clause
71
+
72
+ The return clause of a function specifies the return type using one of three
73
+ possible syntaxes:
74
+
75
+ - `->` followed by an _expression_, such as `i64`, directly states the return
76
+ type. This expression will be evaluated at compile-time, so must be valid in
77
+ that context.
78
+ - For example, `fn ToString(val: i64) -> String;` has a return type of
79
+ `String`.
80
+ - `->` followed by the `auto` keyword indicates that
81
+ [type inference](type_inference.md) should be used to determine the return
82
+ type.
83
+ - For example, `fn Echo(val: i64) -> auto { return val; }` will have a
84
+ return type of `i64` through type inference.
85
+ - Declarations must have a known return type, so `auto` is not valid.
86
+ - The function must have precisely one `return` statement. That `return`
87
+ statement's expression will then be used for type inference.
88
+ - Omission indicates that the return type is the empty tuple, `()`.
89
+ - For example, `fn Sleep(seconds: i64);` is similar to
90
+ `fn Sleep(seconds: i64) -> ();`.
91
+ - `()` is similar to a `void` return type in C++.
92
+
93
+ ### `return` statements
94
+
95
+ The [`return` statement](control_flow/return.md) is essential to function
96
+ control flow. It ends the flow of the function and returns execution to the
97
+ caller.
98
+
99
+ When the [return clause](#return-clause) is omitted, the `return` statement has
100
+ no expression argument, and function control flow implicitly ends after the last
101
+ statement in the function's body as if `return;` were present.
102
+
103
+ When the return clause is provided, including when it is `-> ()`, the `return`
104
+ statement must have an expression that is convertible to the return type, and a
105
+ `return` statement must be used to end control flow of the function.
106
+
107
+ ## Function declarations
39
108
109
+ Functions may be declared separate from the definition by providing only a
110
+ signature, with no body. This provides an API which may be called. For example:
111
+
112
+ ```carbon
113
+ // Declaration:
114
+ fn Add(a: i64, b: i64) -> i64;
115
+
116
+ // Definition:
117
+ fn Add(a: i64, b: i64) -> i64 {
118
+ return a + b;
119
+ }
40
120
```
41
- std::int64_t Sum(std::int64_t a, std::int64_t b);
42
121
43
- // Or with trailing return type syntax:
44
- auto Sum(std::int64_t a, std::int64_t b) -> std::int64_t;
122
+ The corresponding definition may be provided later in the same file or, when the
123
+ declaration is in an
124
+ [ ` api ` file of a library] ( code_and_name_organization/#libraries ) , in the ` impl `
125
+ file of the same library. The signature of a function declaration must match the
126
+ corresponding definition. This includes the [ return clause] ( #return-clause ) ;
127
+ even though an omitted return type has equivalent behavior to ` -> () ` , the
128
+ presence or omission must match.
129
+
130
+ ## Function calls
131
+
132
+ Function calls use a function's identifier to pass multiple expression arguments
133
+ corresponding to the function signature's parameters. For example:
134
+
135
+ ``` carbon
136
+ fn Add(a: i64, b: i64) -> i64 {
137
+ return a + b;
138
+ }
139
+
140
+ fn Main() {
141
+ Add(1, 2);
142
+ }
45
143
```
46
144
47
- Let's look at how some specific parts of this work. The function declaration is
48
- introduced with a keyword ` fn ` followed by the name of the function ` Sum ` . This
49
- declares that name in the surrounding scope and opens up a new scope for this
50
- function. We declare the first parameter as ` Int a ` . The ` Int ` part is an
51
- expression (here referring to a constant) that computes the type of the
52
- parameter. The ` : ` marks the end of the type expression and introduces the
53
- identifier for the parameter, ` a ` . The parameter names are introduced into the
54
- function's scope and can be referenced immediately after they are introduced.
55
- The return type is indicated with ` -> Int ` , where again ` Int ` is just an
56
- expression computing the desired type. The return type can be completely omitted
57
- in the case of functions which do not return a value.
58
-
59
- Calling functions involves a new form of expression: ` Sum(1, 2) ` for example.
60
- The first part, ` Sum ` , is an expression referring to the name of the function.
61
- The second part, ` (1, 2) ` is a parenthesized list of arguments to the function.
62
- The juxtaposition of one expression with parentheses forms the core of a call
63
- expression, similar to a postfix operator.
145
+ Here, ` Add(1, 2) ` is a function call expression. ` Add ` refers to the function
146
+ definition's identifier. The parenthesized arguments ` 1 ` and ` 2 ` are passed to
147
+ the ` a ` and ` b ` parameters of ` Add ` .
148
+
149
+ ## Functions in other features
150
+
151
+ Other designs build upon basic function syntax to add advanced features:
152
+
153
+ - [ Generic functions] ( generics/overview.md#generic-functions ) adds support for
154
+ deduced parameters and generic type parameters.
155
+ - [ Class member functions] ( classes.md#member-functions ) adds support for
156
+ methods and class functions.
157
+
158
+ ## Alternatives considered
159
+
160
+ - [ Function keyword] ( /proposals/p0438.md#function-keyword )
161
+ - [ Only allow ` auto ` return types if parameters are generic] ( /proposals/p0826.md#only-allow-auto-return-types-if-parameters-are-generic )
162
+ - [ Provide alternate function syntax for concise return type inference] ( /proposals/p0826.md#provide-alternate-function-syntax-for-concise-return-type-inference )
163
+ - [ Allow separate declaration and definition] ( /proposals/p0826.md#allow-separate-declaration-and-definition )
164
+
165
+ ## References
166
+
167
+ - Proposal
168
+ [ #438 : Add statement syntax for function declarations] ( https://github.com/carbon-language/carbon-lang/pull/438 )
169
+ - Proposal
170
+ [ #826 : Function return type inference] ( https://github.com/carbon-language/carbon-lang/pull/826 )
0 commit comments