Skip to content

Commit a2728f8

Browse files
jonmeowchandlerczygoloid
authored
Updating function and variable docs (carbon-language#1017)
I was doing this for carbon-language#851 initially, but I think carbon-language#438 and carbon-language#826 hadn't made it in (possibly intentionally due to carbon-language#851? I don't recall). Co-authored-by: Chandler Carruth <[email protected]> Co-authored-by: Richard Smith <[email protected]>
1 parent 6c3e1f6 commit a2728f8

File tree

4 files changed

+212
-48
lines changed

4 files changed

+212
-48
lines changed

Diff for: docs/design/README.md

+8-10
Original file line numberDiff line numberDiff line change
@@ -301,23 +301,21 @@ Some common expressions in Carbon include:
301301
### Functions
302302

303303
> References: [Functions](functions.md)
304-
>
305-
> **TODO:** References need to be evolved.
306304
307305
Functions are the core unit of behavior. For example:
308306

309307
```carbon
310-
fn Sum(a: Int, b: Int) -> Int;
308+
fn Add(a: i64, b: i64) -> i64;
311309
```
312310

313311
Breaking this apart:
314312

315313
- `fn` is the keyword used to indicate a function.
316-
- Its name is `Sum`.
317-
- It accepts two `Int` parameters, `a` and `b`.
318-
- It returns an `Int` result.
314+
- Its name is `Add`.
315+
- It accepts two `i64` parameters, `a` and `b`.
316+
- It returns an `i64` result.
319317

320-
You would call this function like `Sum(1, 2)`.
318+
You would call this function like `Add(1, 2)`.
321319

322320
### Blocks and statements
323321

@@ -354,16 +352,16 @@ work similarly to function parameters.
354352
For example:
355353

356354
```carbon
357-
fn Foo() {
358-
var x: Int = 42;
355+
fn DoSomething() {
356+
var x: i64 = 42;
359357
}
360358
```
361359

362360
Breaking this apart:
363361

364362
- `var` is the keyword used to indicate a variable.
365363
- Its name is `x`.
366-
- Its type is `Int`.
364+
- Its type is `i64`.
367365
- It is initialized with the value `42`.
368366

369367
### Lifetime and move semantics

Diff for: docs/design/functions.md

+143-36
Original file line numberDiff line numberDiff line change
@@ -10,54 +10,161 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
1010

1111
## Table of contents
1212

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)
1522

1623
<!-- tocstop -->
1724

18-
## TODO
25+
## Overview
1926

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:
2429

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+
]_ `)`
2638

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.
3142

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+
}
3251
```
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+
}
3468
```
3569
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
39108
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+
}
40120
```
41-
std::int64_t Sum(std::int64_t a, std::int64_t b);
42121

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+
}
45143
```
46144

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)

Diff for: docs/design/type_inference.md

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Type inference
2+
3+
<!--
4+
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
5+
Exceptions. See /LICENSE for license information.
6+
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
-->
8+
9+
<!-- toc -->
10+
11+
## Table of contents
12+
13+
- [Overview](#overview)
14+
- [Open questions](#open-questions)
15+
- [Inferring a variable type from literals](#inferring-a-variable-type-from-literals)
16+
- [Alternatives considered](#alternatives-considered)
17+
- [References](#references)
18+
19+
<!-- tocstop -->
20+
21+
## Overview
22+
23+
[Type inference](https://en.wikipedia.org/wiki/Type_inference) occurs in Carbon
24+
when the `auto` keyword is used. This may occur in
25+
[variable declarations](variables.md) or [function declarations](functions.md).
26+
27+
At present, type inference is very simple: given the expression which generates
28+
the value to be used for type inference, the inferred type is the precise type
29+
of that expression. For example, the inferred type for `auto` in
30+
`fn Foo(x: i64) -> auto { return x; }` is `i64`.
31+
32+
Type inference is currently supported for [function return types](functions.md)
33+
and [declared variable types](variables.md).
34+
35+
## Open questions
36+
37+
### Inferring a variable type from literals
38+
39+
Using the type on the right side for `var y: auto = 1` currently results in a
40+
constant `IntLiteral(1)` value, whereas most languages would suggest a variable
41+
integer type, such as `i64`. Carbon might also make it an error. Although type
42+
inference currently only addresses `auto` for variables and function return
43+
types, this is something that will be considered as part of type inference in
44+
general, because it also affects generics, templates, lambdas, and return types.
45+
46+
## Alternatives considered
47+
48+
- [Use `_` instead of `auto`](/proposals/p0851.md#use-_-instead-of-auto)
49+
50+
## References
51+
52+
- Proposal
53+
[#851: auto keyword for vars](https://github.com/carbon-language/carbon-lang/pull/851)

Diff for: docs/design/variables.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2222

2323
Carbon's local variable syntax is:
2424

25-
> `var` _identifier_`:` _type_ _[_ `=` _value_ _]_`;`
25+
- `var` _identifier_`:` _< expression |_ `auto` _> [_ `=` _value ]_`;`
2626

2727
Blocks introduce nested scopes and can contain local variable declarations that
2828
work similarly to function parameters.
@@ -31,7 +31,7 @@ For example:
3131

3232
```
3333
fn Foo() {
34-
var x: Int = 42;
34+
var x: i32 = 42;
3535
}
3636
```
3737

@@ -40,6 +40,9 @@ type `Int` and is initialized with the value `42`. These variable declarations
4040
(and function declarations) have a lot more power than what we're covering just
4141
yet, but this gives you the basic idea.
4242

43+
If `auto` is used in place of the type, [type inference](type_inference.md) is
44+
used to automatically determine the variable's type.
45+
4346
While there can be global constants, there are no global variables.
4447

4548
## Notes
@@ -61,10 +64,13 @@ discover that their convenience outweighs any improvements afforded.
6164
- [Colon between type and identifier](/proposals/p0339.md#colon-between-type-and-identifier)
6265
- [Type elision](/proposals/p0339.md#type-elision)
6366
- [Type ordering](/proposals/p0618.md#type-ordering)
67+
- [Elide the type instead of using `auto`](/proposals/p0851.md#elide-the-type-instead-of-using-auto)
6468

6569
## References
6670

6771
- Proposal
6872
[#339: `var` statement](https://github.com/carbon-language/carbon-lang/pull/339)
6973
- Proposal
7074
[#618: `var` ordering](https://github.com/carbon-language/carbon-lang/pull/618)
75+
- Proposal
76+
[#851: auto keyword for vars](https://github.com/carbon-language/carbon-lang/pull/851)

0 commit comments

Comments
 (0)