Skip to content

Commit

Permalink
Additional reviewer comments addressed
Browse files Browse the repository at this point in the history
  • Loading branch information
CJ-Johnson committed Apr 16, 2024
1 parent f7d461b commit 4b408a2
Showing 1 changed file with 38 additions and 19 deletions.
57 changes: 38 additions & 19 deletions proposals/p3848.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,23 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

- [Abstract](#abstract)
- [Syntax Overview](#syntax-overview)
- [Succinctly](#succinctly)
- [Alternative Considered: Terse vs Elaborated](#alternative-considered-terse-vs-elaborated)
- [Introducer](#introducer)
- [Alternative Considered: Sigil](#alternative-considered-sigil)
- [Positional Parameters](#positional-parameters)
- [Positional Parameter Restrictions](#positional-parameter-restrictions)
- [Alternative Considered: Additional Restriction](#alternative-considered-additional-restriction)
- [Function Captures](#function-captures)
- [Capture Modes](#capture-modes)
- [Alternative Considered: By-Value Captures](#alternative-considered-by-value-captures)
- [Default Capture Mode](#default-capture-mode)
- [Alternative Considered: Middle vs Beginning](#alternative-considered-middle-vs-beginning)
- [Function Fields](#function-fields)
- [Alternative Considered: No Function Fields](#alternative-considered-no-function-fields)
- [Copy Semantics](#copy-semantics)
- [Self and Recursion](#self-and-recursion)
- [Alternative Considered: Recursive Self](#alternative-considered-recursive-self)
- [Rationale](#rationale)

<!-- tocstop -->
Expand Down Expand Up @@ -126,7 +134,7 @@ fn Foo() {
}
```

<h3 id="syntax-overview-succinctly">Succinctly</h3>
### Succinctly

Function definitions have one of the following syntactic forms (where items in
square brackets are optional and independent):
Expand All @@ -149,8 +157,8 @@ omitted, it is equivalent to `[]`.
The presence of _name_ determines whether this is a function declaration or a
lambda expression.

The presence of tuple-pattern determines whether the function body uses named or
positional parameters.
The presence of _tuple-pattern_ determines whether the function body uses named
or positional parameters.

The presence of "`->` _return-type_" determines whether the function body can
(and must) return a value.
Expand Down Expand Up @@ -231,7 +239,7 @@ fn G[B, C](D) { E3; }
fn G[B, C](D) -> F { E4; }
```

<h3 id="syntax-overview-alternative-considered">Alternative Considered</h3>
### Alternative Considered: Terse vs Elaborated

As opposed to a continuous syntax between lambdas and function declarations,
alternatively, Carbon could adopt a few different categories of functions. As
Expand Down Expand Up @@ -299,7 +307,7 @@ fn FunctionDeclaration1 => T.Make();
fn FunctionDeclaration2[]() -> T { return T.Make(); }
```

<h3 id="introducer-alternative-considered">Alternative Considered</h3>
### Alternative Considered: Sigil

Introduce with a sigil, such as `$` or `@`. Since introducer punctuation is such
a scarce resource, and since there was no consensus on what sigil would best
Expand Down Expand Up @@ -372,7 +380,7 @@ fn Foo6() {
}
```

<h4 id="positional-parameter-restrictions-alternative-considered">Alternative Considered</h4>
#### Alternative Considered: Additional Restriction

In addition to the proposed restrictions, an additional restriction was
considered. That being, visibility of functions with positional parameters could
Expand All @@ -381,10 +389,11 @@ forth as a leads question before a decision is made.**

## Function Captures

**Proposal**: Function captures in Carbon mirror the non-init captures of C++.
Bindings defined in a scope visible to a function can be captured in the
function instance, be it a function declaration or a lambda. The lifetime of a
capture is the lifetime of the function in which it exists. For example...
**Proposal**: Function captures in Carbon mirror the non-init captures of C++. A
function capture declaration consists of a capture mode followed by the name of
a binding from the enclosing scope, and makes that identifier available in the
inner function body. The lifetime of a capture is the lifetime of the function
in which it exists. For example...

```
fn Foo() {
Expand Down Expand Up @@ -415,6 +424,11 @@ captures. They behave as specified in the following table:
| `ref` | Capture "by-reference" behaving as a C++ reference |
| `const ref` | Capture "by-const-reference" behaving as a C++ const reference |

To prevent ambiguities, captures can only exist on functions where the
definition is attached to the declaration. This means they are supported on
lambdas and they are supported on function declarations that are immediately
defined, but they are not supported on forward-declared functions.

Capture modes can be used as
[default capture mode specifiers](#default-capture-mode) or for explicit
captures as shown in the example code below.
Expand Down Expand Up @@ -454,7 +468,7 @@ fn Example {
}
```

<h4 id="capture-modes-alternative-considered">Alternative Considered</h4>
#### Alternative Considered: By-Value Captures

Alternatively, the below-shown four capture modes (by-value, by-object, by-copy
\[immutable\], and by-reference \[mutable\]) could be provided for function
Expand Down Expand Up @@ -536,7 +550,7 @@ fn Foo() {
}
```

<h4 id="default-capture-mode-alternative-considered">Alternative Considered</h4>
#### Alternative Considered: Middle vs Beginning

Previously, it was proposed that the default capture mode would come after all
the explicit captures. In addition, it was proposed that the lack of any square
Expand All @@ -549,11 +563,16 @@ that says they can't intermix, the more flexible behavior was favored.

## Function Fields

**Proposal**: To mirror the behavior of init captures in C++, function fields
will support nothing-implies-`let` and `var` binding patterns. These will be
annotated with a type and initialized with the right-hand-side of an equals
sign. The lifetime of a function field is the same as the lifetime of the
function declaration or lambda in which it exists.
**Proposal**: Function fields mirror the behavior of init captures in C++. A
function field definition consists of an irrefutable pattern, `=`, and an
initializer. It matches the pattern with the initializer when the function
definition is evaluated. The bindings in the pattern have the same lifetime as
the function, and their scope extends to the end of the function body.

To prevent ambiguities, function fields can only exist on functions where the
definition is attached to the declaration. This means they are supported on
lambdas and they are supported on function declarations that are immediately
defined, but they are not supported on forward-declared functions.

```
fn Foo() {
Expand All @@ -566,7 +585,7 @@ fn Foo() {
}
```

<h3 id="function-fields-alternative-considered">Alternative Considered</h3>
### Alternative Considered: No Function Fields

Alternatively, by-value and by-object capturing could serve the same purpose.
This was decided against because capturing is not as expressive as general
Expand Down Expand Up @@ -598,7 +617,7 @@ For function declarations, it is only permitted when the function is a member of
a class type, such that it refers to the class type and not to the function
itself.

<h3 id="self-and-recursion-alternative-considered">Alternative Considered</h3>
### Alternative Considered: Recursive Self

For use in recursion, `self: Self` could be permitted on all functions and
lambdas and refer to the function itself. This was originally the plan.
Expand Down

0 comments on commit 4b408a2

Please sign in to comment.