From d0e50d90a107e70ffc9a2a57ce182d82244bd642 Mon Sep 17 00:00:00 2001 From: Alexander Cyon Date: Mon, 19 Aug 2024 20:01:43 +0200 Subject: [PATCH] [Proposals] fix typos in 90+ proposals --- ...-api-guidelines-to-the-standard-library.md | 2 +- ...0018-flexible-memberwise-initialization.md | 32 +++++++++---------- .../0026-abstract-classes-and-methods.md | 4 +-- proposals/0058-objectivecbridgeable.md | 4 +-- proposals/0073-noescape-once.md | 2 +- proposals/0075-import-test.md | 2 +- proposals/0082-swiftpm-package-edit.md | 2 +- proposals/0088-libdispatch-for-swift3.md | 2 +- proposals/0099-conditionclauses.md | 2 +- proposals/0106-rename-osx-to-macos.md | 2 +- proposals/0107-unsaferawpointer.md | 2 +- proposals/0108-remove-assoctype-inference.md | 2 +- proposals/0119-extensions-access-modifiers.md | 6 ++-- proposals/0138-unsaferawbufferpointer.md | 6 ++-- .../0145-package-manager-version-pinning.md | 2 +- proposals/0147-move-unsafe-initialize-from.md | 2 +- proposals/0156-subclass-existentials.md | 2 +- ...2-package-manager-custom-target-layouts.md | 2 +- proposals/0172-one-sided-ranges.md | 4 +-- proposals/0173-swap-indices.md | 2 +- proposals/0174-filter-range-replaceable.md | 2 +- ...0176-enforce-exclusive-access-to-memory.md | 2 +- proposals/0180-string-index-overhaul.md | 2 +- proposals/0183-substring-affordances.md | 2 +- ...ross-module-inlining-and-specialization.md | 2 +- proposals/0196-diagnostic-directives.md | 2 +- .../0198-playground-quicklook-api-revamp.md | 2 +- proposals/0207-containsOnly.md | 2 +- ...ckage-manager-swift-lang-version-update.md | 2 +- .../0223-array-uninitialized-initializer.md | 2 +- ...28-fix-expressiblebystringinterpolation.md | 2 +- proposals/0231-optional-iteration.md | 4 +-- proposals/0235-add-result.md | 2 +- proposals/0240-ordered-collection-diffing.md | 4 +-- .../0243-codepoint-and-character-literals.md | 2 +- proposals/0244-opaque-result-types.md | 2 +- .../0245-array-uninitialized-initializer.md | 2 +- proposals/0246-mathable.md | 2 +- proposals/0253-callable.md | 2 +- proposals/0254-static-subscripts.md | 2 +- proposals/0259-approximately-equal.md | 2 +- proposals/0260-library-evolution.md | 2 +- proposals/0261-identifiable.md | 2 +- ...nd-punctuations-for-escaped-identifiers.md | 4 +-- proposals/0290-negative-availability.md | 4 +-- ...thesis-for-enums-with-associated-values.md | 2 +- proposals/0296-async-await.md | 2 +- proposals/0298-asyncsequence.md | 2 +- .../0303-swiftpm-extensible-build-tools.md | 8 ++--- proposals/0306-actors.md | 2 +- ...ock-existential-types-for-all-protocols.md | 4 +-- .../0310-effectful-readonly-properties.md | 2 +- proposals/0311-task-locals.md | 8 ++--- proposals/0313-actor-isolation-control.md | 2 +- proposals/0317-async-let.md | 2 +- proposals/0318-package-creation.md | 10 +++--- proposals/0319-never-identifiable.md | 2 +- .../0325-swiftpm-additional-plugin-apis.md | 6 ++-- proposals/0332-swiftpm-command-plugins.md | 2 +- ...ental-migration-to-concurrency-checking.md | 2 +- ...aries-by-default-on-supported-platforms.md | 2 +- proposals/0345-if-let-shorthand.md | 6 ++-- .../0347-type-inference-from-default-exprs.md | 2 +- proposals/0348-buildpartialblock.md | 2 +- proposals/0349-unaligned-loads-and-stores.md | 2 +- proposals/0351-regex-builder.md | 8 ++--- proposals/0352-implicit-open-existentials.md | 2 +- proposals/0354-regex-literals.md | 4 +-- proposals/0356-swift-snippets.md | 2 +- ...0357-regex-string-processing-algorithms.md | 8 ++--- .../0363-unicode-for-string-processing.md | 4 +-- proposals/0367-conditional-attributes.md | 2 +- proposals/0376-function-back-deployment.md | 2 +- proposals/0381-task-group-discard-results.md | 4 +-- ...-declared-objc-interfaces-and-protocols.md | 2 +- proposals/0389-attached-macros.md | 2 +- proposals/0392-custom-actor-executors.md | 30 ++++++++--------- proposals/0400-init-accessors.md | 2 +- proposals/0402-extension-macros.md | 2 +- .../0403-swiftpm-mixed-language-targets.md | 6 ++-- proposals/0406-async-stream-backpressure.md | 2 +- proposals/0410-atomics.md | 8 ++--- proposals/0413-typed-throws.md | 4 +-- proposals/0414-region-based-isolation.md | 4 +-- proposals/0415-function-body-macros.md | 2 +- proposals/0417-task-executor-preference.md | 2 +- proposals/0421-generalize-async-sequence.md | 4 +-- proposals/0423-dynamic-actor-isolation.md | 2 +- ...m-isolation-checking-for-serialexecutor.md | 2 +- proposals/0426-bitwise-copyable.md | 2 +- ...428-resolve-distributed-actor-protocols.md | 2 +- proposals/0433-mutex.md | 6 ++-- proposals/0438-metatype-keypath.md | 2 +- proposals/0440-debug-description-macro.md | 2 +- ...oup-childtaskresult-type-to-be-inferred.md | 2 +- 95 files changed, 169 insertions(+), 169 deletions(-) diff --git a/proposals/0006-apply-api-guidelines-to-the-standard-library.md b/proposals/0006-apply-api-guidelines-to-the-standard-library.md index 2b78b786bd..76349a2287 100644 --- a/proposals/0006-apply-api-guidelines-to-the-standard-library.md +++ b/proposals/0006-apply-api-guidelines-to-the-standard-library.md @@ -1144,7 +1144,7 @@ public struct OpaquePointer : ... { - allowedCharacters: NSCharacterSet - ) -> String? + public func addingPercentEncoding( -+ withAllowedCharaters allowedCharacters: NSCharacterSet ++ withAllowedCharacters allowedCharacters: NSCharacterSet + ) -> String? - public func stringByAddingPercentEscapesUsingEncoding( diff --git a/proposals/0018-flexible-memberwise-initialization.md b/proposals/0018-flexible-memberwise-initialization.md index 9b1646ff2f..2bddbf171c 100644 --- a/proposals/0018-flexible-memberwise-initialization.md +++ b/proposals/0018-flexible-memberwise-initialization.md @@ -20,7 +20,7 @@ When designing initializers for a type we are currently faced with the unfortuna Underlying this problem is the fact that initialization scales with M x N complexity (M members, N initializers). We need as much help from the compiler as we can get! -Flexible and concise initialization for both type authors and consumers will encourages using immutability where possible and removes the need for boilerplate from the concerns one must consider when designing the intializers for a type. +Flexible and concise initialization for both type authors and consumers will encourages using immutability where possible and removes the need for boilerplate from the concerns one must consider when designing the initializers for a type. Quoting [Chris Lattner](https://forums.swift.org/t/proposal-helpers-for-initializing-properties-of-same-name-as-parameters/129/8): @@ -31,9 +31,9 @@ Quoting [Chris Lattner](https://forums.swift.org/t/proposal-helpers-for-initiali 4) var properties with default initializers should have their parameter to the synthesized initializer defaulted. 5) lazy properties with memberwise initializers have problems (the memberwise init eagerly touches it). -Add to the list “all or nothing”. The compiler generates the entire initializer and does not help to eliminate boilerplate for any other initializers where it may be desirable to use memberwise intialization for a subset of members and initialize others manually. +Add to the list “all or nothing”. The compiler generates the entire initializer and does not help to eliminate boilerplate for any other initializers where it may be desirable to use memberwise initialization for a subset of members and initialize others manually. -It is common to have a type with a number of public members that are intended to be configured by clients, but also with some private state comprising implementation details of the type. This is especially prevalent in UI code which may expose many properties for configuring visual appearance, etc. Flexibile memberwise initialization can provide great benefit in these use cases, but it immediately becomes useless if it is "all or nothing". +It is common to have a type with a number of public members that are intended to be configured by clients, but also with some private state comprising implementation details of the type. This is especially prevalent in UI code which may expose many properties for configuring visual appearance, etc. Flexible memberwise initialization can provide great benefit in these use cases, but it immediately becomes useless if it is "all or nothing". We need a flexible solution that can synthesize memberwise initialization for some members while allowing the type author full control over initialization of implementation details. @@ -47,7 +47,7 @@ The two approaches are not mutually exclusive: it is possible to use the *automa The *automatic* model of the current proposal determines the set of properties that receive memberwise initialization parameters by considering *only* the initializer declaration and the declarations for all properties that are *at least* as visible as the initializer (including any behaviors attached to the properties). The rules are as follows: -1. The access level of the property is *at least* as visible as the memberwise initializer. The visiblity of the **setter** is used for `var` properties. +1. The access level of the property is *at least* as visible as the memberwise initializer. The visibility of the **setter** is used for `var` properties. 2. They do not have a behavior which prohibits memberwise initialization (e.g. the 'lazy' behavior). 3. If the property is a `let` property it *may not* have an initial value. @@ -192,7 +192,7 @@ Throughout this design the term **memberwise initialization parameter** is used 1. Determine the set of properties eligible for memberwise initialization synthesis. Properties are eligible for memberwise initialization synthesis if: - 1. The access level of the property is *at least* as visible as the memberwise initializer. The visiblity of the **setter** is used for `var` properties. + 1. The access level of the property is *at least* as visible as the memberwise initializer. The visibility of the **setter** is used for `var` properties. 2. They do not have a behavior which prohibits memberwise initialization. 3. If the property is a `let` property it *may not* have an initial value. @@ -216,7 +216,7 @@ This proposal will also support generating an *implicit* memberwise initializer 2. The type is: 1. a struct 2. a root class - 3. a class whose superclass has a designated intializer requiring no arguments + 3. a class whose superclass has a designated initializer requiring no arguments The implicitly generated memberwise initializer will have the highest access level possible while still allowing all stored properties to be eligible for memberwise parameter synthesis, but will have at most `internal` visibility. Currently this means its visibility will be `internal` when all stored properties of the type have setters with *at least* `internal` visibility, and `private` otherwise (when one or more stored properties are `private` or `private(set)`). @@ -228,7 +228,7 @@ The changes described in this proposal are *almost* entirely additive. The only 1. If the implicitly synthesized memberwise initializer was only used *within* the same source file no change is necessary. An implicit `private` memberwise initializer will still be synthesized by the compiler. 2. A mechanical migration could generate the explicit code necessary to declare the previously implicit initializer. This would be an `internal` memberwise initializer with *explicit* parameters used to manually initialize the stored properties with `private` setters. -3. If the "Access control for init" enhancement were accepted the `private` members could have their access control modified to `private internal(init)` which would allow the implicit memberwise intializer to continue to have `internal` visibility as all stored properties would be eligible for parameter synthesis by an `internal` memberwise initializer. +3. If the "Access control for init" enhancement were accepted the `private` members could have their access control modified to `private internal(init)` which would allow the implicit memberwise initializer to continue to have `internal` visibility as all stored properties would be eligible for parameter synthesis by an `internal` memberwise initializer. The only other impact on existing code is that memberwise parameters corresponding to `var` properties with initial values will now have default values. This will be a change in the behavior of the implicit memberwise initializer but will not break any code. The change will simply allow new code to use that initializer without providing an argument for such parameters. @@ -293,7 +293,7 @@ The rules of the current proposal are designed to synthesize memberwise paramete Introducing a `memberwise` declaration modifier for properties would allow programmers to specify exactly which properties should participate in memberwise initialization synthesis. It allows full control and has the clarity afforded by being explicit. -Specifc use cases this feature would support include allowing `private` properties to receive synthesized memberwise parameters in a `public` initializer, or allow `public` properties to be omitted from parameter synthesis. +Specific use cases this feature would support include allowing `private` properties to receive synthesized memberwise parameters in a `public` initializer, or allow `public` properties to be omitted from parameter synthesis. An example of this @@ -348,7 +348,7 @@ struct S { If this enhancement were submitted the first property eligibility rule would be updates as follows: -1. Their **init** access level is *at least* as visible as the memberwise initializer. If the property does not have an **init** acccess level, the access level of its **setter** must be *at least* as visible as the memberwise initializer. +1. Their **init** access level is *at least* as visible as the memberwise initializer. If the property does not have an **init** access level, the access level of its **setter** must be *at least* as visible as the memberwise initializer. ### @nomemberwise @@ -400,7 +400,7 @@ struct S { init(s: String) { /* synthesized */ self.s = s - // body of the user's intializer remains + // body of the user's initializer remains i = 42 } } @@ -408,7 +408,7 @@ struct S { ### Memberwise initializer chaining / parameter forwarding -Ideally it would be possible to define convenience and delegating initializers without requiring them to manually declare parameters and pass arguments to the designated initializer for memberwise intialized properties. It would also be ideal if designated initializers also did not have to the same for memberwise intialization parmaeters of super. +Ideally it would be possible to define convenience and delegating initializers without requiring them to manually declare parameters and pass arguments to the designated initializer for memberwise initialized properties. It would also be ideal if designated initializers also did not have to the same for memberwise initialization parameters of super. A general solution for parameter forwarding would solve this problem. A future parameter forwarding proposal to support this use case and others is likely to be pursued. @@ -435,7 +435,7 @@ Obviously supporting memberwise initialization with Cocoa classes would require This is a reasonable option and and I expect a healthy debate about which default is better. The decision to adopt the *automatic* model by default was made for several reasons: 1. The memberwise initializer for structs does not currently require an annotation for properties to opt-in. Requiring an annotation for a mechanism designed to supersede that mechanism may be viewed as boilerplate. -2. Stored properties with public visibility are often intialized directly with a value provided by the caller. +2. Stored properties with public visibility are often initialized directly with a value provided by the caller. 3. Stored properties with **less visibility** than a memberwise initializer are not eligible for memberwise initialization. No annotation is required to indicate that and it is usually not desired. 4. The *automatic* model cannot exist unless it is the default. The *opt-in* model can exist alongside the *automatic* model and itself be opted-into simply by specifying the `memberwise` declaration modifier on one or more properties. @@ -462,7 +462,7 @@ Reasons to limit memberwise parameter synthesis to members which are *at least* 5. If a proposal for `@nomemberwise` is put forward and adopted that would allow us to prevent synthesis of parameters for members as desired. Unfortunately `@nomemberwise` would need to be used much more heavily than it otherwise would (i.e. to prevent synthesis of memberwise parameters for more-private members). It would be better if `@nomemberwise` was not necessary most of the time. 6. If callers must be able to provide memberwise arguments for more-private members directly it is still possible to allow that while taking advantage of memberwise initialization for same-or-less-private members. You just need to declare a `memberwise init` with explicitly declared parameters for the more-private members and initialize them manually in the body. If the "Access control for init" enhancement is accepted another option would be upgrading the visibility of `init` for the more-private member while retaining its access level for the getter and setter. Requiring the programmer to explicitly expose a more-private member either via `init` access control or by writing code that it directly is arguably a very good thing. -Reasons we might want to allow memberwise parameter synthesis for members with lower visiblity than the initializer: +Reasons we might want to allow memberwise parameter synthesis for members with lower visibility than the initializer: 1. Not doing so puts tension between access control for stored properties and memberwise inits. You have to choose between narrower access control or getting the benefit of a memberwise init. Another way to say it: this design means that narrow access control leads to boilerplate. @@ -470,7 +470,7 @@ NOTE: The tension mentioned here is lessened by #6 above: memberwise initializat ### Require initializers to explicitly specify memberwise initialization parameters -The thread "[helpers for initializing properties of the same name as parameters](https://forums.swift.org/t/proposal-helpers-for-initializing-properties-of-same-name-as-parameters/129/3)" discussed an idea for synthesizing property initialization in the body of the initializer while requiring the parameters to be declard explicitly. +The thread "[helpers for initializing properties of the same name as parameters](https://forums.swift.org/t/proposal-helpers-for-initializing-properties-of-same-name-as-parameters/129/3)" discussed an idea for synthesizing property initialization in the body of the initializer while requiring the parameters to be declared explicitly. ```swift struct Foo { @@ -494,7 +494,7 @@ Under the current proposal full control is still available. It requires initial I believe the `memberwise` declaration modifier on the initializer and the placeholder in the parameter list make it clear that the compiler will synthesize additional parameters. Furthermore, IDEs and generated documentation will contain the full, synthesized signature of the initializer. -Finally, this idea is not mutually exclusive with the current proposal. It could even work in the declaration of a memberwise initializer, so long the corresponding property was made ineligible for memberwise intialization synthesis. +Finally, this idea is not mutually exclusive with the current proposal. It could even work in the declaration of a memberwise initializer, so long the corresponding property was made ineligible for memberwise initialization synthesis. ### Adopt "type parameter list" syntax like Kotlin and Scala @@ -540,7 +540,7 @@ Responses to these points follow: 1. If the expansion of this syntax does not supply initial values to the synthesized properties and only uses the default value for parameters of the synthesized initializer this is true. The downside of doing this is that `var` properties no longer have an initial value which may be desirable if you write additional initializers for the type. I believe we should continue the discussion about default values for `let` properties. Ideally we can find an acceptable solution that will work with the current proposal, as well as any additional syntactic sugar we add in the future. -2. I don't believe allowing parameter labels for memberwise initialization parameters is a good idea. Callers are directly initializing a property and are best served by a label that matches the name of the property. If you really need to provide a different name you can still do so by writing your initializer manually. With future enhancements to the current proposal you may be able to use memberwise intialization for properties that do not require a custom label while manually initialzing properties that do need one. +2. I don't believe allowing parameter labels for memberwise initialization parameters is a good idea. Callers are directly initializing a property and are best served by a label that matches the name of the property. If you really need to provide a different name you can still do so by writing your initializer manually. With future enhancements to the current proposal you may be able to use memberwise initialization for properties that do not require a custom label while manually initializing properties that do need one. 3. The Scala / Kotlin syntax is indeed more concise in some cases, but not in all cases. Under this proposal the example given above is actually more concise than it is with that syntax: ```swift diff --git a/proposals/0026-abstract-classes-and-methods.md b/proposals/0026-abstract-classes-and-methods.md index c86badb14a..24b89a5eb9 100644 --- a/proposals/0026-abstract-classes-and-methods.md +++ b/proposals/0026-abstract-classes-and-methods.md @@ -16,7 +16,7 @@ in inherited class like protocols. ## Motivation -like pure virtual methods in C++ and abtract classes in Java and C#, frameworks development +like pure virtual methods in C++ and abstract classes in Java and C#, frameworks development sometimes required abstract classes facility. An abstract class is like a regular class, but some methods/properties are not implemented and must be implemented in one of inherited classes. @@ -97,7 +97,7 @@ class MyRestServiceClient : RESTClient { ``` ## Detailed design -An abstract class cannot be instanciated. +An abstract class cannot be instantiated. Abstract method/property cannot have implementation. diff --git a/proposals/0058-objectivecbridgeable.md b/proposals/0058-objectivecbridgeable.md index 6461ecec58..478a23adf4 100644 --- a/proposals/0058-objectivecbridgeable.md +++ b/proposals/0058-objectivecbridgeable.md @@ -77,7 +77,7 @@ public protocol ObjectiveCBridgeable { /// Objective-C thunk or when calling Objective-C code. /// /// - note: This initializer should eagerly perform the - /// conversion without defering any work for later, + /// conversion without deferring any work for later, /// returning `nil` if the conversion fails. init?(bridgedFromObjectiveC: ObjectiveCType) @@ -144,7 +144,7 @@ The compiler generates automatic thunks only when there is no ambiguity, while e 3. Bridged collection types will still observe the protocol conformance if cast to a Swift type (eg: `NSArray as? [Int]` will call the `ObjectiveCBridgeable` implementation on `Array`, which itself will call the implementation on `Int` for the elements) 2. A Swift type may bridge to an Objective-C base class then provide different subclass instances at runtime, but no other Swift type may bridge to that base class or any of its subclasses. 1. The compiler should emit a diagnostic when it detects two Swift types attempting to bridge to the same `ObjectiveCType`. -3. An exception to these rules exists for trivially convertable built-in types like `NSInteger` <--> `Int` when specified outside of a bridged collection type. In those cases the compiler will continue the existing behavior, bypassing the `ObjectiveCBridgeable` protocol. The effect is that types like `Int` will not bridge to `NSNumber` unless contained inside a collection type (see `BuiltInBridgeable below`). +3. An exception to these rules exists for trivially convertible built-in types like `NSInteger` <--> `Int` when specified outside of a bridged collection type. In those cases the compiler will continue the existing behavior, bypassing the `ObjectiveCBridgeable` protocol. The effect is that types like `Int` will not bridge to `NSNumber` unless contained inside a collection type (see `BuiltInBridgeable below`). ### Resiliance diff --git a/proposals/0073-noescape-once.md b/proposals/0073-noescape-once.md index c541f9afd1..793f313095 100644 --- a/proposals/0073-noescape-once.md +++ b/proposals/0073-noescape-once.md @@ -128,7 +128,7 @@ expected. ## Not requiring exactly one execution Assuming that the main goal of this proposal is to relax initialization -requirements, a unique invocation of the closure is not stricly required. +requirements, a unique invocation of the closure is not strictly required. However the requirement of unique invocation makes the proposal simpler to understand. diff --git a/proposals/0075-import-test.md b/proposals/0075-import-test.md index 298e4dcde9..7844243832 100644 --- a/proposals/0075-import-test.md +++ b/proposals/0075-import-test.md @@ -33,7 +33,7 @@ Swift's existing set of build configurations specify platform differences, not m #endif ``` -Guarding code with operating system tests can be less future-proofed than testing for module support. Excluding OS X to use UIColor creates code that might eventually find its way to a Linux plaform. Targeting Apple platforms by inverting a test for Linux essentially broke after the introduction of `Windows` and `FreeBSD` build configurations: +Guarding code with operating system tests can be less future-proofed than testing for module support. Excluding OS X to use UIColor creates code that might eventually find its way to a Linux platform. Targeting Apple platforms by inverting a test for Linux essentially broke after the introduction of `Windows` and `FreeBSD` build configurations: ```swift // Exclusive os tests are brittle diff --git a/proposals/0082-swiftpm-package-edit.md b/proposals/0082-swiftpm-package-edit.md index ff458171b2..5e3e24bfed 100644 --- a/proposals/0082-swiftpm-package-edit.md +++ b/proposals/0082-swiftpm-package-edit.md @@ -93,7 +93,7 @@ This solution is intended to directly address the desired behaviors of the package manager: * By hiding the sources by default, we minimize the distractions in the common - case where a user is programming against a known, well-establised, library + case where a user is programming against a known, well-established, library they do not need to modify. * By adding a new, explicit workflow for switching to an "editable" package, we diff --git a/proposals/0088-libdispatch-for-swift3.md b/proposals/0088-libdispatch-for-swift3.md index 8f17fd830b..19bfd9d3bc 100644 --- a/proposals/0088-libdispatch-for-swift3.md +++ b/proposals/0088-libdispatch-for-swift3.md @@ -259,7 +259,7 @@ struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable { } ``` -This proposal will introduce new accessor methods to access the bytes in a Data object. Along with becoming iteratable, several methods will be introduced that replace the ```dispatch_data_create_map``` approach used in C: +This proposal will introduce new accessor methods to access the bytes in a Data object. Along with becoming iterable, several methods will be introduced that replace the ```dispatch_data_create_map``` approach used in C: ```swift struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable { diff --git a/proposals/0099-conditionclauses.md b/proposals/0099-conditionclauses.md index 902b0258de..95ca694357 100644 --- a/proposals/0099-conditionclauses.md +++ b/proposals/0099-conditionclauses.md @@ -9,7 +9,7 @@ ## Introduction -Swift condition clauses appear in `guard`, `if`, and `while` statements. This proposal re-architects the condition grammar to enable an arbitrary mix of Boolean expressions, `let` conditions (which test and unwrap optionals), general `case` clauses for arbitrary pattern matching, and availability tests. It removes `where` clauses from optional binding conditions and case conditions, and eliminates gramatical ambiguity by using commas for separation between clauses instead of using them both to separate clauses and terms within each clause. These modifications streamline Swift's syntax and alleviate the situation where many Swift developers don't know they can use arbitrary Boolean conditions after a value binding. +Swift condition clauses appear in `guard`, `if`, and `while` statements. This proposal re-architects the condition grammar to enable an arbitrary mix of Boolean expressions, `let` conditions (which test and unwrap optionals), general `case` clauses for arbitrary pattern matching, and availability tests. It removes `where` clauses from optional binding conditions and case conditions, and eliminates grammatical ambiguity by using commas for separation between clauses instead of using them both to separate clauses and terms within each clause. These modifications streamline Swift's syntax and alleviate the situation where many Swift developers don't know they can use arbitrary Boolean conditions after a value binding. Swift-evolution thread: [\[Pitch\] making where and , interchangeable in guard conditions](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702) diff --git a/proposals/0106-rename-osx-to-macos.md b/proposals/0106-rename-osx-to-macos.md index b43afd0446..e5f4714024 100644 --- a/proposals/0106-rename-osx-to-macos.md +++ b/proposals/0106-rename-osx-to-macos.md @@ -73,7 +73,7 @@ This proposal is purely additive. It will not affect existing code other than ad Instead of retaining and aliasing `os(OSX)`, it can be fully replaced by `os(macOS)`. This mirrors the situation with the phoneOS to iOS rename and would require a migration assistant to fixit old-style use. -Charlie Monroe points out: "Since Swift 3.0 is a code-breaking change my guess is that there is no burden if the Xcode migration assistent automatically changes all `#if os(OSX)` to `#if os(macOS)`, thus deprecating the term OSX, not burdening the developer at all. If iOS was renamed to phoneOS and kept versioning, you'd still expect `#if os(iOS)` to be matched when targeting phoneOS and vice-versa." +Charlie Monroe points out: "Since Swift 3.0 is a code-breaking change my guess is that there is no burden if the Xcode migration assistant automatically changes all `#if os(OSX)` to `#if os(macOS)`, thus deprecating the term OSX, not burdening the developer at all. If iOS was renamed to phoneOS and kept versioning, you'd still expect `#if os(iOS)` to be matched when targeting phoneOS and vice-versa." ## Unaddressed Issues diff --git a/proposals/0107-unsaferawpointer.md b/proposals/0107-unsaferawpointer.md index cab2021cf8..6acefab32f 100644 --- a/proposals/0107-unsaferawpointer.md +++ b/proposals/0107-unsaferawpointer.md @@ -160,7 +160,7 @@ value argument could result in miscompilation if the inferred type ever deviates from the user's original expectations. The type parameter also importantly conveys that the raw memory becomes accessible via a pointer to that type at the point of the call. The -type should be explicitly spelled at this point because accesing the +type should be explicitly spelled at this point because accessing the memory via a typed pointer of an unrelated type could also result in miscompilation. diff --git a/proposals/0108-remove-assoctype-inference.md b/proposals/0108-remove-assoctype-inference.md index 77357b6918..b1373d8a75 100644 --- a/proposals/0108-remove-assoctype-inference.md +++ b/proposals/0108-remove-assoctype-inference.md @@ -165,7 +165,7 @@ There are some advantages to this approach. Brevity is slightly improved. A type As well, Dave Abrahams expresses a [potential issue](https://forums.swift.org/t/pitch-remove-type-inference-for-associated-types/3135/17): -> Finally, I am very concerned that there are protocols such as `Collection`, with many inferrable associated types, and that conforming to these protocols could become *much* uglier. +> Finally, I am very concerned that there are protocols such as `Collection`, with many inferable associated types, and that conforming to these protocols could become *much* uglier. As with many proposals, there is a tradeoff between the status quo and the proposed behavior. As *Completing Generics* puts it, diff --git a/proposals/0119-extensions-access-modifiers.md b/proposals/0119-extensions-access-modifiers.md index 7a9728399d..9112147c9a 100644 --- a/proposals/0119-extensions-access-modifiers.md +++ b/proposals/0119-extensions-access-modifiers.md @@ -56,7 +56,7 @@ This simple access control model also allows us to nest types inside each other *Extensions* however behave differently when it comes to their access control: -* The *access modifier* of an *extension* sets the default modifier of its members which do not have their own localy defined modifier. +* The *access modifier* of an *extension* sets the default modifier of its members which do not have their own locally defined modifier. ```swift public struct D {} @@ -234,7 +234,7 @@ I propose to revise the access control on extensions by removing access modifier fileprivate group { - // Every group memebr is `fileprivate` + // Every group member is `fileprivate` func member1() {} func member2() {} func member3() {} @@ -286,7 +286,7 @@ Iff the *access-level-modifier* is not present, the access modifier on extension ```diff - extension SomeType : SomeProtocol { + public extension SomeType : SomeProtocol { - public func someMemeber() + public func someMember() } ``` diff --git a/proposals/0138-unsaferawbufferpointer.md b/proposals/0138-unsaferawbufferpointer.md index 74f3c7b0a5..b425d8356a 100644 --- a/proposals/0138-unsaferawbufferpointer.md +++ b/proposals/0138-unsaferawbufferpointer.md @@ -32,7 +32,7 @@ for binding memory to a type for subsequent normal typed access. However, migration is not always straightforward because SE-0107 provided only minimal support for raw pointers. Extending raw pointer support to the `UnsafeBufferPointer` type will fill in this -funcionality gap. This is especially important for code that currently +functionality gap. This is especially important for code that currently views "raw" bytes of memory as `UnsafeBufferPointer`. Converting between `UInt8` and the client's element type at every API transition is difficult to do @@ -69,7 +69,7 @@ is natural for the same type that encapsulates a raw pointer and length to also allow clients to view that memory as raw bytes without the need to explicitly bind the memory type each time memory is accessed. This would also improve performance in some cases that I've -encoutered by avoiding array copies. Let's call this new type +encountered by avoiding array copies. Let's call this new type `Unsafe[Mutable]RawBufferPointer`. Any array could be viewed as `UnsafeRawBufferPointer`, and that raw @@ -488,7 +488,7 @@ collection of bytes, so there's no loss in functionality: ```swift public final class BufferedOutputByteStream: OutputByteStream { // FIXME: For inmemory implementation we should be share this buffer with OutputByteStream. - // One way to do this is by allowing OuputByteStream to install external buffers. + // One way to do this is by allowing OutputByteStream to install external buffers. private var contents = [UInt8]() override final func writeImpl(_ bytes: UnsafeRawBufferPointer) { diff --git a/proposals/0145-package-manager-version-pinning.md b/proposals/0145-package-manager-version-pinning.md index 77cc29266d..6900359fa2 100644 --- a/proposals/0145-package-manager-version-pinning.md +++ b/proposals/0145-package-manager-version-pinning.md @@ -366,7 +366,7 @@ specification in the manifest (which is the "requirement"). The meaning of pin connotes this transient relationship between the pin action and the underlying dependency. -In constrast, not only does lock have the wrong connotation, but it also is a +In contrast, not only does lock have the wrong connotation, but it also is a heavily overloaded word which can lead to confusion. For example, if the package manager used POSIX file locking to prevent concurrent manipulation of packages (a feature we intend to implement), and we also referred to the pinning files as diff --git a/proposals/0147-move-unsafe-initialize-from.md b/proposals/0147-move-unsafe-initialize-from.md index b40479613e..7964d5d408 100644 --- a/proposals/0147-move-unsafe-initialize-from.md +++ b/proposals/0147-move-unsafe-initialize-from.md @@ -54,7 +54,7 @@ Therefore: - Over-allocating the destination buffer relative to `underestimatedCount` is valid and simply results in sequence underflow with potentially uninitialized buffer memory (a likely case with arrays that reserve more than they need). - The source sequence's actual count may exceed both `underestimatedCount` and the destination buffer size, resulting in sequence overflow. This is also valid and handled by returning an iterator to the uncopied elements as an overflow sequence. -A matching change should also be made to `UnsafeRawBufferPointer.initializeMemory(from:)`. The one difference is that for convenience this should return an `UnsafeMutableBufferPointer` of the (typed) intialized elements instead of an index into the raw buffer. +A matching change should also be made to `UnsafeRawBufferPointer.initializeMemory(from:)`. The one difference is that for convenience this should return an `UnsafeMutableBufferPointer` of the (typed) initialized elements instead of an index into the raw buffer. ## Detailed design diff --git a/proposals/0156-subclass-existentials.md b/proposals/0156-subclass-existentials.md index 74e685f6f4..a3107aef79 100644 --- a/proposals/0156-subclass-existentials.md +++ b/proposals/0156-subclass-existentials.md @@ -190,7 +190,7 @@ let myViewController = MyViewController() myViewController.setup(UIViewController()) ``` -The previous code continues to compile but still crashs if the Objective-C code calls a method of `UITableViewDataSource` or `UITableViewDelegate`. But if this proposal is accepted and implemented as-is, the Objective-C code will be imported in Swift 4 mode as: +The previous code continues to compile but still crashes if the Objective-C code calls a method of `UITableViewDataSource` or `UITableViewDelegate`. But if this proposal is accepted and implemented as-is, the Objective-C code will be imported in Swift 4 mode as: ```swift class MyViewController { diff --git a/proposals/0162-package-manager-custom-target-layouts.md b/proposals/0162-package-manager-custom-target-layouts.md index 9cce18f915..78d428e350 100644 --- a/proposals/0162-package-manager-custom-target-layouts.md +++ b/proposals/0162-package-manager-custom-target-layouts.md @@ -91,7 +91,7 @@ remember. consider upgrading this to its own type to allow per-file build settings. The new type would conform to `CustomStringConvertible`, so existing declarations would continue to work (except where the strings were - constructed programatically). + constructed programmatically). * `exclude`: This property can be used to exclude certain files and directories from being picked up as sources. Exclude paths are relative diff --git a/proposals/0172-one-sided-ranges.md b/proposals/0172-one-sided-ranges.md index 83286f50cd..0864e86a10 100644 --- a/proposals/0172-one-sided-ranges.md +++ b/proposals/0172-one-sided-ranges.md @@ -64,7 +64,7 @@ variants of `Sequence.enumerated()` when you either want them non-zero-based i.e. `zip(1..., greeting)`, or want to flip the order i.e. `zip(greeting, 0...)`. -This syntax would supercede the existing `prefix` and `suffix` operations that +This syntax would supersede the existing `prefix` and `suffix` operations that take indices, which will be deprecated in a later release. Note that the versions that take distances are not covered by this proposal, and would remain. @@ -171,7 +171,7 @@ extension MutableCollection { where R.Bound == Index { get set } } -extension RangeReplaceableColleciton { +extension RangeReplaceableCollection { public mutating func replaceSubrange( _ subrange: ${Range}, with newElements: C ) where C.Iterator.Element == Iterator.Element, R.Bound == Index diff --git a/proposals/0173-swap-indices.md b/proposals/0173-swap-indices.md index edf2cd57ed..26055065f5 100644 --- a/proposals/0173-swap-indices.md +++ b/proposals/0173-swap-indices.md @@ -82,7 +82,7 @@ protocol MutableCollection { The current `swap` is required to `fatalError` on attempts to swap an element with itself for implementation reasons. This pushes the burden to check this first onto the caller. While swapping an element with itself is often a logic -errror (for example, in a `sort` algorithm where you have a fenceposts bug), it +error (for example, in a `sort` algorithm where you have a fenceposts bug), it is occasionally a valid situation (for example, it can occur easily in an implementation of `shuffle`). This implementation removes the precondition. diff --git a/proposals/0174-filter-range-replaceable.md b/proposals/0174-filter-range-replaceable.md index 6f791b7fc2..ead1768f74 100644 --- a/proposals/0174-filter-range-replaceable.md +++ b/proposals/0174-filter-range-replaceable.md @@ -70,7 +70,7 @@ They may be be relying on an array being returned (albeit often in order to then transform it back into the original type), but this version will still be available (via the extension on `Sequence`) and will be called if forced through type context. The only code that will break is if this operation spans -multple lines: +multiple lines: ```swift // filtered used to be [Character], now String diff --git a/proposals/0176-enforce-exclusive-access-to-memory.md b/proposals/0176-enforce-exclusive-access-to-memory.md index 3deef84685..f11512ff96 100644 --- a/proposals/0176-enforce-exclusive-access-to-memory.md +++ b/proposals/0176-enforce-exclusive-access-to-memory.md @@ -740,7 +740,7 @@ automatically to avoid source-compatibility problems. ## Effect on ABI stability and resilience -In order to gain the performance and language-desing benefits of +In order to gain the performance and language-design benefits of exclusivity, we must be able to assume that it is followed faithfully in various places throughout the ABI. Therefore, exclusivity must be enforced before we commit to a stable ABI, or else we'll be stuck with diff --git a/proposals/0180-string-index-overhaul.md b/proposals/0180-string-index-overhaul.md index 1593ba1c1f..abe8de6074 100644 --- a/proposals/0180-string-index-overhaul.md +++ b/proposals/0180-string-index-overhaul.md @@ -129,7 +129,7 @@ let tagEnd = html.utf16[tagStart...].index(of: close) let tag = html[tagStart...tagEnd] ``` -A property and an intializer will be added to `String.Index`, exposing +A property and an initializer will be added to `String.Index`, exposing the offset of the index in code units (currently only UTF-16) from the beginning of the string: diff --git a/proposals/0183-substring-affordances.md b/proposals/0183-substring-affordances.md index 854ec865ef..eb83064787 100644 --- a/proposals/0183-substring-affordances.md +++ b/proposals/0183-substring-affordances.md @@ -74,7 +74,7 @@ case of `filter`). ## Effect on ABI stability -The switch from conrete to generic types needs to be made before ABI stability. +The switch from concrete to generic types needs to be made before ABI stability. ## Alternatives considered diff --git a/proposals/0193-cross-module-inlining-and-specialization.md b/proposals/0193-cross-module-inlining-and-specialization.md index 20a15b047e..bbdcc7305a 100644 --- a/proposals/0193-cross-module-inlining-and-specialization.md +++ b/proposals/0193-cross-module-inlining-and-specialization.md @@ -171,7 +171,7 @@ The closest analogue in C to `@usableFromInline` is a non-`static` function that ## Alternatives considered -One possible alterative would be to add a new compiler mode where _all_ declarations become implicitly `@inlinable`, and _all_ private and internal declarations become `@usableFromInline`. +One possible alternative would be to add a new compiler mode where _all_ declarations become implicitly `@inlinable`, and _all_ private and internal declarations become `@usableFromInline`. However, such a compilation mode would not solve the problem of delivering a stable ABI and standard library which can be deployed separately from user code. We _don't want_ all declaration bodies in the standard library to be available to the optimizer when building user code. diff --git a/proposals/0196-diagnostic-directives.md b/proposals/0196-diagnostic-directives.md index 51133c3744..2b69a98991 100644 --- a/proposals/0196-diagnostic-directives.md +++ b/proposals/0196-diagnostic-directives.md @@ -155,7 +155,7 @@ On February 1, 2018 the Core Team decided to **accept** this proposal with slight revision over the [original proposal](https://github.com/swiftlang/swift-evolution/blob/ab0c22a2340be9bfcb82e6f237752b4d959a93b7/proposals/0196-diagnostic-directives.md). The only revision over the original proposal is to change the syntax to use -`#warning()` instead of `#warning `. This fits well with +`#warning()` instead of `#warning `. This fits well with most of Swift's existing compiler directives, and was strongly supported in the [review discussion](https://forums.swift.org/t/se-0196-compiler-diagnostic-directives/8734). diff --git a/proposals/0198-playground-quicklook-api-revamp.md b/proposals/0198-playground-quicklook-api-revamp.md index 59b4d0722f..7b6608d542 100644 --- a/proposals/0198-playground-quicklook-api-revamp.md +++ b/proposals/0198-playground-quicklook-api-revamp.md @@ -261,7 +261,7 @@ support the replacement of `CustomPlaygroundQuickLookable` with `CustomPlaygroundDisplayConvertible`. Instead, we intend for Swift 4.1 to be a deprecation period for these APIs, allowing any code bases which implement `CustomPlaygroundQuickLookable` to manually switch to the new protocol. While -this migration may not be trivial programatically, it should -- in most cases -- +this migration may not be trivial programmatically, it should -- in most cases -- be fairly trivial for someone to hand-migrate to `CustomPlaygroundDisplayConvertible`. During the deprecation period, the PlaygroundLogger framework will continue to honor implementations of diff --git a/proposals/0207-containsOnly.md b/proposals/0207-containsOnly.md index df5aa065c7..c82a4d6fa2 100644 --- a/proposals/0207-containsOnly.md +++ b/proposals/0207-containsOnly.md @@ -75,4 +75,4 @@ This change is purely additive so has no API resilience consequences. Not adding it, since it can be trivially (if confusingly) composed. -Much name bikeshedding has ensued. Names considered included `containsOnly` and `all`. `all` has strong precedent in other languages, but was considered unclear at the call site (adding an argument label does not help here given trailing closures omit them). Naming it `all` suggests a renaming of `contains` to `any` would be appropriate – but this is already a fairly heavily-used term elsewhere in Swift, and is less explicit. `containsOnly` is more explicit, and echoes the existing `contains`, but is too easily misread at the use-site as “contains one instance equal to,” especially when considering empty collections. `contains(only:)` was discounted due to trailing closures dropping the argument label, rendering it indistiguishable from `contains(where:)`. +Much name bikeshedding has ensued. Names considered included `containsOnly` and `all`. `all` has strong precedent in other languages, but was considered unclear at the call site (adding an argument label does not help here given trailing closures omit them). Naming it `all` suggests a renaming of `contains` to `any` would be appropriate – but this is already a fairly heavily-used term elsewhere in Swift, and is less explicit. `containsOnly` is more explicit, and echoes the existing `contains`, but is too easily misread at the use-site as “contains one instance equal to,” especially when considering empty collections. `contains(only:)` was discounted due to trailing closures dropping the argument label, rendering it indistinguishable from `contains(where:)`. diff --git a/proposals/0209-package-manager-swift-lang-version-update.md b/proposals/0209-package-manager-swift-lang-version-update.md index def6f95c7d..78b2825f32 100644 --- a/proposals/0209-package-manager-swift-lang-version-update.md +++ b/proposals/0209-package-manager-swift-lang-version-update.md @@ -17,7 +17,7 @@ array. The Swift compiler now allows `4.2` as an accepted value of Swift version flag (`-swift-version`). The `swiftLanguageVersions` API in `Package.swift` currently -accepts an interger array and we need to update this API in order for packages +accepts an integer array and we need to update this API in order for packages to declare this language version if required. ## Proposed solution diff --git a/proposals/0223-array-uninitialized-initializer.md b/proposals/0223-array-uninitialized-initializer.md index 024899b158..cd78c92bc4 100644 --- a/proposals/0223-array-uninitialized-initializer.md +++ b/proposals/0223-array-uninitialized-initializer.md @@ -53,7 +53,7 @@ The new initializer takes a closure that operates on an `UnsafeMutableBufferPoin and an `inout` count of initialized elements. This closure has access to the uninitialized contents of the newly created array's storage, -and must set the intialized count of the array before exiting. +and must set the initialized count of the array before exiting. ```swift var myArray = Array(unsafeUninitializedCapacity: 10) { buffer, initializedCount in diff --git a/proposals/0228-fix-expressiblebystringinterpolation.md b/proposals/0228-fix-expressiblebystringinterpolation.md index 2acc16717b..701036698b 100644 --- a/proposals/0228-fix-expressiblebystringinterpolation.md +++ b/proposals/0228-fix-expressiblebystringinterpolation.md @@ -508,7 +508,7 @@ String(stringInterpolation: .literal("!")) ``` -However, this requires that conformers expose a homogenous return value, which has expressibility and/or efficiency drawbacks. The proposed approach, which is statement based, keeps this as a detail internal to the conformer. +However, this requires that conformers expose a homogeneous return value, which has expressibility and/or efficiency drawbacks. The proposed approach, which is statement based, keeps this as a detail internal to the conformer. ### Have a formal `appendInterpolation(_:)` requirement diff --git a/proposals/0231-optional-iteration.md b/proposals/0231-optional-iteration.md index cb8ac69f6d..ec8dd5f227 100644 --- a/proposals/0231-optional-iteration.md +++ b/proposals/0231-optional-iteration.md @@ -27,7 +27,7 @@ default: print() } ``` -Optional patterns bring a succint way of handling the `.some` case when optional binding is unavailable: +Optional patterns bring a succinct way of handling the `.some` case when optional binding is unavailable: ```swift for case let unwrapped? in sequence { ... } @@ -86,7 +86,7 @@ if let unwrappedArray = array { } ``` -The `?` notation here is a semantic emphasis rather than a functional unit: there is no `for!`. Syntactically marking an optional iteration is redundant, however, in constrast to `switch`, nil values are *skipped silently*. Swift strives to follow a style where silent handling of `nil` is acknowledged via the `?` sigil, distinctly reflected in optional chaining syntax. This decision was primarily based on inconsistency and potential confusion that an otherwise left without syntactic changes `for-in` loop could potentially lead to ("clarity over brevity"). +The `?` notation here is a semantic emphasis rather than a functional unit: there is no `for!`. Syntactically marking an optional iteration is redundant, however, in contrast to `switch`, nil values are *skipped silently*. Swift strives to follow a style where silent handling of `nil` is acknowledged via the `?` sigil, distinctly reflected in optional chaining syntax. This decision was primarily based on inconsistency and potential confusion that an otherwise left without syntactic changes `for-in` loop could potentially lead to ("clarity over brevity"). ``` swift for element in optionalArray { ... } // Silently handling optionals implicitly is a style that Swift prefers to eschew. diff --git a/proposals/0235-add-result.md b/proposals/0235-add-result.md index d7e7f7d733..f4b979f6f7 100644 --- a/proposals/0235-add-result.md +++ b/proposals/0235-add-result.md @@ -293,7 +293,7 @@ This proposal adds a type to the standard library and so will affect the ABI onc ## Effect on API resilience -Addition of `Result` should be future proof against additional needs surrounding error handling. +Addition of `Result` should be future proof against additional needs surrounding error handling. ## Alternatives considered diff --git a/proposals/0240-ordered-collection-diffing.md b/proposals/0240-ordered-collection-diffing.md index 9e64b5a25f..b75c0a8448 100644 --- a/proposals/0240-ordered-collection-diffing.md +++ b/proposals/0240-ordered-collection-diffing.md @@ -64,7 +64,7 @@ extension BidirectionalCollection { /// - areEquivalent: A closure that returns whether the two /// parameters are equivalent. /// - /// - Returns: The difference needed to produce the reciever's state from + /// - Returns: The difference needed to produce the receiver's state from /// the parameter's state. /// /// - Complexity: For pathological inputs, worst case performance is @@ -87,7 +87,7 @@ extension BidirectionalCollection where Element: Equatable { /// - Parameters: /// - other: The base state. /// - /// - Returns: The difference needed to produce the reciever's state from + /// - Returns: The difference needed to produce the receiver's state from /// the parameter's state. /// /// - Complexity: For pathological inputs, worst case performance is diff --git a/proposals/0243-codepoint-and-character-literals.md b/proposals/0243-codepoint-and-character-literals.md index 048bbc907c..6890ca77cf 100644 --- a/proposals/0243-codepoint-and-character-literals.md +++ b/proposals/0243-codepoint-and-character-literals.md @@ -154,7 +154,7 @@ In Swift 1.0, single quotes were reserved for some yet-to-be determined syntacti - In current discussions around [regex literals](https://forums.swift.org/t/string-update/7398/6), most people seem to prefer slashes (`/`). -Given that, and the desire for lightweight syntax for single chararcter syntax, and the precedent in other languages for characters, it is natural to use single quotes for this purpose. +Given that, and the desire for lightweight syntax for single character syntax, and the precedent in other languages for characters, it is natural to use single quotes for this purpose. ### Existing double quote initializers for characters diff --git a/proposals/0244-opaque-result-types.md b/proposals/0244-opaque-result-types.md index da3ea39a61..a6404963e1 100644 --- a/proposals/0244-opaque-result-types.md +++ b/proposals/0244-opaque-result-types.md @@ -634,7 +634,7 @@ The one using opaque typealiases requires an intermediate name, which one must r ## Future Directions -As noted in the introduction, this proposal is the first part of a group of changes we're considering in a [design document for improving the UI of the generics model](https://forums.swift.org/t/improving-the-ui-of-generics/22814). That design document lays out a number of related directions we can go based on the foundation establised by this proposal, including: +As noted in the introduction, this proposal is the first part of a group of changes we're considering in a [design document for improving the UI of the generics model](https://forums.swift.org/t/improving-the-ui-of-generics/22814). That design document lays out a number of related directions we can go based on the foundation established by this proposal, including: - allowing [fully generalized reverse generics](https://forums.swift.org/t/improving-the-ui-of-generics/22814#heading--reverse-generics) - [generalizing the `some` syntax](https://forums.swift.org/t/improving-the-ui-of-generics/22814#heading--directly-expressing-constraints) as shorthand for generic arguments, and allowing structural use in generic returns diff --git a/proposals/0245-array-uninitialized-initializer.md b/proposals/0245-array-uninitialized-initializer.md index 7180c5ec9b..28c017a2b9 100644 --- a/proposals/0245-array-uninitialized-initializer.md +++ b/proposals/0245-array-uninitialized-initializer.md @@ -46,7 +46,7 @@ buffer. The new initializer takes a closure that operates on an `UnsafeMutableBufferPointer` and an `inout` count of initialized elements. This closure has access to the uninitialized contents of the newly created array's -storage, and must set the intialized count of the array before exiting. +storage, and must set the initialized count of the array before exiting. ```swift var myArray = Array(unsafeUninitializedCapacity: 10) { buffer, initializedCount in diff --git a/proposals/0246-mathable.md b/proposals/0246-mathable.md index dae0a33fc3..c4fe2be0a8 100644 --- a/proposals/0246-mathable.md +++ b/proposals/0246-mathable.md @@ -311,7 +311,7 @@ to want only the first value, so returning a tuple creates noise: re-exported in Swift where `lgamma` is ambiguous; it can be either the platform shim returning `(T, Int)`, or the C library function returning `Double`; we want to deprecate the first and make the second unavailable. -Simulataneously introducing yet another function with the same name would +Simultaneously introducing yet another function with the same name would create a bit of a mess. ### Future expansion diff --git a/proposals/0253-callable.md b/proposals/0253-callable.md index bf59d62b45..035161bc7b 100644 --- a/proposals/0253-callable.md +++ b/proposals/0253-callable.md @@ -595,7 +595,7 @@ struct Adder { We feel this approach is not ideal because 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. -There's also an unforunate edge case that must be explicitly handled: if a +There's also an unfortunate edge case that must be explicitly handled: if a `@staticCallable` type defines no call-syntax delegate methods, an error must be produced. diff --git a/proposals/0254-static-subscripts.md b/proposals/0254-static-subscripts.md index ca63840d4f..fdc1935b81 100644 --- a/proposals/0254-static-subscripts.md +++ b/proposals/0254-static-subscripts.md @@ -98,7 +98,7 @@ Objective-C class methods with the same selectors as instance subscript methods ## Source compatibility -This proposal is purely additive; it does not change any prevously existing behavior. All syntax it will add support for was previously illegal. +This proposal is purely additive; it does not change any previously existing behavior. All syntax it will add support for was previously illegal. ## ABI compatibility and backwards deployment diff --git a/proposals/0259-approximately-equal.md b/proposals/0259-approximately-equal.md index ff167fbb1b..c8a1249e4f 100644 --- a/proposals/0259-approximately-equal.md +++ b/proposals/0259-approximately-equal.md @@ -133,7 +133,7 @@ extension FloatingPoint { tolerance: Self = Self.ulpOfOne.squareRoot() ) -> Bool { // tolerances outside of [.ulpOfOne,1) yield well-defined but useless results, - // so this is enforced by an assert rathern than a precondition. + // so this is enforced by an assert rather than a precondition. assert(tolerance >= .ulpOfOne && tolerance < 1, "tolerance should be in [.ulpOfOne, 1).") // The simple computation below does not necessarily give sensible // results if one of self or other is infinite; we need to rescale diff --git a/proposals/0260-library-evolution.md b/proposals/0260-library-evolution.md index 7d19902b08..e14420908c 100644 --- a/proposals/0260-library-evolution.md +++ b/proposals/0260-library-evolution.md @@ -27,7 +27,7 @@ _Note: this proposal will use the word "field" to mean "stored instance property As of Swift 5, libraries are able to declare a stable ABI, allowing a library binary to be replaced with a newer version without requiring client programs to be recompiled. -What consitutes the ABI of a library differs from language to language. In C and C++, the public ABI for a library includes information that ideally would be kept purely as an implementation detail. For example, the _size_ of a struct is fixed as part of the ABI, and is known to the library user at compile time. This prevents adding new fields to that type in later releases once the ABI is declared stable. If direct access to fields is allowed, the _layout_ of the struct can also become part of the ABI, so fields cannot then be reordered. +What constitutes the ABI of a library differs from language to language. In C and C++, the public ABI for a library includes information that ideally would be kept purely as an implementation detail. For example, the _size_ of a struct is fixed as part of the ABI, and is known to the library user at compile time. This prevents adding new fields to that type in later releases once the ABI is declared stable. If direct access to fields is allowed, the _layout_ of the struct can also become part of the ABI, so fields cannot then be reordered. This often leads to manual workarounds. A common technique is to have the struct hold only a pointer to an "impl" type, which holds the actual stored properties. All access to these properties is made via function calls, which can be updated to handle changes to the layout of the "impl" type. This has some obvious downsides: diff --git a/proposals/0261-identifiable.md b/proposals/0261-identifiable.md index 48fcc60f47..c19eda84de 100644 --- a/proposals/0261-identifiable.md +++ b/proposals/0261-identifiable.md @@ -101,7 +101,7 @@ doesn't move to the standard library Swift programmers will need to continue using their own variation of this protocol and will need to ensure it is able co-exist with other similar definitions found in other frameworks higher up the dependency stack. Unfortunately none these variations -are likey to be compatible with one another. +are likely to be compatible with one another. ## Proposed solution diff --git a/proposals/0275-allow-more-characters-like-whitespaces-and-punctuations-for-escaped-identifiers.md b/proposals/0275-allow-more-characters-like-whitespaces-and-punctuations-for-escaped-identifiers.md index 0129be339a..c2423c71e4 100644 --- a/proposals/0275-allow-more-characters-like-whitespaces-and-punctuations-for-escaped-identifiers.md +++ b/proposals/0275-allow-more-characters-like-whitespaces-and-punctuations-for-escaped-identifiers.md @@ -107,10 +107,10 @@ It was considered to extend the grammars for methods declaration only, this was It was suggested, as an alternative, for the testing method names use case to add a method attribute: ``` @test("test validation should succeed when input is less than ten") -func testValidationShouldSuccedWhenInputIsLessThanTen() {} +func testValidationShouldSucceedWhenInputIsLessThanTen() {} ``` It was not considered a valid option for few reasons: -* it introduces information redudancy +* it introduces information redundancy * it is not applicable for the rest of the issues mentioned above * adding a new attribute would likely to introduce more complexity to the compiler and to the test runner diff --git a/proposals/0290-negative-availability.md b/proposals/0290-negative-availability.md index bca419bdc5..2d43fdcce4 100644 --- a/proposals/0290-negative-availability.md +++ b/proposals/0290-negative-availability.md @@ -193,7 +193,7 @@ if #available(iOS 12, iOS 13, *) // Error: Version for 'iOS' already specified Additionally, the specification of different platforms have no effect on the final result -- it depends *only* on the (unique) spec that matches the current platform being compiled. A check like `#available(iOS 12, watchOS 4, *)` compiled in iOS doesn't mean "return true if (iOS 12 **||** watchOS 4 **||** the current platform's minimum deployment target) is available", it simply means "return true if iOS 12 is available". The specs that refer to different platforms are ignored. -Finally, the wildcard represents *only* the platforms that were not explicitly specified in the spec list. When `#available(iOS 13, *)` is compiled for iOS, the wildcard will be ignored in favor of the explictly defined iOS 13 spec. As mentioned before, a platform can only be mentioned once. +Finally, the wildcard represents *only* the platforms that were not explicitly specified in the spec list. When `#available(iOS 13, *)` is compiled for iOS, the wildcard will be ignored in favor of the explicitly defined iOS 13 spec. As mentioned before, a platform can only be mentioned once. For unavailability, the semantics mentioned above means that `#unavailable(*)` and `#unavailable(notWhatImCompiling X, *)` should do the opposite of `#available` and return `false`. Since the minimum deployment target will always be present, the statement can never be true. This behavior is exactly how the current workaround works, and it also matches how the theoretical `!#available(*)` would behave. @@ -242,7 +242,7 @@ On the other hand, given that it's fair to consider that this is a developer's f One point of discussion was the importance of the wildcard in the case of unavailability. Because the wildcard achieves nothing in terms of functionality, we considered alternatives that involved omitting or removing it completely. However, the wildcard is still important from a platform migration point of view, because although we don't need to force the guarded branch to be executed like in `#available`, the presence of the wildcard still play its intended role of allowing code involving unavailability statements to be ported to different platforms without requiring every single statement to be modified. -Additionally, we had lenghty discussions about the *readability* of unavailability statements. We've noticed that even though availability in Swift has never been a boolean expression, it was clear that pretty much every developer's first instinct is to assume that `(iOS 12, *)` is equivalent to `iOS 12 || *`. The main point of discussion then was that the average developer might not understand why a call like `#unavailable(iOS 12, *)` will return `false` in non-iOS platforms, because they will assume the list means `iOS 12 || *` (`true`), while in reality (and as described in the `Semantics` section) the list means just `*` (`false`). During the pitch we tried to come up with alternatives that could eliminate this, and although some of them *did* succeed in doing that, they were doing so at the cost of making `#unavailable` "misleading", just like in the case of `!#available`. We ultimately decided that these improvements would be better suited for a *separate* proposal that focused on improving spec lists in general, which will be mentioned again at the end of this section. +Additionally, we had lengthy discussions about the *readability* of unavailability statements. We've noticed that even though availability in Swift has never been a boolean expression, it was clear that pretty much every developer's first instinct is to assume that `(iOS 12, *)` is equivalent to `iOS 12 || *`. The main point of discussion then was that the average developer might not understand why a call like `#unavailable(iOS 12, *)` will return `false` in non-iOS platforms, because they will assume the list means `iOS 12 || *` (`true`), while in reality (and as described in the `Semantics` section) the list means just `*` (`false`). During the pitch we tried to come up with alternatives that could eliminate this, and although some of them *did* succeed in doing that, they were doing so at the cost of making `#unavailable` "misleading", just like in the case of `!#available`. We ultimately decided that these improvements would be better suited for a *separate* proposal that focused on improving spec lists in general, which will be mentioned again at the end of this section. In general, there was much worry that this confusion could cause developers to misuse `#unavailable` and introduce bugs in their applications. We can prove that this feeling cannot happen in practice by how `#unavailable` doesn't introduce any new behavior -- it's nothing more than a reversed `#available` with a reversed literal name, which is semantically no different than the current workaround of using the `else` branch. Any confusing `#unavailable` scenario can also be conveyed as a confusing `#available` scenario by simply swapping the branches. diff --git a/proposals/0295-codable-synthesis-for-enums-with-associated-values.md b/proposals/0295-codable-synthesis-for-enums-with-associated-values.md index eeb9245f08..599e2db532 100644 --- a/proposals/0295-codable-synthesis-for-enums-with-associated-values.md +++ b/proposals/0295-codable-synthesis-for-enums-with-associated-values.md @@ -196,7 +196,7 @@ public init(from decoder: Decoder) throws { ### User customization -For the existing cases, users can customize which properties are included in the encoded respresentation +For the existing cases, users can customize which properties are included in the encoded representation and map the property name to a custom name for the encoded representation by providing a custom `CodingKeys` declaration, instead of having the compiler generate one. The same should apply to the enum case. diff --git a/proposals/0296-async-await.md b/proposals/0296-async-await.md index d7c0b5c89b..6c32790ac6 100644 --- a/proposals/0296-async-await.md +++ b/proposals/0296-async-await.md @@ -486,7 +486,7 @@ In the first case, Swift's overloading rules prefer to call a function with fewe error: `async` function cannot be called from non-asynchronous context ``` -This presents problems for code evolution, because developers of existing asynchronous libraries would have to either have a hard compatiblity break (e.g, to a new major version) or would need have different names for all of the new `async` versions. The latter would likely result in a scheme such as [C#'s pervasive `Async` suffix](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/task-asynchronous-programming-model). +This presents problems for code evolution, because developers of existing asynchronous libraries would have to either have a hard compatibility break (e.g, to a new major version) or would need have different names for all of the new `async` versions. The latter would likely result in a scheme such as [C#'s pervasive `Async` suffix](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/task-asynchronous-programming-model). The second case, where both functions have the same signature and only differ in `async`, is normally rejected by existing Swift's overloading rules. Those do not allow two functions to differ only in their *effects*, and one can not define two functions that only differ in `throws`, for example. diff --git a/proposals/0298-asyncsequence.md b/proposals/0298-asyncsequence.md index 5e70db8c35..d0899264df 100644 --- a/proposals/0298-asyncsequence.md +++ b/proposals/0298-asyncsequence.md @@ -230,7 +230,7 @@ With this extension, our "first long line" example from earlier becomes simply: let first = try? await myFile.lines().first(where: { $0.count > 80 }) ``` -Or, if the sequence should be processed asynchonously and used later: +Or, if the sequence should be processed asynchronously and used later: ```swift async let first = myFile.lines().first(where: { $0.count > 80 }) diff --git a/proposals/0303-swiftpm-extensible-build-tools.md b/proposals/0303-swiftpm-extensible-build-tools.md index 12ece94388..7761d1b5d5 100644 --- a/proposals/0303-swiftpm-extensible-build-tools.md +++ b/proposals/0303-swiftpm-extensible-build-tools.md @@ -431,7 +431,7 @@ struct Diagnostics { static func remark(_ message: String, file: Path? = #file, line: Int? = #line) /// Emits a diagnostic with the specified severity and descriptive message. - static func emit(_ severity: Serverity, _ message: String, file: Path? = #file, line: Int? = #line) + static func emit(_ severity: Severity, _ message: String, file: Path? = #file, line: Int? = #line) /// The seriousness with which the diagnostic is treated. An error causes /// SwiftPM to consider the plugin to have failed to run. @@ -547,11 +547,11 @@ Prebuild commands should be used when the tool being invoked can produce outputs ##### Build Commands -Commands of type `.buildCommand` that are retured by the plugin are incorporated into the build system's dependency graph, so that they run as needed during the build, based on their declared inputs and outputs. This requires that the paths of any outputs can be known before the command is run. This is usually done by forming the names of the outputs based on some combination of the output directory and the name of the input file. +Commands of type `.buildCommand` that are returned by the plugin are incorporated into the build system's dependency graph, so that they run as needed during the build, based on their declared inputs and outputs. This requires that the paths of any outputs can be known before the command is run. This is usually done by forming the names of the outputs based on some combination of the output directory and the name of the input file. Examples of plugins that can use regular build commands include compiler-like translators such as Protobuf and other tools that take a fixed set of inputs and produce a fixed set of outputs. (note that one nuance with Protobuf in particular is that it is actually up to the source generator invoked by `protoc` to determine the output paths — however, the relevant source generators for Swift and C do produce output files with predictable names). -Other examples include translators that "compile" data files in JSON or other editable formats to a suitable binary runtime respresentation. +Other examples include translators that "compile" data files in JSON or other editable formats to a suitable binary runtime representation. Regular build commands with defined outputs are preferable whenever possible, because such commands don't have to run unless their outputs are missing or their inputs have changed since the last time they ran. @@ -867,7 +867,7 @@ import Foundation // Create a module mappings file. This is something that the Swift source // generator `protoc` plug-in we are using requires. The details are not // important for this proposal, except that it needs to be able to be con- - // structed from the information in the context given to the plugin, and + // structured from the information in the context given to the plugin, and // to be written out to the intermediates directory. let moduleMappingsFile = otherFilesDir.appending("module-mappings") let outputString = ". . . module mappings file . . ." diff --git a/proposals/0306-actors.md b/proposals/0306-actors.md index 8dda3655eb..4a1d6d0ee0 100644 --- a/proposals/0306-actors.md +++ b/proposals/0306-actors.md @@ -544,7 +544,7 @@ We'll describe each scenario in detail. An actor-isolated non-`async` declaration can only be synchronously accessed from another declaration that is isolated to the same actor. For synchronous access to an actor-isolated function, the function must be called from another actor-isolated function. For synchronous access to an actor-isolated instance property or instance subscript, the instance itself must be actor-isolated. -An actor-isolated declaration can be asynchronously accessed from any declaration, whether it is isolated to another actor or is non-isolated. Such accesses are asynchronous operations, and therefore must be annotated with `await`. Semantically, the progam will switch to the actor to perform the synchronous operation, and then switch back to the caller's executor afterward. +An actor-isolated declaration can be asynchronously accessed from any declaration, whether it is isolated to another actor or is non-isolated. Such accesses are asynchronous operations, and therefore must be annotated with `await`. Semantically, the program will switch to the actor to perform the synchronous operation, and then switch back to the caller's executor afterward. For example: diff --git a/proposals/0309-unlock-existential-types-for-all-protocols.md b/proposals/0309-unlock-existential-types-for-all-protocols.md index 72a4f71ff1..460d97f02d 100644 --- a/proposals/0309-unlock-existential-types-for-all-protocols.md +++ b/proposals/0309-unlock-existential-types-for-all-protocols.md @@ -80,7 +80,7 @@ Removing the type-level restriction would mean that adding defaulted requirement ### Type-Erasing Wrappers -Beyond making incremental progress toward the goal of [generalized existentials](https://github.com/apple/swift/blob/main/docs/GenericsManifesto.md#generalized-existentials), removing this restriction is a necessary — albeit not sufficient — condition for eliminating the need for manual type-erasing wrappers like [`AnySequence`](https://developer.apple.com/documentation/swift/anysequence). These containers are not always straightforward to implement, and can become a pain to mantain in resilient environments, since the wrapper must evolve in parallel to the protocol. In the meantime, wrapping the unconstrained existential type instead of resorting to `Any` or boxing the value in a subclass or closure will enable type-erasing containers to be written in a way that's easier for the compiler to optimize, and ABI-compatible with future generalized existentials. For requirements that cannot be accessed on the existential directly, it will be possible to forward the call through the convolution of writing protocol extension methods to open the value inside and have full access to the protocol interface inside the protocol extension: +Beyond making incremental progress toward the goal of [generalized existentials](https://github.com/apple/swift/blob/main/docs/GenericsManifesto.md#generalized-existentials), removing this restriction is a necessary — albeit not sufficient — condition for eliminating the need for manual type-erasing wrappers like [`AnySequence`](https://developer.apple.com/documentation/swift/anysequence). These containers are not always straightforward to implement, and can become a pain to maintain in resilient environments, since the wrapper must evolve in parallel to the protocol. In the meantime, wrapping the unconstrained existential type instead of resorting to `Any` or boxing the value in a subclass or closure will enable type-erasing containers to be written in a way that's easier for the compiler to optimize, and ABI-compatible with future generalized existentials. For requirements that cannot be accessed on the existential directly, it will be possible to forward the call through the convolution of writing protocol extension methods to open the value inside and have full access to the protocol interface inside the protocol extension: ```swift protocol Foo { @@ -314,7 +314,7 @@ Though, if we *were* going to introduce a new syntax for existentials, we think * Simplify the implementation of Standard Library type-erasing wrappers, such as [`AnyHashable`](https://github.com/apple/swift/blob/main/stdlib/public/core/AnyHashable.swift) and [`AnyCollection`](https://github.com/apple/swift/blob/main/stdlib/public/core/ExistentialCollection.swift), using the practical advice from [earlier](#type-erasing-wrappers). * Deemphasize existential types. - It is often that people reach for existential types when they should be employing generic contraints — "should" not merely for performance reasons, but because they truly do not need or intend for any type erasure. Even though the compiler is sometimes able to back us up performance-wise by turning existential code into generic code (as in `func foo(s: Sequence)` vs `func foo(s: S)`), there is an important difference between the two abstractions. Existential types provide value-level abstraction, that is, they eliminate the type-level distinction between different values of the type, and cannot maintain type relationships between independent existential values. Under most cirumstances, value-level abstraction only really makes sense in mutable state, in the elements of heterogeneous containers, or, unless our support of [`some` types](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0244-opaque-result-types.md) can turn the tide, in the storage of larger type-erasing constructs. A fitting starting point for giving value-level abstraction more careful consideration early on is the [Language Guide](https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html). + It is often that people reach for existential types when they should be employing generic constraints — "should" not merely for performance reasons, but because they truly do not need or intend for any type erasure. Even though the compiler is sometimes able to back us up performance-wise by turning existential code into generic code (as in `func foo(s: Sequence)` vs `func foo(s: S)`), there is an important difference between the two abstractions. Existential types provide value-level abstraction, that is, they eliminate the type-level distinction between different values of the type, and cannot maintain type relationships between independent existential values. Under most circumstances, value-level abstraction only really makes sense in mutable state, in the elements of heterogeneous containers, or, unless our support of [`some` types](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0244-opaque-result-types.md) can turn the tide, in the storage of larger type-erasing constructs. A fitting starting point for giving value-level abstraction more careful consideration early on is the [Language Guide](https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html). * Make existential types "self-conforming" by automatically opening them when passed as generic arguments to functions. Generic instantiations could have them opened as opaque types. * Add an `init(_ box: Hashable)` initializer to `AnyHashable` to alleviate confusion and aid in usability. This initializer would be treated as a workaround, and deprecated should automatic opening of existential types become available. * Introduce [`any P` as a dual to `some P`](https://forums.swift.org/t/improving-the-ui-of-generics/22814#heading--clarifying-existentials) for explicitly spelling existential types. diff --git a/proposals/0310-effectful-readonly-properties.md b/proposals/0310-effectful-readonly-properties.md index 370cc91d49..af9dc2b7d8 100644 --- a/proposals/0310-effectful-readonly-properties.md +++ b/proposals/0310-effectful-readonly-properties.md @@ -347,7 +347,7 @@ There are a number of places where the effects specifiers be placed: Where `` refers to "position X" in the example. Consider each of these positions: * **Position A** is primarily used by access modifiers like `private(set)` or declaration modifiers like `override`. The more effect-like `mutating`/`nonmutating` is only allowed in Position C, which precedes the accessor declaration, just like a method within a struct. This position was not chosen because phrases like `override async throws var prop` or `async throws override var prop` do not read particularly well. -* **Position B** does not make much sense, because effects are only carried as part of a function type, not other types. So, it would be very confusing, leading people to think `Int async throws` is a type, when that is not. Introducing a new kind of punctuation here was ruled out because there are alteratives to this position. +* **Position B** does not make much sense, because effects are only carried as part of a function type, not other types. So, it would be very confusing, leading people to think `Int async throws` is a type, when that is not. Introducing a new kind of punctuation here was ruled out because there are alternatives to this position. * **Position C** is not bad; it's only occupied by `mutating`/`nonmutating`, but placing effects specifiers here is not consistent with the positioning for functions, which is *after* the subject. Since Position D is available, it makes more sense to use that instead of Position C. * **Position D** is the one ultimately chosen for this proposal. It is an unused place in the grammar, places the effects on the accessor and not the variable or its type. Plus, it is consistent with where effects go on a function declaration, after the subject: `get throws` and `get async throws`, where get is the subject. Another benefit is that it is away from the variable, so it prevents confusion between the accessor's effects and the effects of a function being returned: diff --git a/proposals/0311-task-locals.md b/proposals/0311-task-locals.md index 4c3f895014..d6f48593e5 100644 --- a/proposals/0311-task-locals.md +++ b/proposals/0311-task-locals.md @@ -116,7 +116,7 @@ Each task-local declaration represents its own, independent task-local storage. Because of those pitfalls with creating multiple instances of the same task local identifier, we propose to diagnose and fail at compile time if the `@TaskLocal` property wrapper is not defined on a static or global property. -> In order to do so, we will extend the internal `public static subscript(_enclosingInstance object: T, ...)` subscript mechanism to require "no enclosing instance", which will cause the apropriate compile time error reporting to be triggered if such wrapper is used on a non-static or non-global property. +> In order to do so, we will extend the internal `public static subscript(_enclosingInstance object: T, ...)` subscript mechanism to require "no enclosing instance", which will cause the appropriate compile time error reporting to be triggered if such wrapper is used on a non-static or non-global property. The diagnosed error would look like this: @@ -499,7 +499,7 @@ await withTaskGroup(...) { group in ### Task-local value lifecycle -Task-local values are retained until `withValue`'s `operation` scope exits. Effectively this means that the value is kept alive until all child tasks created in such scope exit as well. This is important because child tasks may be refering to this specific value in the parent task, so it cannot be released earlier. +Task-local values are retained until `withValue`'s `operation` scope exits. Effectively this means that the value is kept alive until all child tasks created in such scope exit as well. This is important because child tasks may be referring to this specific value in the parent task, so it cannot be released earlier. Both value and reference types are allowed to be stored in task-local storage, using their expected respective semantics: @@ -951,7 +951,7 @@ Dispatch offers APIs that allow setting values that are _specific to a dispatch These APIs serve their purpose well, however they are incompatible with Swift Concurrency's task-focused model. Even if actors and asynchronous functions execute on dispatch queues, no capability to carry values over multiple queues is given, which is necessary to work well with Swift Concurrency, as execution may hop back and forth between queues. ## Intended use-cases -It is important to keep in mind the intended use case of this API. Task-local values are not intended to replace passing parameters where doing so explicitly is the right tool for the job. Please note that task local storage is more expensive to access than parameters passed explicitly. They also are "invisible" in API, so take care to avoid accidentally building APIs which absolutely must have some task local value set when they are called as this is very suprising and hard to debug behavior. +It is important to keep in mind the intended use case of this API. Task-local values are not intended to replace passing parameters where doing so explicitly is the right tool for the job. Please note that task local storage is more expensive to access than parameters passed explicitly. They also are "invisible" in API, so take care to avoid accidentally building APIs which absolutely must have some task local value set when they are called as this is very surprising and hard to debug behavior. Only use task local storage for auxiliary _metadata_ or "_execution scoped configuration_", like mocking out some runtime bits for the duration of a _specific call_ but not globally, etc. @@ -1195,7 +1195,7 @@ Some, specialized use-cases however can declare more specific inheritance semant A `TaskLocal` type may declare an inheritance semantics by defining the static `inherit` parameter when declaring the variable: `TaskLocal(inherit: .never)`. -The semantics default to `.default`, which are what one would expect normally — that child tasks are able to lookup values defined in their parents, unless overriden in that specific child. We will discuss the exact semantics of lookups in depth in [Reading task-local values](#reading-task-local-values). +The semantics default to `.default`, which are what one would expect normally — that child tasks are able to lookup values defined in their parents, unless overridden in that specific child. We will discuss the exact semantics of lookups in depth in [Reading task-local values](#reading-task-local-values). In this proposal, we introduce two additional inheritance semantics: `.never` and `.alwaysBestEffort`: diff --git a/proposals/0313-actor-isolation-control.md b/proposals/0313-actor-isolation-control.md index 89fb4d8b6b..72f35a9d04 100644 --- a/proposals/0313-actor-isolation-control.md +++ b/proposals/0313-actor-isolation-control.md @@ -322,7 +322,7 @@ At a high level, isolated parameters and isolated conformances are similar to pa } } ``` - Generally speaking, a variable in Swift has the same type when it's captured in a nested context as it does in its enclosing context, which provides a level of predictability that would be lost with `@sync` types. In the example above, type inference for the call to `f` differs significantly whether you're in the closure or not. A [recent discussion on the forums](https://forums.swift.org/t/implicit-casts-for-verified-type-information/41035) about narrowing types showed resistence to the idea of changing the type of a variable in a nested context, even when doing so could eliminate additional boilerplate. + Generally speaking, a variable in Swift has the same type when it's captured in a nested context as it does in its enclosing context, which provides a level of predictability that would be lost with `@sync` types. In the example above, type inference for the call to `f` differs significantly whether you're in the closure or not. A [recent discussion on the forums](https://forums.swift.org/t/implicit-casts-for-verified-type-information/41035) about narrowing types showed resistance to the idea of changing the type of a variable in a nested context, even when doing so could eliminate additional boilerplate. * The design relies heavily on the implicit conversion from `@sync MyActor` to `MyActor`, e.g., diff --git a/proposals/0317-async-let.md b/proposals/0317-async-let.md index d85965d91c..6720edf791 100644 --- a/proposals/0317-async-let.md +++ b/proposals/0317-async-let.md @@ -783,7 +783,7 @@ func runThrowsOkay() async { } ``` -The rules above attempt to limit the places in which the new `await` syntaxes are required to only those where they are semantically meaningful, i.e., those places where the `async let` child tasks will not already have had their completion explicitly awaited. The rules are complicated enough that we would not expect programmers to be able to correctly write `await` in all of the places where it is required. Rather, the Swift compiler would need to provide error messags with Fix-Its to indicate the places where additional `await` annotations are required, and those `await`s will remain as an artifact for the reader. +The rules above attempt to limit the places in which the new `await` syntaxes are required to only those where they are semantically meaningful, i.e., those places where the `async let` child tasks will not already have had their completion explicitly awaited. The rules are complicated enough that we would not expect programmers to be able to correctly write `await` in all of the places where it is required. Rather, the Swift compiler would need to provide error messages with Fix-Its to indicate the places where additional `await` annotations are required, and those `await`s will remain as an artifact for the reader. We feel that the complexity of the solution for marking all suspension points, which includes both the grammar expansion for marking control-flow edges and the flow-sensitive analysis to only require the additional `await` marking when necessary, exceeds the benefits of adding it. Instead, we feel that the presence of `async let` in a block with complicated control flow is sufficient to imply the presence of additional suspension points. diff --git a/proposals/0318-package-creation.md b/proposals/0318-package-creation.md index 1ad4a894a5..606cf9ad69 100644 --- a/proposals/0318-package-creation.md +++ b/proposals/0318-package-creation.md @@ -233,8 +233,8 @@ let package = Package( name: "___NAME_AS_C99___", sources: "src", dependencies: [ - .product(name: "NIO", pacakge: "swift-nio"), - .product(name: "Crypto", pacakge: "swift-crypto") + .product(name: "NIO", package: "swift-nio"), + .product(name: "Crypto", package: "swift-crypto") ] ), ] @@ -279,8 +279,8 @@ let package = Package( name: "HelloWorld", sources: "src", dependencies: [ - .product(name: "NIO", pacakge: "swift-nio"), - .product(name: "Crypto", pacakge: "swift-crypto") + .product(name: "NIO", package: "swift-nio"), + .product(name: "Crypto", package: "swift-crypto") ] ), ] @@ -358,7 +358,7 @@ No impact. The main alternative is to modify the behavior of `swift package init` such that it better caters to the creation of new packages from scratch. The advantage of this alternative is that it maintains the API surface area. The disadvantages are that any changes to make it better for package creation are likely to make it confusing for transforming existing sources to package. More importantly, changes to the existing command may cause impact on users that have automation tied to the current behavior. -For templates, the main alternative is to use a data file (e.g. JSON) that describes how the package should be constructed. This would hone in the implementation as it defines a finite set of capabilities driven by configuraiton. This was not selected in order to provide a better user experience, and greater flexibility with respect to including other files in a template. +For templates, the main alternative is to use a data file (e.g. JSON) that describes how the package should be constructed. This would hone in the implementation as it defines a finite set of capabilities driven by configuration. This was not selected in order to provide a better user experience, and greater flexibility with respect to including other files in a template. # Future Iterations diff --git a/proposals/0319-never-identifiable.md b/proposals/0319-never-identifiable.md index 25efcce36f..e298dcc55b 100644 --- a/proposals/0319-never-identifiable.md +++ b/proposals/0319-never-identifiable.md @@ -18,7 +18,7 @@ With the acceptance of [SE-0215](https://github.com/swiftlang/swift-evolution/bl The conformance of `Never` to `Equatable` and `Hashable` in SE-0215 was motivated by examples like using `Never` as a generic constraint in types like `Result` and in enumerations. These same use cases motivate the conformance of `Never` to `Identifiable`, which is pervasive in commonly used frameworks like SwiftUI. -For example, the new `TableRowContent` protocol in SwiftUI follows a "recursive type pattern" and has the need for a primitive bottom type with an `Identifiable` assocated type: +For example, the new `TableRowContent` protocol in SwiftUI follows a "recursive type pattern" and has the need for a primitive bottom type with an `Identifiable` associated type: ```swift extension Never: TableRowContent { diff --git a/proposals/0325-swiftpm-additional-plugin-apis.md b/proposals/0325-swiftpm-additional-plugin-apis.md index 70abb2ce63..626710d855 100644 --- a/proposals/0325-swiftpm-additional-plugin-apis.md +++ b/proposals/0325-swiftpm-additional-plugin-apis.md @@ -181,7 +181,7 @@ public protocol Product { /// The targets that directly comprise the product, in the order in which /// they are declared in the package manifest. The product will contain the - /// transitive closure of the these targets and their depdendencies. + /// transitive closure of the these targets and their dependencies. var targets: [Target] { get } } @@ -419,7 +419,7 @@ This proposal also adds the first of what is expected to be a toolbox of APIs to ```swift extension Target { - /// The transitive closure of all the targets on which the reciver depends, + /// The transitive closure of all the targets on which the receiver depends, /// ordered such that every dependency appears before any other target that /// depends on it (i.e. in "topological sort order"). public var recursiveTargetDependencies: [Target] @@ -509,7 +509,7 @@ struct MyPlugin: BuildToolPlugin { // Create a module mappings file. This is something that the Swift source // generator `protoc` plug-in we are using requires. The details are not // important for this proposal, except that it needs to be able to be con- - // structed from the information in the context given to the plugin, and + // structured from the information in the context given to the plugin, and // to be written out to the intermediates directory. let moduleMappingsFile = otherFilesDir.appending("module-mappings") let outputString = ". . . module mappings file . . ." diff --git a/proposals/0332-swiftpm-command-plugins.md b/proposals/0332-swiftpm-command-plugins.md index 8eb0c891a7..3e30dc8957 100644 --- a/proposals/0332-swiftpm-command-plugins.md +++ b/proposals/0332-swiftpm-command-plugins.md @@ -24,7 +24,7 @@ Separately to this proposal, it would also be useful to define custom actions th ## Proposed Solution -This proposal defines a new plugin capability called `command` that allows packages to augment the set of package-related commands availabile in the SwiftPM CLI and in IDEs that support packages. A command plugin specifies the semantic intent of the command — this might be one of the predefined intents such “documentation generation” or “source code formatting”, or it might be a custom intent with a specialized verb that can be passed to the `swift` `package` command. A command plugin can also specify any special permissions it needs (such as the permission to modify the files under the package directory). +This proposal defines a new plugin capability called `command` that allows packages to augment the set of package-related commands available in the SwiftPM CLI and in IDEs that support packages. A command plugin specifies the semantic intent of the command — this might be one of the predefined intents such “documentation generation” or “source code formatting”, or it might be a custom intent with a specialized verb that can be passed to the `swift` `package` command. A command plugin can also specify any special permissions it needs (such as the permission to modify the files under the package directory). The command's intent declaration provides a way of grouping command plugins by their functional categories, so that SwiftPM — or an IDE that supports SwiftPM packages — can show the commands that are available for a particular purpose. For example, this approach supports having different command plugins for generating documentation for a package, while still allowing those different commands to be grouped and discovered by intent. diff --git a/proposals/0337-support-incremental-migration-to-concurrency-checking.md b/proposals/0337-support-incremental-migration-to-concurrency-checking.md index 2bfd135f3c..f3804f5a8f 100644 --- a/proposals/0337-support-incremental-migration-to-concurrency-checking.md +++ b/proposals/0337-support-incremental-migration-to-concurrency-checking.md @@ -73,7 +73,7 @@ Achieving this will require several features working in tandem: * When applied to a nominal declaration, the `@preconcurrency` attribute specifies that a declaration was modified to update it for concurrency checking, so the compiler should allow some uses in Swift 5 mode that violate concurrency checking, and generate code that interoperates with pre-concurrency binaries. -* When applied to an `import` statement, the `@preconcurrency` attribute tells the compiler that it should only diagnose `Sendable`-requiring uses of non-`Sendable` types from that module if the type explicitly declares a `Sendable` conformance that is unavailable or has constraints that are not satisifed; even then, this will only be a warning, not an error. +* When applied to an `import` statement, the `@preconcurrency` attribute tells the compiler that it should only diagnose `Sendable`-requiring uses of non-`Sendable` types from that module if the type explicitly declares a `Sendable` conformance that is unavailable or has constraints that are not satisfied; even then, this will only be a warning, not an error. ## Detailed design diff --git a/proposals/0342-static-link-runtime-libraries-by-default-on-supported-platforms.md b/proposals/0342-static-link-runtime-libraries-by-default-on-supported-platforms.md index c8ade71a5f..788c935013 100644 --- a/proposals/0342-static-link-runtime-libraries-by-default-on-supported-platforms.md +++ b/proposals/0342-static-link-runtime-libraries-by-default-on-supported-platforms.md @@ -206,7 +206,7 @@ The new behavior will take effect with a new version of SwiftPM, and packages bu ### Additional validation when linking libraries SwiftPM currently performs no validation when linking libraries into an executable that statically links the Swift runtime libraries. -This means that users can mistakinly link a library that already has the Swift runtime libraries statically linked into the executable that will also statically link the Swift runtime libraries, which could lead to runtime errors if the versions of the Swift runtime libraries do not match. +This means that users can mistakenly link a library that already has the Swift runtime libraries statically linked into the executable that will also statically link the Swift runtime libraries, which could lead to runtime errors if the versions of the Swift runtime libraries do not match. As part of this proposal, SwiftPM will gain a new post build validation checking for this condition and warning the user accordingly. ## Alternatives considered and future directions diff --git a/proposals/0345-if-let-shorthand.md b/proposals/0345-if-let-shorthand.md index 48e82755ed..265d89d873 100644 --- a/proposals/0345-if-let-shorthand.md +++ b/proposals/0345-if-let-shorthand.md @@ -253,7 +253,7 @@ if foo == true, bar == true { } ``` -To avoid this abiguity, we need some sort of distinct syntax for optional bindings. +To avoid this ambiguity, we need some sort of distinct syntax for optional bindings. ### `if unwrap foo` @@ -295,7 +295,7 @@ Once borrow introducers are added to the language, seeing `ref x` or `inout x` a Borrow introducers will be very useful, but adopting them is a tradeoff between performance and conceptual overhead. Borrows are cheap but come with high conceptual overhead. Copies can be expensive but always work as expected without much extra thought. Given this tradeoff, it likely makes sense for this shorthand syntax to provide a way for users to choose between performing a copy or performing a borrow, rather than limiting users to one or the other. -Additionally, for consistency with existing optional binding conditions, this new shorthand should support the distinction between immutable and mutable variables. Combined with the disctinction between copies and borrows, that would give us the same set of options as normal variables: +Additionally, for consistency with existing optional binding conditions, this new shorthand should support the distinction between immutable and mutable variables. Combined with the distinction between copies and borrows, that would give us the same set of options as normal variables: ```swift // Included in this proposal: @@ -363,7 +363,7 @@ Since `if var foo = foo` is significantly less common than `if let foo = foo`, w `var` shadowing has the potential to be more confusing than `let` shadowing -- `var` introduces a new _mutable_ variable, and any mutations to the new variable are not shared with the original optional variable. On the other hand, `if var foo = foo` already exists, and it seems unlikely that `if var foo` would be more confusing / less clear than the existing syntax. -Since `let` and `var` are interchangable elsewhere in the language, that should also be the case here -- disallowing `if var foo` would be inconsistent with existing optional binding condition syntax. If we were using an alternative spelling that _did not_ use `let`, it may be reasonable to exclude `var` -- but since we are using `let` here, `var` should also be allowed. +Since `let` and `var` are interchangeable elsewhere in the language, that should also be the case here -- disallowing `if var foo` would be inconsistent with existing optional binding condition syntax. If we were using an alternative spelling that _did not_ use `let`, it may be reasonable to exclude `var` -- but since we are using `let` here, `var` should also be allowed. ## Acknowledgments diff --git a/proposals/0347-type-inference-from-default-exprs.md b/proposals/0347-type-inference-from-default-exprs.md index 1f1b90eda3..db105e1d92 100644 --- a/proposals/0347-type-inference-from-default-exprs.md +++ b/proposals/0347-type-inference-from-default-exprs.md @@ -202,7 +202,7 @@ struct Box { ```swift enum Box { case flatRate(dimensions: D = [...], flags: F = DefaultFlags()) -case overnight(dimentions: D = [...], flags: F = DefaultFlags()) +case overnight(dimensions: D = [...], flags: F = DefaultFlags()) ... } ``` diff --git a/proposals/0348-buildpartialblock.md b/proposals/0348-buildpartialblock.md index 967aa96947..4a196e68c6 100644 --- a/proposals/0348-buildpartialblock.md +++ b/proposals/0348-buildpartialblock.md @@ -268,7 +268,7 @@ Such features would greatly complicate the type system. #### Overload `buildBlock` method name -Because the proposed feature overlaps `buildBlock`, one could argue for reusing `buildBlock` as the method base name instead of `buildPartialBlock` and using arguemnt labels to distinguish whether it is the pairwise version, e.g. `buildBlock(partiallyAccumulated:next:)` or `buildBlock(combining:into:)`. +Because the proposed feature overlaps `buildBlock`, one could argue for reusing `buildBlock` as the method base name instead of `buildPartialBlock` and using argument labels to distinguish whether it is the pairwise version, e.g. `buildBlock(partiallyAccumulated:next:)` or `buildBlock(combining:into:)`. ```swift extension Builder { diff --git a/proposals/0349-unaligned-loads-and-stores.md b/proposals/0349-unaligned-loads-and-stores.md index 26c9b30d14..b542077621 100644 --- a/proposals/0349-unaligned-loads-and-stores.md +++ b/proposals/0349-unaligned-loads-and-stores.md @@ -13,7 +13,7 @@ Swift does not currently provide a clear way to load data from an arbitrary sour ## Motivation -The method `UnsafeRawPointer.load(fromByteOffset offset: Int, as type: T.Type) -> T` requires the address at `self+offset` to be properly aligned to access an instance of type `T`. Attempts to use a combination of pointer and byte offset that is not aligned for `T` results in a runtime crash. Unfortunately, in general, data saved to files or network streams does not adhere to the same restrictions as in-memory layouts do, and tends to not be properly aligned. When copying data from such sources to memory, Swift users therefore frequently encounter aligment mismatches that require using a workaround. This is a longstanding issue reported in e.g. [SR-10273](https://bugs.swift.org/browse/SR-10273). +The method `UnsafeRawPointer.load(fromByteOffset offset: Int, as type: T.Type) -> T` requires the address at `self+offset` to be properly aligned to access an instance of type `T`. Attempts to use a combination of pointer and byte offset that is not aligned for `T` results in a runtime crash. Unfortunately, in general, data saved to files or network streams does not adhere to the same restrictions as in-memory layouts do, and tends to not be properly aligned. When copying data from such sources to memory, Swift users therefore frequently encounter alignment mismatches that require using a workaround. This is a longstanding issue reported in e.g. [SR-10273](https://bugs.swift.org/browse/SR-10273). For example, given an arbitrary data stream in which a 4-byte value is encoded between byte offsets 3 through 7: diff --git a/proposals/0351-regex-builder.md b/proposals/0351-regex-builder.md index df32e27fe5..41a39eae1d 100644 --- a/proposals/0351-regex-builder.md +++ b/proposals/0351-regex-builder.md @@ -87,7 +87,7 @@ This proposal introduces all core API for creating and composing regexes that ec ## Motivation -Regex is a fundemental and powerful tool for textual pattern matching. It is a domain-specific language often expressed as text. For example, given the following bank statement: +Regex is a fundamental and powerful tool for textual pattern matching. It is a domain-specific language often expressed as text. For example, given the following bank statement: ``` CREDIT 04062020 PayPal transfer $4.99 @@ -370,7 +370,7 @@ public enum RegexComponentBuilder { Before Swift supports variadic generics, `buildPartialBlock(accumulated:next:)` must be overloaded to support concatenating regexes of supported capture quantities (arities). It is overloaded up to `arity^2` times to account for all possible pairs of regexes that make up 10 captures. -In the initial version of the DSL, we plan to support regexes with up to 10 captures, as 10 captures are sufficient for most use cases. These overloads can be superceded by variadic versions of `buildPartialBlock(first:)` and `buildPartialBlock(accumulated:next:)` in a future release. +In the initial version of the DSL, we plan to support regexes with up to 10 captures, as 10 captures are sufficient for most use cases. These overloads can be superseded by variadic versions of `buildPartialBlock(first:)` and `buildPartialBlock(accumulated:next:)` in a future release. ```swift extension RegexComponentBuilder { @@ -1576,7 +1576,7 @@ The proposed feature does not change the ABI of existing features. ## Effect on API resilience -The proposed feature relies heavily upon overloads of `buildBlock` and `buildPartialBlock(accumulated:next:)` to work for different capture arities. In the fullness of time, we are hoping for variadic generics to supercede existing overloads. Such a change should not involve ABI-breaking modifications as it is merely a change of overload resolution. +The proposed feature relies heavily upon overloads of `buildBlock` and `buildPartialBlock(accumulated:next:)` to work for different capture arities. In the fullness of time, we are hoping for variadic generics to supersede existing overloads. Such a change should not involve ABI-breaking modifications as it is merely a change of overload resolution. ## Future directions @@ -1907,7 +1907,7 @@ extension Capture { } ``` -In this case, since the argument label will not be specfied for the first trailing closure, using `Capture` where the component is a non-builder-closure may cause type-checking ambiguity. +In this case, since the argument label will not be specified for the first trailing closure, using `Capture` where the component is a non-builder-closure may cause type-checking ambiguity. ```swift Regex { diff --git a/proposals/0352-implicit-open-existentials.md b/proposals/0352-implicit-open-existentials.md index 964297e8e8..ccf49c1942 100644 --- a/proposals/0352-implicit-open-existentials.md +++ b/proposals/0352-implicit-open-existentials.md @@ -276,7 +276,7 @@ When binding a generic parameter `T` to an opened existential, `T`, `T` and `T`- will be type-erased to their upper bounds as per the generic signature of the existential that is used to access the member. The upper bounds can be either a class, protocol, protocol composition, or `Any`, depending on the *presence* and *kind* of generic constraints on the associated type. -When `T` or a `T`-rooted associated type appears in a non-covariant position in the result type, `T` cannot be bound to the underlying type of an existential value because there would be no way to represent the type-erased result. This is essentially the same property as descibed for the parameter types that prevents opening of existentials, as described above. For example: +When `T` or a `T`-rooted associated type appears in a non-covariant position in the result type, `T` cannot be bound to the underlying type of an existential value because there would be no way to represent the type-erased result. This is essentially the same property as described for the parameter types that prevents opening of existentials, as described above. For example: ```swift func cannotOpen7(_ value: T) -> X { /*...*/ } diff --git a/proposals/0354-regex-literals.md b/proposals/0354-regex-literals.md index 3523b40aa5..752e22f085 100644 --- a/proposals/0354-regex-literals.md +++ b/proposals/0354-regex-literals.md @@ -490,7 +490,7 @@ It should also be noted that `#regex(...)` would introduce a syntactic inconsist ##### On future extensibility to other foreign language snippets -One of the benefits of `#regex(...)` or `re'...'` is the extensibility to other kinds of foreign langauge snippets, such as SQL. Nothing in this proposal precludes a scalable approach to foreign language snippets using `#lang(...)` or `lang'...'`. If or when that happens, regex could participate as well, but the proposed syntax would still be valuable as regex literals *are* unique in their prevalence as fragments passed directly to API, as well as components of a result builder DSL. +One of the benefits of `#regex(...)` or `re'...'` is the extensibility to other kinds of foreign language snippets, such as SQL. Nothing in this proposal precludes a scalable approach to foreign language snippets using `#lang(...)` or `lang'...'`. If or when that happens, regex could participate as well, but the proposed syntax would still be valuable as regex literals *are* unique in their prevalence as fragments passed directly to API, as well as components of a result builder DSL. #### Shortened magic literal `#(...)` @@ -647,7 +647,7 @@ The regex builder DSL is unable to provide some of the features presented such a Similarly, there is no literal equivalent for some of the regex builder features, but that isn't an argument against them. The regex builder DSL has references which serves this role (though not as concisely) and they are useful beyond just naming captures. -Regex literals should not be outright avoided, they should be used well. Artifically hampering their usage doesn't provide any benefit and we wouldn't want to lock these limitations into Swift's ABI. +Regex literals should not be outright avoided, they should be used well. Artificially hampering their usage doesn't provide any benefit and we wouldn't want to lock these limitations into Swift's ABI. diff --git a/proposals/0356-swift-snippets.md b/proposals/0356-swift-snippets.md index cebb994700..e1ab8692c2 100644 --- a/proposals/0356-swift-snippets.md +++ b/proposals/0356-swift-snippets.md @@ -361,7 +361,7 @@ USAGE: snippet-build ARGUMENTS: - The directory containing Swift snippets - - The diretory in which to place Symbol Graph JSON file(s) representing the snippets + - The directory in which to place Symbol Graph JSON file(s) representing the snippets - The module name to use for the Symbol Graph (typically should be the package name) ``` diff --git a/proposals/0357-regex-string-processing-algorithms.md b/proposals/0357-regex-string-processing-algorithms.md index ca9b7325c7..1cbd60d3f3 100644 --- a/proposals/0357-regex-string-processing-algorithms.md +++ b/proposals/0357-regex-string-processing-algorithms.md @@ -594,7 +594,7 @@ extension Collection where SubSequence == Substring { /// Returns a collection containing all matches of the specified regex. /// - Parameter regex: The regex to search for. /// - Returns: A collection of matches of `regex`. - public func matches(of regex: R) -> some Collection.Match> + public func matches(of regex: R) -> some Collection.Match> } // In RegexBuilder module @@ -613,7 +613,7 @@ extension Collection where SubSequence == Substring { #### Replace -We propose generic collection algorithms that will replace all occurences of a given subsequence: +We propose generic collection algorithms that will replace all occurrences of a given subsequence: ```swift extension RangeReplaceableCollection where Element: Equatable { @@ -788,7 +788,7 @@ extension RangeReplaceableCollection where SubSequence == Substring { public func replacing( _ regex: R, maxReplacements: Int = .max, - with replacement: (Regex.Match) throws -> Replacement + with replacement: (Regex.Match) throws -> Replacement ) rethrows -> Self where Replacement.Element == Element /// Replaces all occurrences of the sequence matching the given regex with @@ -1124,7 +1124,7 @@ This protocol customizes the basic consume-from-the-front functionality. A proto ### Why `where SubSequence == Substring`? -A `Substring` slice requirement allows the regex engine to produce indicies in the original collection by operating over a portion of the input. Unfortunately, this is not one of the requirements of `StringProtocol`. +A `Substring` slice requirement allows the regex engine to produce indices in the original collection by operating over a portion of the input. Unfortunately, this is not one of the requirements of `StringProtocol`. A new protocol for types that can produce a `Substring` on request (e.g. from UTF-8 contents) would have to eagerly produce a `String` copy first and would need requirements to translate indices. When higher-level algorithms are implemented via multiple calls to the lower-level algorithms, these copies could happen many times. Shared strings are future work but a much better solution to this. diff --git a/proposals/0363-unicode-for-string-processing.md b/proposals/0363-unicode-for-string-processing.md index 3f2703b74b..a56e074ddf 100644 --- a/proposals/0363-unicode-for-string-processing.md +++ b/proposals/0363-unicode-for-string-processing.md @@ -373,7 +373,7 @@ When matching with *grapheme cluster semantics* (the default), metacharacters li When matching with *Unicode scalar semantics*, metacharacters and character classes match a single Unicode scalar value, even if that scalar comprises part of a grapheme cluster. Canonical representations are _not_ used, corresponding with the way comparison would work when using a string's `UnicodeScalarView`. -These specific levels of matching, and the options to switch between them, are unique to Swift, but not unprecedented in other regular expression engines. Several engines, including Perl, Java, and ICU-based engines like `NSRegularExpression`, support the `\X` metacharacter for matching a grapheme cluster within otherwise Unicode scalar semantic matching. Rust has a related concept in its [`regex::bytes` type][regexbytes], which matches over abitrary bytes by default but allows switching into Unicode mode for segments of the regular expression. +These specific levels of matching, and the options to switch between them, are unique to Swift, but not unprecedented in other regular expression engines. Several engines, including Perl, Java, and ICU-based engines like `NSRegularExpression`, support the `\X` metacharacter for matching a grapheme cluster within otherwise Unicode scalar semantic matching. Rust has a related concept in its [`regex::bytes` type][regexbytes], which matches over arbitrary bytes by default but allows switching into Unicode mode for segments of the regular expression. These semantic levels lead to different results when working with strings that have characters made up of multiple Unicode scalar values, such as Emoji or decomposed characters. In the following example, `queRegex` matches any 3-character string that begins with `"q"`. @@ -1273,7 +1273,7 @@ Instead, we could use this opportunity to choose default options that are more e ### Include `\O` and `CharacterClass.anyUnicodeScalar` -An earlier draft of this proposal included a metacharacter and `CharacterClass` API for matching an individual Unicode scalar value, regardless of the current matching level, as a counterpart to `\X`/`.anyGraphemeCluster`. The behavior of this character class, particularly when matching with grapheme cluster semantics, is still unclear at this time, however. For example, when matching the expression `\O*`, does the implict grapheme boundary assertion apply between the `\O` and the quantification operator, or should we treat the two as a single unit and apply the assertion after the `*`? +An earlier draft of this proposal included a metacharacter and `CharacterClass` API for matching an individual Unicode scalar value, regardless of the current matching level, as a counterpart to `\X`/`.anyGraphemeCluster`. The behavior of this character class, particularly when matching with grapheme cluster semantics, is still unclear at this time, however. For example, when matching the expression `\O*`, does the implicit grapheme boundary assertion apply between the `\O` and the quantification operator, or should we treat the two as a single unit and apply the assertion after the `*`? At the present time, we prefer to allow authors to write regexes that explicitly shift into and out of Unicode scalar mode, where those kinds of decisions are handled by the explicit scope of the setting. If common patterns emerge that indicate some version of `\O` would be useful, we can add it in the future. diff --git a/proposals/0367-conditional-attributes.md b/proposals/0367-conditional-attributes.md index b6ca2bb8ec..09b915db61 100644 --- a/proposals/0367-conditional-attributes.md +++ b/proposals/0367-conditional-attributes.md @@ -36,7 +36,7 @@ This is unsatisfactory for at least two reasons. First, it's a lot of code dupli I propose two related changes to make it easier to adopt new attributes in existing code: * Allow `#if` checks to surround attributes on a declaration wherever they appear, eliminating the need to clone a declaration just to adopt a new attribute. -* Add a conditional directive `hasAttribute(AttributeName)` that evalutes `true` when the compiler has support for the attribute with the name `AttributeName` in the current language mode. +* Add a conditional directive `hasAttribute(AttributeName)` that evaluates `true` when the compiler has support for the attribute with the name `AttributeName` in the current language mode. The first two of these can be combined to make the initial example less repetitive and more descriptive: diff --git a/proposals/0376-function-back-deployment.md b/proposals/0376-function-back-deployment.md index c5b2465127..396dcc93da 100644 --- a/proposals/0376-function-back-deployment.md +++ b/proposals/0376-function-back-deployment.md @@ -89,7 +89,7 @@ extension Temperature { @available(toasterOS 1.0, ovenOS 1.0, *) @backDeployed(before: toasterOS 2.0, ovenOS 2.0) public var degreesFahrenheit: Double { - return (degreesCelcius * 9 / 5) + 32 + return (degreesCelsius * 9 / 5) + 32 } } diff --git a/proposals/0381-task-group-discard-results.md b/proposals/0381-task-group-discard-results.md index 6ff0e4a2b3..27ec7607b0 100644 --- a/proposals/0381-task-group-discard-results.md +++ b/proposals/0381-task-group-discard-results.md @@ -17,7 +17,7 @@ Task groups are the building block of structured concurrency, allowing for the S The version of Task Groups introduced in [SE-0304](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0304-structured-concurrency.md) provides all of these features. However, it also provides the ability to propagate return values to the user of the task group. This capability provides an unexpected limitation in some use-cases. -As users of Task Groups are able to retrieve the return values of child tasks, it implicitly follows that the Task Group preserves at least the `Result` of any completed child task. As a practical matter, the task group actually preseves the entire `Task` object. This data is preserved until the user consumes it via one of the Task Group consumption APIs, whether that is `next()` or by iterating the Task Group. +As users of Task Groups are able to retrieve the return values of child tasks, it implicitly follows that the Task Group preserves at least the `Result` of any completed child task. As a practical matter, the task group actually preserves the entire `Task` object. This data is preserved until the user consumes it via one of the Task Group consumption APIs, whether that is `next()` or by iterating the Task Group. The result of this is that Task Groups are ill-suited to running for a potentially unbounded amount of time. An example of such a use-case is managing connections accepted from a listening socket. A simplified example of such a workload might be: @@ -103,7 +103,7 @@ public func withThrowingDiscardingTaskGroup( ) async throws -> GroupResult { ... } ``` -And the types themselfes, mostly mirroring the APIs of `TaskGroup`, except that they're missing `next()` and related functionality: +And the types themselves, mostly mirroring the APIs of `TaskGroup`, except that they're missing `next()` and related functionality: ```swift public struct DiscardingTaskGroup { diff --git a/proposals/0384-importing-forward-declared-objc-interfaces-and-protocols.md b/proposals/0384-importing-forward-declared-objc-interfaces-and-protocols.md index 6718630157..e7da438da2 100644 --- a/proposals/0384-importing-forward-declared-objc-interfaces-and-protocols.md +++ b/proposals/0384-importing-forward-declared-objc-interfaces-and-protocols.md @@ -227,7 +227,7 @@ Issues: Issues: - It seems achievable to teach the typechecker that `IncompleteFoo.Foo` and `CompleteFoo.Foo` can be implicitly converted between one another, but that is not enough - - Any typechecking contraint that `CompleteFoo.Foo` satisfies must also be satisfied by `IncompleteFoo.Foo`. + - Any typechecking constraint that `CompleteFoo.Foo` satisfies must also be satisfied by `IncompleteFoo.Foo`. - It might be possible to "inject" an extension into the REPL's context that adds any required methods, computed properties and protocol conformances to `IncompleteFoo.Foo`. However, it is not possible to add new inheritances. We believe that given these issues, it is better to disable the feature in the REPL entirely rather than provide a confusing experience. We believe that this diff --git a/proposals/0389-attached-macros.md b/proposals/0389-attached-macros.md index b412eb2655..c3a20dfc6a 100644 --- a/proposals/0389-attached-macros.md +++ b/proposals/0389-attached-macros.md @@ -302,7 +302,7 @@ The `expansion` operation accepts the attribute syntax `node` for the spelling o #### Conformance macros -Conformance macros allow one to introduce new protocol conformances to a type. This would often be paired with other macros whose purpose is to help satisfy the protocol conformance. For example, one could imagine an extended version of the `OptionSetMembers` attributed shown earlier that also adds the `OptionSet` conformance. With it, the mimimal implementation of an option set could be: +Conformance macros allow one to introduce new protocol conformances to a type. This would often be paired with other macros whose purpose is to help satisfy the protocol conformance. For example, one could imagine an extended version of the `OptionSetMembers` attributed shown earlier that also adds the `OptionSet` conformance. With it, the minimal implementation of an option set could be: ```swift @OptionSet diff --git a/proposals/0392-custom-actor-executors.md b/proposals/0392-custom-actor-executors.md index af8925e9c4..97baac5ace 100644 --- a/proposals/0392-custom-actor-executors.md +++ b/proposals/0392-custom-actor-executors.md @@ -63,7 +63,7 @@ Nonetheless, it is sometimes useful to more finely control how code is executed: For example, some libraries maintain state in thread-local variables, and running code on the wrong thread will lead to broken assumptions in the library. - For another example, not all execution environments are homogenous; some threads may be pinned to processors with extra capabilities. + For another example, not all execution environments are homogeneous; some threads may be pinned to processors with extra capabilities. - The code's performance may benefit from the programmer being more explicit about where code should run. @@ -73,11 +73,11 @@ Nonetheless, it is sometimes useful to more finely control how code is executed: This is the first proposal discussing custom executors and customization points in the Swift Concurrency runtime, and while it introduces only the most basic customization points, we are certain that it already provides significant value to users seeking tighter control over their actor's execution semantics. -Along with introducing ways to customize where code executes, this proposal also introduces ways to assert and assume the apropriate executor is used. This allows for more confidence when migrating away from other concurrency models to Swift Concurrency. +Along with introducing ways to customize where code executes, this proposal also introduces ways to assert and assume the appropriate executor is used. This allows for more confidence when migrating away from other concurrency models to Swift Concurrency. ## Proposed solution -We propose to give developers the ability to implement simple serial executors, which then can be used with actors in order to ensure that any code executoring on such "actor with custom serial executor" runs on the apropriate thread or context. Implementing a naive executor takes the shape of: +We propose to give developers the ability to implement simple serial executors, which then can be used with actors in order to ensure that any code executoring on such "actor with custom serial executor" runs on the appropriate thread or context. Implementing a naive executor takes the shape of: ```swift final class SpecificThreadExecutor: SerialExecutor { @@ -114,9 +114,9 @@ actor Worker { } ``` -And lastly, in order to increase the confidence during moves from other concurrency models to Swift Concurrency with custom executors, we also provide ways to assert that a piece of code is executing on the apropriate executor. These methods should be used only if there is not better way to express the requirement statically. For example by expressing the code as a method on a specific actor, or annotating it with a `@GlobalActor`, should be preferred to asserting when possible, however sometimes this is not possible due to the old code fulfilling synchronous protocol requirements that still have these threading requirements. +And lastly, in order to increase the confidence during moves from other concurrency models to Swift Concurrency with custom executors, we also provide ways to assert that a piece of code is executing on the appropriate executor. These methods should be used only if there is not better way to express the requirement statically. For example by expressing the code as a method on a specific actor, or annotating it with a `@GlobalActor`, should be preferred to asserting when possible, however sometimes this is not possible due to the old code fulfilling synchronous protocol requirements that still have these threading requirements. -Asserting the apropriate executor is used in a synchronous piece of code looks like this: +Asserting the appropriate executor is used in a synchronous piece of code looks like this: ````swift func synchronousButNeedsMainActorContext() { @@ -128,7 +128,7 @@ func synchronousButNeedsMainActorContext() { } ```` -Furthermore, we also offer a new API to safely "assume" an actor's execution context. For example, a synchronous function may know that it always will be invoked by the `MainActor` however for some reason it cannot be marked using `@MainActor`, this new API allows to assume (or crash if called from another execution context) the apropriate execution context, including the safety of synchronously accessing any state protected by the main actor executor: +Furthermore, we also offer a new API to safely "assume" an actor's execution context. For example, a synchronous function may know that it always will be invoked by the `MainActor` however for some reason it cannot be marked using `@MainActor`, this new API allows to assume (or crash if called from another execution context) the appropriate execution context, including the safety of synchronously accessing any state protected by the main actor executor: ```swift @MainActor func example() {} @@ -407,7 +407,7 @@ public protocol DistributedActor: AnyActor { > Note: It is not possible to express this protocol requirement on `AnyActor` directly because `AnyActor` is a "marker protocol" which are not present at runtime, and cannot have protocol requirements. -The compiler synthesizes an implementation for this requirement for every `(distributed) actor` declaration, unless an explicit implementation is provided. The default implementation synthesized by the compiler uses the default `SerialExecutor`, that uses tha apropriate mechanism for the platform (e.g. Dispatch). Actors using this default synthesized implementation are referred to as "Default Actors", i.e. actors using the default serial executor implementation. +The compiler synthesizes an implementation for this requirement for every `(distributed) actor` declaration, unless an explicit implementation is provided. The default implementation synthesized by the compiler uses the default `SerialExecutor`, that uses tha appropriate mechanism for the platform (e.g. Dispatch). Actors using this default synthesized implementation are referred to as "Default Actors", i.e. actors using the default serial executor implementation. Developers can customize the executor used by an actor on a declaration-by-declaration basis, by implementing this protocol requirement in an actor. For example, thanks to the `sharedUnownedExecutor` static property on `MainActor` it is possible to declare other actors which are also guaranteed to use the same serial executor (i.e. "the main thread"). @@ -439,10 +439,10 @@ It is also possible for libraries to offer protocols where a default, library sp ```swift protocol WithSpecifiedExecutor: Actor { - nonisolated var executor: LibrarySecificExecutor { get } + nonisolated var executor: LibrarySpecificExecutor { get } } -protocol LibrarySecificExecutor: SerialExecutor {} +protocol LibrarySpecificExecutor: SerialExecutor {} extension LibrarySpecificActor { /// Establishes the WithSpecifiedExecutorExecutor as the serial @@ -480,7 +480,7 @@ A library could also provide a default implementation of such executor as well. ### Asserting on executors -A common pattern in event-loop heavy code–not yet using Swift Concurrency–is to ensure/verify that a synchronous piece of code is executed on the exected event-loop. Since one of the goals of making executors customizable is to allow such libraries to adopt Swift Concurrency by making such event-loops conform to `SerialExecutor`, it is useful to allow the checking if code is indeed executing on the apropriate executor, for the library to gain confidence while it is moving towards fully embracing actors and Swift concurrency. +A common pattern in event-loop heavy code–not yet using Swift Concurrency–is to ensure/verify that a synchronous piece of code is executed on the exected event-loop. Since one of the goals of making executors customizable is to allow such libraries to adopt Swift Concurrency by making such event-loops conform to `SerialExecutor`, it is useful to allow the checking if code is indeed executing on the appropriate executor, for the library to gain confidence while it is moving towards fully embracing actors and Swift concurrency. For example, Swift NIO intentionally avoids synchronization checks in some synchronous methods, in order to avoid the overhead of doing so, however in DEBUG mode it performs assertions that given code is running on the expected event-loop: @@ -579,7 +579,7 @@ MainActor.preconditionIsolated() // Precondition failed: Incorrect actor executor assumption; Expected 'MainActorExecutor' executor, but was executing on 'Sample.InlineExecutor'. ```` -It should be noted that this API will return true whenever two actors share an executor. Semantically sharing a serial executor means running in the same isolation domain, however this is only known dynamically and `await`s are stil necessary for calls between such actors: +It should be noted that this API will return true whenever two actors share an executor. Semantically sharing a serial executor means running in the same isolation domain, however this is only known dynamically and `await`s are still necessary for calls between such actors: ```swift actor A { @@ -635,7 +635,7 @@ extension MainActor { } ``` -Similarily to the `preconditionIsolated` API, the executor check is performed against the target actor's executor, so if multiple actors are run on the same executor, this check will succeed in synchronous code invoked by such actors as well. In other words, the following code is also correct: +Similarly to the `preconditionIsolated` API, the executor check is performed against the target actor's executor, so if multiple actors are run on the same executor, this check will succeed in synchronous code invoked by such actors as well. In other words, the following code is also correct: ```swift func check(values: MainActorValues) /* synchronous! */ { @@ -894,7 +894,7 @@ actor Friend { Note that the raw type of the MainActor executor is never exposed, but we merely get unowned wrappers for it. This allows the Swift runtime to pick various specific implementations depending on the runtime environment. -The default global concurrent executor is not accessible direcly from code, however it is the executor that handles all the tasks which do not have a specific executor requirement, or are explicitly required to run on that executor, e.g. like top-level async functions. +The default global concurrent executor is not accessible directly from code, however it is the executor that handles all the tasks which do not have a specific executor requirement, or are explicitly required to run on that executor, e.g. like top-level async functions. ## Source compatibility @@ -908,7 +908,7 @@ Swift's concurrency runtime has already been using executors, jobs and tasks sin The design of `SerialExecutor` currently does not support non-reentrant actors, and it does not support executors for which dispatch is always synchronous (e.g. that just acquire a traditional mutex). -Some of the APIs discussed in this proposal existed from the first introduction of Swift Concurrency, so making any breaking changes to them is not possible. Some APIs were carefully renamed and polished up though. We encourage discussion of all the types and methods present in this proposal, however changing some of them may prove to be challanging or impossible due to ABI impact. +Some of the APIs discussed in this proposal existed from the first introduction of Swift Concurrency, so making any breaking changes to them is not possible. Some APIs were carefully renamed and polished up though. We encourage discussion of all the types and methods present in this proposal, however changing some of them may prove to be challenging or impossible due to ABI impact. ## Effect on API resilience @@ -987,7 +987,7 @@ We will consider adding these, or similar, APIs to enable custom executors to pa ### Specifying Task executors -Specifying executors to tasks has a suprising number of tricky questions it has to answer, so for the time being we are not introducing such capability. Specifically, passing an executor to `Task(startingOn: someExecutor) { ... }` would make the Task _start_ on the specified executor, but detailed semantics about if the _all_ of this Task's body is expected to execute on `someExecutor` (i.e. we have to hop-back to it every time after an `await`), or if it is enough to just start on it and then continue avoiding scheduling more jobs if possible (i.e. allow for aggressive switching). +Specifying executors to tasks has a surprising number of tricky questions it has to answer, so for the time being we are not introducing such capability. Specifically, passing an executor to `Task(startingOn: someExecutor) { ... }` would make the Task _start_ on the specified executor, but detailed semantics about if the _all_ of this Task's body is expected to execute on `someExecutor` (i.e. we have to hop-back to it every time after an `await`), or if it is enough to just start on it and then continue avoiding scheduling more jobs if possible (i.e. allow for aggressive switching). ### DelegateActor property diff --git a/proposals/0400-init-accessors.md b/proposals/0400-init-accessors.md index 95bd502cde..852421b0fd 100644 --- a/proposals/0400-init-accessors.md +++ b/proposals/0400-init-accessors.md @@ -597,7 +597,7 @@ Other syntax suggestions from pitch reviewers included: * Using more concise effect names, e.g. `writes` and `reads` instead of `initializes` and `accesses` * And more! -However, the current syntax in this proposal, which uses an attribute, most accurately models the semantics of initialization effects. An `init` accessor is a function -- not a closure -- that has side-effects related to initialization. _Only_ the `init` accessor has these effects; though the `set` accessor often contains code that looks the same as the code in the `init` accessor, the effects of these accessors are different. Because `init` accessors are called before all of `self` is initialized, they do not recieve a fully-initialized `self` as a parameter like `set` accessors do, and assignments to `initializes` stored properties in `init` accessors have the same semantics as that of a standard initializer, such as suppressing `willSet` and `didSet` observers. +However, the current syntax in this proposal, which uses an attribute, most accurately models the semantics of initialization effects. An `init` accessor is a function -- not a closure -- that has side-effects related to initialization. _Only_ the `init` accessor has these effects; though the `set` accessor often contains code that looks the same as the code in the `init` accessor, the effects of these accessors are different. Because `init` accessors are called before all of `self` is initialized, they do not receive a fully-initialized `self` as a parameter like `set` accessors do, and assignments to `initializes` stored properties in `init` accessors have the same semantics as that of a standard initializer, such as suppressing `willSet` and `didSet` observers. ## Future directions diff --git a/proposals/0402-extension-macros.md b/proposals/0402-extension-macros.md index b47ef4ee4a..80513bae90 100644 --- a/proposals/0402-extension-macros.md +++ b/proposals/0402-extension-macros.md @@ -70,7 +70,7 @@ SE-0389 states that whenever a macro produces declarations that are visible to o * The names of protocols that are listed in the extension's conformance clause. These protocols are specified in the `conformances:` list of the `@attached(conformances:)` attribute. Each name that appears in this list must be a conformance constraint, where a conformance constraint is one of: * A protocol name * A typealias whose underlying type is a conformance constraint - * A protocol composition whose entires are each a conformance constraint + * A protocol composition whose entries are each a conformance constraint The following restrictions apply to generated conformances and names listed in `@attached(extension)`: diff --git a/proposals/0403-swiftpm-mixed-language-targets.md b/proposals/0403-swiftpm-mixed-language-targets.md index 7153cfe920..c339f2e424 100644 --- a/proposals/0403-swiftpm-mixed-language-targets.md +++ b/proposals/0403-swiftpm-mixed-language-targets.md @@ -455,7 +455,7 @@ the public headers directory: The compiler assumes that the above path can be resolved relative to the public header directory. Instead of forcing package authors to structure their packages around that constraint, the Swift compiler's interop header generation -logic will be ammended to do the following in such cases where the target +logic will be amended to do the following in such cases where the target does not have the public headers directory structure of an xcframework: - If an umbrella header that is modularized by the Clang module exists, the @@ -536,11 +536,11 @@ feature will continue to [throw an error][mixed-target-error]. ## Future Directions - Enable package authors to expose non-public headers to their mixed - target's Swift implemention. + target's Swift implementation. - Extend mixed language target support to currently unsupported types of targets (e.g. executables). - Extend this solution so that all targets are mixed language targets by - default. This could simplify the implemention as language-specific types + default. This could simplify the implementation as language-specific types like `ClangTarget`, `SwiftTarget`, and `MixedTarget` could be consolidated into a single type. This approach was avoided in the initial implementation of this feature to reduce the risk of introducing a regression. diff --git a/proposals/0406-async-stream-backpressure.md b/proposals/0406-async-stream-backpressure.md index cb9f4722c2..58817b3ede 100644 --- a/proposals/0406-async-stream-backpressure.md +++ b/proposals/0406-async-stream-backpressure.md @@ -664,7 +664,7 @@ This change is additive and does not affect source compatibility. ## ABI compatibility This change is additive and does not affect ABI compatibility. All new methods -are non-inlineable leaving us flexiblity to change the implementation in the +are non-inlineable leaving us flexibility to change the implementation in the future. ## Future directions diff --git a/proposals/0410-atomics.md b/proposals/0410-atomics.md index ea54a07fac..21d348b3a2 100644 --- a/proposals/0410-atomics.md +++ b/proposals/0410-atomics.md @@ -130,7 +130,7 @@ That said, it seems highly undesirable to add low-level atomics to the default n import Synchronization ``` -We expect that most Swift projects will use atomic operations only indirectly, through higher-level synchronization constructs. Therefore, importing the `Synchronization` module will be a relatively rare occurrance, mostly limited to projects that implement such tools. +We expect that most Swift projects will use atomic operations only indirectly, through higher-level synchronization constructs. Therefore, importing the `Synchronization` module will be a relatively rare occurrence, mostly limited to projects that implement such tools. ### Atomic Memory Orderings @@ -296,7 +296,7 @@ extension Optional: AtomicRepresentable where Wrapped: AtomicOptionalRepresentab * `UnsafeMutableBufferPointer` * `UnsafeRawBufferPointer` * `UnsafeMutableRawBufferPointer` -* On 64 bit plaforms that do not support double-word atomics, the following conformances are not available: +* On 64 bit platforms that do not support double-word atomics, the following conformances are not available: * `Duration` * `UnsafeBufferPointer` * `UnsafeMutableBufferPointer` @@ -1082,7 +1082,7 @@ let myAtomic = makeAnAtomic() -In the same vein, these types must never be passed as `inout` parameters as that declares that the callee has exclusive access to the atomic, which would make the access no longer atomic. Attemping to create an `inout` binding for an atomic variable is also a compile-time error. Parameters that are used to pass `Atomic` values must either be `borrowing` or `consuming`. (Passing a variable as `consuming` is also an exclusive access, but it's destroying the original variable, so we no longer need to care for its atomicity.) +In the same vein, these types must never be passed as `inout` parameters as that declares that the callee has exclusive access to the atomic, which would make the access no longer atomic. Attempting to create an `inout` binding for an atomic variable is also a compile-time error. Parameters that are used to pass `Atomic` values must either be `borrowing` or `consuming`. (Passing a variable as `consuming` is also an exclusive access, but it's destroying the original variable, so we no longer need to care for its atomicity.) ```swift // error: parameter of type 'Atomic' must be declared as either 'borrowing' or 'consuming' @@ -1793,7 +1793,7 @@ While there are some API differences between this proposal and the package, most Previous revisions of this proposal named this type `DoubleWord`. This is a good name and is in fact the name used in the `swift-atomics` package. We felt the prefix `Double*` could cause confusion with the pre-existing type in the standard library `Double`. The name `WordPair` has a couple of advantages: -1. Code completion. Because this name starts with an less common letter in the English alphabet, the likelyhood of seeing this type at the top level in code completion is very unlikely and not generally a type used for newer programmers of Swift. +1. Code completion. Because this name starts with an less common letter in the English alphabet, the likelihood of seeing this type at the top level in code completion is very unlikely and not generally a type used for newer programmers of Swift. 2. Directly conveys the semantic meaning of the type. This type is not semantically equivalent to something like `{U}Int128` (on 64 bit platforms). While although its layout shares the same size, the meaning we want to drive home with this type is quite simply that it's a pair of `UInt` words. If and when the standard library proposes a `{U}Int128` type, that will add a conformance to `AtomicRepresentable` on 64 bit platforms who support double-words as well. That itself wouldn't deprecate uses of `WordPair` however, because it's much easier to grab both words independently with `WordPair` as well as being a portable name for such semantics on both 32 bit and 64 bit platforms. ### A different name for the `Synchronization` module diff --git a/proposals/0413-typed-throws.md b/proposals/0413-typed-throws.md index b5184677cf..9ee9502297 100644 --- a/proposals/0413-typed-throws.md +++ b/proposals/0413-typed-throws.md @@ -1102,7 +1102,7 @@ With the `rethrows` formulation of the `last(where:)` function, `getLast` will h let getLast: ((Int) -> Bool) -> Int? = primes.last(where:) // okay, E is inferred to Never ``` -Note that one would have to do the same thing with the `rethrows` formulation to produce a non-throwing `getLast`, because `rethrows` is not a part of the formal type system. Given that most `rethrows` operations are already generic in other parameters (unlike `last(where:)`), and most uses of such APIs are either calls or have type context, it is expected that the actual source compatibilty impact of replacing `rethrows` with typed errors will be small. +Note that one would have to do the same thing with the `rethrows` formulation to produce a non-throwing `getLast`, because `rethrows` is not a part of the formal type system. Given that most `rethrows` operations are already generic in other parameters (unlike `last(where:)`), and most uses of such APIs are either calls or have type context, it is expected that the actual source compatibility impact of replacing `rethrows` with typed errors will be small. ## Effect on ABI stability @@ -1356,7 +1356,7 @@ This function will only throw when `f` or `g` throw, and in both cases will tran * `rethrows` correctly communicates that this function throws only when the arguments for `f` or `g` do, but the thrown error type is treated as `any Error`. * `throws(SimpleError)` correctly communicates that this function throws errors of type `SimpleError`, but not that it throws when the argument for `f` or `g` do. -One way to address this would be to allow `rethrows` to specify the thrown error type, e.g., `rethrows(SimpleError)`, which captures both of the aspects of how this function behavies---when it throws, and what specific error type it `throws`. +One way to address this would be to allow `rethrows` to specify the thrown error type, e.g., `rethrows(SimpleError)`, which captures both of the aspects of how this function behaves---when it throws, and what specific error type it `throws`. With typed `rethrows`, a bare `rethrows` could be treated as syntactic sugar for `rethrows(any Error)`, similarly to how `throws` is syntactic sugar for `throws(any Error)`. This extension is source-compatible and allows one to express more specific error types with throwing behavior. diff --git a/proposals/0414-region-based-isolation.md b/proposals/0414-region-based-isolation.md index f3f64f9cd4..381b2176fa 100644 --- a/proposals/0414-region-based-isolation.md +++ b/proposals/0414-region-based-isolation.md @@ -853,7 +853,7 @@ longer isolated to the function since: own that the non-`Sendable` value could escape into. * Parameters in a task isolated isolation region cannot be transferred into a - different isolation domain that does have persistant isolated state. + different isolation domain that does have persistent isolated state. Thus the value in the caller's region again becomes disconnected once more and thus can be used after the function returns and be transferred again: @@ -1649,7 +1649,7 @@ because: other value will not cause `x`'s fields to point to different values. 2. When `x` is transferred to a callee, `x` will be passed by value. Thus the - callee will recieve a completely new value type albeit with copied + callee will receive a completely new value type albeit with copied fields. This means that if the callee attempts to modify the value, it will be modifying the new value instead of our caller value implying that we cannot race against any assignment when accessing the field in our diff --git a/proposals/0415-function-body-macros.md b/proposals/0415-function-body-macros.md index 57f2f54767..12797b0a2f 100644 --- a/proposals/0415-function-body-macros.md +++ b/proposals/0415-function-body-macros.md @@ -287,7 +287,7 @@ func myMath(a: Int, b: Int) -> Int { } ``` -The advantage of this approach over allowing a `body` macro to replace a body is that we can type-check the function body as it was written, and only need to do so once---then it becomes a value of function type that's passed along to the underying macro. Also like preamble macros, this approach can compose, because the result of one macro could produce another value of function type that can be passed along to another macro. [Python decorators](https://www.datacamp.com/tutorial/decorators-python) have been successful in that language for customizing the behavior of functions in a similar manner. +The advantage of this approach over allowing a `body` macro to replace a body is that we can type-check the function body as it was written, and only need to do so once---then it becomes a value of function type that's passed along to the underlying macro. Also like preamble macros, this approach can compose, because the result of one macro could produce another value of function type that can be passed along to another macro. [Python decorators](https://www.datacamp.com/tutorial/decorators-python) have been successful in that language for customizing the behavior of functions in a similar manner. ## Alternatives considered diff --git a/proposals/0417-task-executor-preference.md b/proposals/0417-task-executor-preference.md index 3c1d6b6634..9f0d5848fd 100644 --- a/proposals/0417-task-executor-preference.md +++ b/proposals/0417-task-executor-preference.md @@ -272,7 +272,7 @@ Task(executorPreference: specialExecutor) { return 12 } group.addTask(executorPreference: differentExecutor) { - // using 'differentExecutor', overriden preference + // using 'differentExecutor', overridden preference return 42 } group.addTask(executorPreference: nil) { diff --git a/proposals/0421-generalize-async-sequence.md b/proposals/0421-generalize-async-sequence.md index 42df2bab92..c0c19c4550 100644 --- a/proposals/0421-generalize-async-sequence.md +++ b/proposals/0421-generalize-async-sequence.md @@ -103,7 +103,7 @@ The new `next(isolation:)` has a default implementation so that conformances wil ### Adopting typed throws -Concrete `AsyncSequence` and `AsyncIteratorProtocol` types determine whether calling `next()` can `throw`. This can be described in each protocol with a `Failure` associated type that is thrown by the `AsyncIteratorProtcol.next(isolation:)` requirement. Describing the thrown error with an associated type allows conformances to fulfill the requirement with a type parameter, which means that libraries do not need to expose separate throwing and non-throwing concrete types that otherwise have the same async iteration functionality. +Concrete `AsyncSequence` and `AsyncIteratorProtocol` types determine whether calling `next()` can `throw`. This can be described in each protocol with a `Failure` associated type that is thrown by the `AsyncIteratorProtocol.next(isolation:)` requirement. Describing the thrown error with an associated type allows conformances to fulfill the requirement with a type parameter, which means that libraries do not need to expose separate throwing and non-throwing concrete types that otherwise have the same async iteration functionality. #### Error type inference from `for try await` loops @@ -213,7 +213,7 @@ Both function requirements of `AsyncIteratorProtocol` have default implementatio To avoid silently allowing conformances that implement neither requirement, and to facilitate the transition of conformances from `next()` to `next(isolation:)`, we add a new availability rule where the witness checker diagnoses a protocol conformance that uses an deprecated, obsoleted, or unavailable default witness implementation. Deprecated implementations will produce a warning, while obsoleted and unavailable implementations will produce an error. -Because the default implementation of `next(isolation:)` is deprecated, conformances that do not provide a direct implementation will produce a warning. This is desirable because the default implementation of `next(isolation:)` violates `Sendable` checking, so while it's necessary for source compatibilty, it's important to aggressively suggest that conforming types implement the new method. +Because the default implementation of `next(isolation:)` is deprecated, conformances that do not provide a direct implementation will produce a warning. This is desirable because the default implementation of `next(isolation:)` violates `Sendable` checking, so while it's necessary for source compatibility, it's important to aggressively suggest that conforming types implement the new method. ### Associated type inference for `AsyncIteratorProtocol` conformances diff --git a/proposals/0423-dynamic-actor-isolation.md b/proposals/0423-dynamic-actor-isolation.md index 1d4b1b08b3..fb7215418e 100644 --- a/proposals/0423-dynamic-actor-isolation.md +++ b/proposals/0423-dynamic-actor-isolation.md @@ -163,7 +163,7 @@ This feature can be freely adopted and un-adopted in source code with no deploym ### Always emit dynamic checks upon entry to synchronous isolated functions -A previous iteration of this proposal specified that dynamic actor isolation checks are always emitted upon entry to a synchronous isolated function. This approach is foolproof; there's little possiblity for missing a dynamic check for code that can be called from another module that does not have strict concurrency checking at compile time. However, the major downside of this approach is that code will be paying the price of runtime overhead for actor isolation checking even when actor isolation is fully enforced at compile time in Swift 6. +A previous iteration of this proposal specified that dynamic actor isolation checks are always emitted upon entry to a synchronous isolated function. This approach is foolproof; there's little possibility for missing a dynamic check for code that can be called from another module that does not have strict concurrency checking at compile time. However, the major downside of this approach is that code will be paying the price of runtime overhead for actor isolation checking even when actor isolation is fully enforced at compile time in Swift 6. The current approach in this proposal has a very desirable property of eliminated more runtime overhead as more of the Swift ecosystem transitions to Swift 6 at the cost of introducing the potential for missing dynamic checks where synchronous functions can be called from not-statically-checked code. We believe this is the right tradeoff for the long term arc of data race safety in Swift 6 and beyond, but it may require more special cases when we discover code patterns that are not covered by the specific set of rules in this proposal. diff --git a/proposals/0424-custom-isolation-checking-for-serialexecutor.md b/proposals/0424-custom-isolation-checking-for-serialexecutor.md index 3bc0b1e290..d04cc3d7fc 100644 --- a/proposals/0424-custom-isolation-checking-for-serialexecutor.md +++ b/proposals/0424-custom-isolation-checking-for-serialexecutor.md @@ -140,7 +140,7 @@ extension DispatchSerialQueue { An executor that wishes to take advantage of this proposal will need to have some mechanism to identity its active worker thread. If that's not possible or desired, the executor should leave the default implementation (that unconditionally crashes) in place. -### Impact on async code and isolation assumtions +### Impact on async code and isolation assumptions The `assumeIsolated(_:file:line:)` APIs purposefully only accept a **synchronous** closure. This is correct, and it remains correct with these proposed additions. An isolation check on an executor ensures that any actor using the executor is synchronously isolated, and the closure provided to `assumeIsolated` will execute prior to any possible async suspension. This is what makes it safe to access actor-isolated state within the closure. diff --git a/proposals/0426-bitwise-copyable.md b/proposals/0426-bitwise-copyable.md index 9c8d5a008d..f057c4dd5e 100644 --- a/proposals/0426-bitwise-copyable.md +++ b/proposals/0426-bitwise-copyable.md @@ -351,7 +351,7 @@ This would be visible to the programmer in several ways: - different overloads would be selected for a value of concrete type from those selected for a value dynamically cast to `BitwiseCopyable` - dynamic casts to `BitwiseCopyable` could fail, then succeed, then fail again in successive OS versions -On the other hand, these behavioral differences may be desireable. +On the other hand, these behavioral differences may be desirable. Considering that this approach would just ignore the existence of conformances to `BitwiseCopyable`, it would be reasonable to ignore the existence of a suppressed conformance as well. diff --git a/proposals/0428-resolve-distributed-actor-protocols.md b/proposals/0428-resolve-distributed-actor-protocols.md index 4dd61d0d8b..52a6964f52 100644 --- a/proposals/0428-resolve-distributed-actor-protocols.md +++ b/proposals/0428-resolve-distributed-actor-protocols.md @@ -412,7 +412,7 @@ extension Greeter { This simplified snippet does not solve the problem about introducing the new protocol requirement in a binary compatible way, and we'd have to come up with some pattern for it -- however the general direction of allowing introducing new versions of APIs with easier deprecation of old ones is something we'd like to explore in the future. -Support for renaming methods could also be provided, such that the legacy method can be called `__deprecated_greet()` for example, while maintaining the "legacy name" of "`greet()`". Overall, we believe that the protocol evolution story here is somethign we will have to flesh out in the near future, anf feel we have the tools to do so. +Support for renaming methods could also be provided, such that the legacy method can be called `__deprecated_greet()` for example, while maintaining the "legacy name" of "`greet()`". Overall, we believe that the protocol evolution story here is something we will have to flesh out in the near future, anf feel we have the tools to do so. ### Consider customization points for distributed call target metadata assignment diff --git a/proposals/0433-mutex.md b/proposals/0433-mutex.md index 30662cf070..f98a9cef27 100644 --- a/proposals/0433-mutex.md +++ b/proposals/0433-mutex.md @@ -86,7 +86,7 @@ Below is the complete API design for the new `Mutex` type: /// class Manager { /// let cache = Mutex<[Key: Resource]>([:]) /// -/// func saveResouce(_ resource: Resouce, as key: Key) { +/// func saveResource(_ resource: Resource, as key: Key) { /// cache.withLock { /// $0[key] = resource /// } @@ -177,7 +177,7 @@ extension Mutex where State: ~Copyable { ## Interaction with Existing Language Features -`Mutex` will be decorated with the `@_staticExclusiveOnly` attribute, meaning you will not be able to declare a variable of type `Mutex` as `var`. These are the same restrictions imposed on the recently accepted `Atomic` and `AtomicLazyReference` types. Please refer to the [Atomics proposal](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0410-atomics.md) for a more in-depth discussion on what is allowed and not allowed. These restrictions are enabled for `Mutex` for all of the same reasons why it was resticted for `Atomic`. We do not want to introduce dynamic exclusivity checking when accessing a value of `Mutex` as a class stored property for instance. +`Mutex` will be decorated with the `@_staticExclusiveOnly` attribute, meaning you will not be able to declare a variable of type `Mutex` as `var`. These are the same restrictions imposed on the recently accepted `Atomic` and `AtomicLazyReference` types. Please refer to the [Atomics proposal](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0410-atomics.md) for a more in-depth discussion on what is allowed and not allowed. These restrictions are enabled for `Mutex` for all of the same reasons why it was restricted for `Atomic`. We do not want to introduce dynamic exclusivity checking when accessing a value of `Mutex` as a class stored property for instance. ### Interactions with Swift Concurrency @@ -224,7 +224,7 @@ By marking the closure as such, we've effectively declared that the mutex is in The mutex type we're proposing is a synchronous lock. This means when other participants want to acquire the lock to access the protected shared data, they will halt execution until they are able to do so. Threads that are waiting to acquire the lock will not be able to make forward progress until their request to acquire the lock has completed. This can lead to thread contention if the acquired thread's critical section is not able to be executed relatively quickly exhausting resources for the rest of the system to continue making forward progress. Synchronous locks are also prone to deadlocks (which Swift's actors cannot currently encounter due to their re-entrant nature) and live-locks which can leave a process in an unrecoverable state. These scenarios can occur when there is a complex hierarchy of different locks that manage to depend on the acquisition of each other. -Actors work very differently. Typical use of an actor doesn't request access to underlying shared data, but rather instruct the actor to perform some operation or service that has exclusive access to that data. An execution context making this request may need to await on the return value of that operation, but with Swift's `async`/`await` model it can immediately start doing other work allowing it to make forward progress on other tasks. The actor executes requests in a serial fashion in the order they are made. This ensures that the shared mutable state is only accessed by the actor. Deadlocks are not possible with the actor model. Asynchronous code that is dependent on a specific operation and resouce from an actor can be later resumed once the actor has serviced that request. While deadlocking is not possible, there are other problems actors have such as the actor reentrancy problem where the state of the actor has changed when the executing operation got resumed after a suspension point. +Actors work very differently. Typical use of an actor doesn't request access to underlying shared data, but rather instruct the actor to perform some operation or service that has exclusive access to that data. An execution context making this request may need to await on the return value of that operation, but with Swift's `async`/`await` model it can immediately start doing other work allowing it to make forward progress on other tasks. The actor executes requests in a serial fashion in the order they are made. This ensures that the shared mutable state is only accessed by the actor. Deadlocks are not possible with the actor model. Asynchronous code that is dependent on a specific operation and resource from an actor can be later resumed once the actor has serviced that request. While deadlocking is not possible, there are other problems actors have such as the actor reentrancy problem where the state of the actor has changed when the executing operation got resumed after a suspension point. Mutexes and actors are very different synchronization tools that help protect shared mutable state. While they can both achieve synchronization of that data access, they do so in varying ways that may be desirable for some and undesirable for others. The proposed `Mutex` is yet another primitive that Swift should expose to help those achieve concurrency safe programs in cases where actors aren't suitable. diff --git a/proposals/0438-metatype-keypath.md b/proposals/0438-metatype-keypath.md index 2cf3efbf4b..94b2bdb954 100644 --- a/proposals/0438-metatype-keypath.md +++ b/proposals/0438-metatype-keypath.md @@ -116,7 +116,7 @@ This feature is back-deployable but it requires emission of new (property descri The type-checker wouldn't allow to form key paths to static properties of types that come from modules that are built by an older compiler that don't support the feature because dynamic or static library produced for such module won't have all of the required symbols. -Attempting to form a key path to a static property of a type from a module compiled with a complier that doesn't yet support the feature will result in the following error with a note to help the developers: +Attempting to form a key path to a static property of a type from a module compiled with a compiler that doesn't yet support the feature will result in the following error with a note to help the developers: ```swift error: cannot form a keypath to a static property of type diff --git a/proposals/0440-debug-description-macro.md b/proposals/0440-debug-description-macro.md index bfda4c3771..e374da0f85 100644 --- a/proposals/0440-debug-description-macro.md +++ b/proposals/0440-debug-description-macro.md @@ -212,7 +212,7 @@ A similar future direction is to support sharing Swift `customMirror` definition ### Explicit LLDB Summary Strings -The simplest macro implementation is one that performs no Swift-to-LLDB translation and directly accepts an LLDB Summary String. This approach requires users to know LLDB Summary String syntax, which while not complex, still presents a hinderance to adoption. Such a macro would could create redundancy: `debugDescription` and the separate LLDB Summary String. These would need to be manually kept in sync. +The simplest macro implementation is one that performs no Swift-to-LLDB translation and directly accepts an LLDB Summary String. This approach requires users to know LLDB Summary String syntax, which while not complex, still presents a hindrance to adoption. Such a macro would could create redundancy: `debugDescription` and the separate LLDB Summary String. These would need to be manually kept in sync. ### Independent Property (No `debugDescription` Reuse) diff --git a/proposals/0442-allow-taskgroup-childtaskresult-type-to-be-inferred.md b/proposals/0442-allow-taskgroup-childtaskresult-type-to-be-inferred.md index 1abe4d92f3..1e10c07770 100644 --- a/proposals/0442-allow-taskgroup-childtaskresult-type-to-be-inferred.md +++ b/proposals/0442-allow-taskgroup-childtaskresult-type-to-be-inferred.md @@ -47,7 +47,7 @@ public func withTaskGroup( The function signature of `withThrowingTaskGroup(of:returning:body:)` is nearly identical, so only `withTaskGroup(of:returning:body:)` will be used as an example throughout this proposal. -Note that the `GroupResult` generic is inferrable via the `= GroupResult.self` default argument. This can also be applied to `ChildTaskResult` as of [SE-0326](0326-extending-multi-statement-closure-inference.md). As in: +Note that the `GroupResult` generic is inferable via the `= GroupResult.self` default argument. This can also be applied to `ChildTaskResult` as of [SE-0326](0326-extending-multi-statement-closure-inference.md). As in: ```swift public func withTaskGroup(