Skip to content

Commit 8987fee

Browse files
dan-zhenglattner
authored andcommitted
Fix typos in SE-0253. (#1010)
* Fix typos in SE-0253. * Improve comment formatting, use ASCII quotes. * Remove extra whitespace. * Use ASCII ellipsis. * Abbreviate implementation link. * Use ASCII quotes. Co-Authored-By: dan-zheng <[email protected]>
1 parent cad41b4 commit 8987fee

File tree

1 file changed

+19
-18
lines changed

1 file changed

+19
-18
lines changed

proposals/0253-callable.md

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
* Authors: [Richard Wei](https://github.com/rxwei), [Dan Zheng](https://github.com/dan-zheng)
55
* Review Manager: [Chris Lattner](https://github.com/lattner)
66
* Status: **Active review (March 27 - April 5, 2019)**
7-
* Implementation: https://github.com/apple/swift/pull/23517
7+
* Implementation: [apple/swift#23517](https://github.com/apple/swift/pull/23517)
88

99
## Introduction
1010

1111
Note: throughout this document, let "call-syntax" refer to the syntax of applying a function to arguments: `f(x, y, z)`.
1212

1313
This proposal introduces [callables](https://en.wikipedia.org/wiki/Callable_object) to Swift. Callables are values that define function-like behavior and can be applied using function application syntax.
1414

15-
In a nutshell, we propose to introduce a new declaration syntax with the keyword `call` :
15+
In a nutshell, we propose to introduce a new declaration syntax with the keyword `call`:
1616

1717
```swift
1818
struct Adder {
@@ -121,21 +121,20 @@ A call syntax sugar would enable `BoundClosure` instances to be applied like nor
121121

122122
### Nominal types with one primary method
123123

124-
Some nominal types have a "primary method" that performs their main use. For example: calculators *calculate*, parsers *parse*, neural network layers *apply to inputs*, types representing functions *apply to arguments*, etc.
124+
Some nominal types have a "primary method" that performs their main use. For example:
125125

126-
For example:
127126
* Calculators *calculate*: `calculator.calculating(query)`.
128127
* Parsers *parse*: `parser.parsing(text)`.
129128
* Neural network layers *apply to inputs*: `layer.applied(to: input)`.
130129
* Types representing functions *apply to arguments*: `function.applied(to: arguments)`.
131130

132131
Types that have a primary method usually call that method frequently. Thus, it may be desirable to sugar applications of the main method with call syntax to reduce noise.
133132

134-
Lets explore neural network layers and string parsers in detail.
133+
Let's explore neural network layers and string parsers in detail.
135134

136135
#### Neural network layers
137136

138-
[Machine learning](https://en.wikipedia.org/wiki/Machine_learning) models often represent a function that contains an internal state called "trainable parameters", and the function takes an input and predicts the output. In code, models are often represented as a data structure that stores trainable parameters, and a method that defines the transformation from an input to an output in terms of these trained parameters. Heres an example:
137+
[Machine learning](https://en.wikipedia.org/wiki/Machine_learning) models often represent a function that contains an internal state called "trainable parameters", and the function takes an input and predicts the output. In code, models are often represented as a data structure that stores trainable parameters, and a method that defines the transformation from an input to an output in terms of these trained parameters. Here's an example:
139138

140139
```swift
141140
struct Perceptron {
@@ -217,7 +216,7 @@ call(_ input: String) throws -> Output {
217216
```
218217

219218
```swift
220-
let sexpParser: Parser<Expression> =
219+
let sexpParser: Parser<Expression> = ...
221220
// Callable syntax.
222221
let sexp = sexpParser("(+ 1 2)")
223222
```
@@ -326,15 +325,15 @@ When type-checking fails, error messages look like those for function calls. Whe
326325

327326
```swift
328327
add1("foo")
329-
// error: cannot invoke add1 with an argument list of type '(String)'
328+
// error: cannot invoke 'add1' with an argument list of type '(String)'
330329
// note: overloads for 'call' exist with these partially matching parameter lists: (Float), (Int)
331330
add1(1, 2, 3)
332331
// error: cannot invoke 'add1' with an argument list of type '(Int, Int, Int)'
333332
```
334333

335334
### When the type is also `@dynamicCallable`
336335

337-
A type can both have `call` members and be declared with `@dynamicCallable` . When type-checking a call expression, the type checker will first try to resolve the call to a function or initializer call, then a `call` member call, and finally a dynamic call.
336+
A type can both have `call` members and be declared with `@dynamicCallable`. When type-checking a call expression, the type checker will first try to resolve the call to a function or initializer call, then a `call` member call, and finally a dynamic call.
338337

339338
### Direct reference to a `call` member
340339

@@ -388,7 +387,7 @@ The proposed feature adds a `call` keyword. Normally, this would require existin
388387

389388
To maintain source compatibility, we propose making `call` a contextual keyword: that is, it is a keyword only in declaration contexts and a normal identifier elsewhere (e.g. in expression contexts). This means that `func call` and `call(...)` (apply expressions) continue to parse correctly.
390389

391-
Heres a comprehensive example of parsing `call` in different contexts:
390+
Here's a comprehensive example of parsing `call` in different contexts:
392391

393392
```swift
394393
struct Callable {
@@ -446,13 +445,13 @@ struct Adder {
446445
}
447446
// Option: `call` declaration modifier on unnamed `func` declarations.
448447
// Makes unnamed `func` less weird and clearly states "call".
449-
call func(_ x: Int) -> Int { }
448+
call func(_ x: Int) -> Int { ... }
450449
}
451450
```
452451

453452
This approach represents call-syntax delegate methods as unnamed `func` declarations instead of creating a new `call` declaration kind.
454453

455-
One option is to use `func(...)` without an identifier name. Since the word "call" does not appear, it is less clear that this denotes a call-syntax delegate method. Additionally, its not clear how direct references would work: the proposed design of referencing `call` declarations via `foo.call` is clear and consistent with the behavior of `init` declarations.
454+
One option is to use `func(...)` without an identifier name. Since the word "call" does not appear, it is less clear that this denotes a call-syntax delegate method. Additionally, it's not clear how direct references would work: the proposed design of referencing `call` declarations via `foo.call` is clear and consistent with the behavior of `init` declarations.
456455

457456
To make unnamed `func(...)` less weird, one option is to add a `call` declaration modifier: `call func(...)`. The word `call` appears in both this option and the proposed design, clearly conveying "call-syntax delegate method". However, declaration modifiers are currently also treated as keywords, so with both approaches, parser changes to ensure source compatibility are necessary. `call func(...)` requires additional parser changes to allow `func` to sometimes not be followed by a name. The authors lean towards `call` declarations for terseness.
458457

@@ -496,6 +495,10 @@ Also, we want to support direct references to call-syntax delegate methods via `
496495
struct Adder {
497496
var base: Int
498497
// Informal rule: all methods with a particular name (e.g. `func call`) are deemed call-syntax delegate methods.
498+
//
499+
// `StringInterpolationProtocol` has a similar informal requirement for
500+
// `func appendInterpolation` methods.
501+
// https://github.com/apple/swift-evolution/blob/master/proposals/0228-fix-expressiblebystringinterpolation.md#proposed-solution
499502
func call(_ x: Int) -> Int {
500503
return base + x
501504
}
@@ -504,7 +507,7 @@ struct Adder {
504507

505508
We feel this approach is not ideal because:
506509

507-
* A marker type attribute is not particularly meaningful. The call-syntax delegate methods of a type are what make values of that type callable - a type attribute means nothing by itself. In fact, theres an edge case that needs to be explicitly handled: if a `@staticCallable` type defines no call-syntax delegate methods, an error must be produced.
510+
* A marker type attribute is not particularly meaningful. The call-syntax delegate methods of a type are what make values of that type callable - a type attribute means nothing by itself. In fact, there's an edge case that needs to be explicitly handled: if a `@staticCallable` type defines no call-syntax delegate methods, an error must be produced.
508511
* The name for call-syntax delegate methods (e.g. `func call` ) is not first-class in the language, while their call site syntax is.
509512

510513
#### Use a `Callable` protocol to represent callable types
@@ -514,8 +517,6 @@ We feel this approach is not ideal because:
514517
struct Adder: Callable {
515518
var base: Int
516519
// Informal rule: all methods with a particular name (e.g. `func call`) are deemed call-syntax delegate methods.
517-
// `StringInterpolationProtocol` has a similar informal requirement for `func appendInterpolation` methods.
518-
// https://github.com/apple/swift-evolution/blob/master/proposals/0228-fix-expressiblebystringinterpolation.md#proposed-solution
519520
func call(_ x: Int) -> Int {
520521
return base + x
521522
}
@@ -536,13 +537,13 @@ Halide::Var x, y;
536537
foo(x, y) = x + y;
537538
```
538539

539-
This can be achieved via Swifts subscripts, which can have a getter and a setter.
540+
This can be achieved via Swift's subscripts, which can have a getter and a setter.
540541

541542
```swift
542543
foo[x, y] = x + y
543544
```
544545

545-
Since the proposed `call` declaration syntax is like `subscript` in many ways, its in theory possible to allow `get` and `set` in a `call` declarations body.
546+
Since the proposed `call` declaration syntax is like `subscript` in many ways, it's in theory possible to allow `get` and `set` in a `call` declaration's body.
546547

547548
```swift
548549
call(x: T) -> U {
@@ -555,7 +556,7 @@ call(x: T) -> U {
555556
}
556557
```
557558

558-
However, we do not believe `call` should behave like a storage accessor like `subscript` . Instead, `call`s appearance should be as close to function calls as possible. Function call expressions today are not assignable because they can't return an l-value reference, so a call to a `call` member should not be assignable either.
559+
However, we do not believe `call` should behave like a storage accessor like `subscript`. Instead, `call`'s appearance should be as close to function calls as possible. Function call expressions today are not assignable because they can't return an l-value reference, so a call to a `call` member should not be assignable either.
559560

560561
### Static `call` members
561562

0 commit comments

Comments
 (0)