# Functions ## Table of contents - [Overview](#overview) - [Function definitions](#function-definitions) - [Return clause](#return-clause) - [`return` statements](#return-statements) - [Function declarations](#function-declarations) - [Function calls](#function-calls) - [Functions in other features](#functions-in-other-features) - [Alternatives considered](#alternatives-considered) - [References](#references) ## Overview > **TODO:** Update this document to reflect the introduction of function values, > function types, and the `Call` interface in > [p2875: Functions, function types, and function calls](/proposals/p2875.md). > **TODO:** Update this document to reflect the changes to named functions in > [p3848: Lambdas](/proposals/p3848.md). Functions are the core building block for applications. Carbon's basic function syntax is: - _parameter_: _identifier_ `:` _expression_ - _parameter-list_: _[ parameter_ `,` _parameter_ `,` _... ]_ - _return-clause_: _[_ `->` _< expression |_ `auto` _> ]_ - _signature_: `fn` _identifier_ `(` _parameter-list_ `)` _return-clause_ - _function-definition_: _signature_ `{` _statements_ `}` - _function-declaration_: _signature_ `;` - _function-call_: _identifier_ `(` _[ expression_ `,` _expression_ `,` _... ]_ `)` A function with only a signature and no body is a function declaration, or forward declaration. When the body is a present, it's a function definition. The body introduces nested scopes which may contain local variable declarations. ## Function definitions A basic function definition may look like: ```carbon fn Add(a: i64, b: i64) -> i64 { return a + b; } ``` This declares a function called `Add` which accepts two `i64` parameters, the first called `a` and the second called `b`, and returns an `i64` result. It returns the result of adding the two arguments. C++ might declare the same thing: ```cpp std::int64_t Add(std::int64_t a, std::int64_t b) { return a + b; } // Or with trailing return type syntax: auto Add(std::int64_t a, std::int64_t b) -> std::int64_t { return a + b; } ``` ### Return clause The return clause of a function specifies the return type using one of three possible syntaxes: - `->` followed by an _expression_, such as `i64`, directly states the return type. This expression will be evaluated at compile-time, so must be valid in that context. - For example, `fn ToString(val: i64) -> String;` has a return type of `String`. - `->` followed by the `auto` keyword indicates that [type inference](type_inference.md) should be used to determine the return type. - For example, `fn Echo(val: i64) -> auto { return val; }` will have a return type of `i64` through type inference. - Declarations must have a known return type, so `auto` is not valid. - The function must have precisely one `return` statement. That `return` statement's expression will then be used for type inference. - Omission indicates that the return type is the empty tuple, `()`. - For example, `fn Sleep(seconds: i64);` is similar to `fn Sleep(seconds: i64) -> ();`. - `()` is similar to a `void` return type in C++. > **TODO:** Update this section to cover return forms, as discussed > [here](values.md#function-calls-and-returns). ### `return` statements The [`return` statement](control_flow/return.md) is essential to function control flow. It ends the flow of the function and returns execution to the caller. When the [return clause](#return-clause) is omitted, the `return` statement has no expression argument, and function control flow implicitly ends after the last statement in the function's body as if `return;` were present. When the return clause is provided, including when it is `-> ()`, the `return` statement must have an expression that is convertible to the return type, and a `return` statement must be used to end control flow of the function. > **TODO:** Update this section to cover the requirements on the form of the > expression. ## Function declarations Functions may be declared separate from the definition by providing only a signature, with no body. This provides an API which may be called. For example: ```carbon // Declaration: fn Add(a: i64, b: i64) -> i64; // Definition: fn Add(a: i64, b: i64) -> i64 { return a + b; } ``` The corresponding definition may be provided later in the same file or, when the declaration is in an [API file of a library](code_and_name_organization/#libraries), in an implementation file of the same library. The signature of a function declaration must match the corresponding definition. This includes the [return clause](#return-clause); even though an omitted return type has equivalent behavior to `-> ()`, the presence or omission must match. ## Function calls Function calls use a function's identifier to pass multiple expression arguments corresponding to the function signature's parameters. For example: ```carbon fn Add(a: i64, b: i64) -> i64 { return a + b; } fn Run() { Add(1, 2); } ``` Here, `Add(1, 2)` is a function call expression. `Add` refers to the function definition's identifier. The parenthesized arguments `1` and `2` are passed to the `a` and `b` parameters of `Add`. ## Functions in other features Other designs build upon basic function syntax to add advanced features: - [Generic functions](generics/overview.md#generic-functions) adds support for deduced parameters and compile-time parameters. - [Class member functions](classes.md#member-functions) adds support for methods and class functions. ## Alternatives considered - [Function keyword](/proposals/p0438.md#function-keyword) - [Only allow `auto` return types if parameters are compile-time](/proposals/p0826.md#only-allow-auto-return-types-if-parameters-are-generic) - [Provide alternate function syntax for concise return type inference](/proposals/p0826.md#provide-alternate-function-syntax-for-concise-return-type-inference) - [Allow separate declaration and definition](/proposals/p0826.md#allow-separate-declaration-and-definition) ## References - Proposal [#438: Add statement syntax for function declarations](https://github.com/carbon-language/carbon-lang/pull/438) - Proposal [#826: Function return type inference](https://github.com/carbon-language/carbon-lang/pull/826)