Skip to content

Commit f19aca6

Browse files
authored
[WIP] Revise documentation for Swift 5 stdlib additions (#21333)
* Revise the Unicode scalar/Character properties * Minor revisions to `compactMapValues` docs. * Add documentation for AdditiveArithmetic, revise Numeric * Apply minor style updates to count(where:). * Revise string interpolation docs. - Convert table of interpolation examples to a list of examples. Tables aren't supported by Swift markup, so this wouldn't render properly in Xcode or on the web. - Add a description of what a user must implement in a custom string interpolation type to get the behavior they want. * Revise isMultiple(of:) docs. - In particular, add emphasis to mathematical symbols and equations to match how we document such things elsewhere. - I'm using asterisks for single symbols, and underscores for equations because it's easier to read in-source when you don't have to escape multiplication within emphasis. * Add some abstracts to the SIMD vector types. - Adds a dictionary of spelled out numbers. Only numbers < 10 should be spelled out according to editorial. - Adds abstracts to some of the basic members. - Includes parameter descriptions for the xyzw properties and inits, but not for the unlabeled initializers. Combined with the protocol extension method abstracts, this should complete coverage of the concrete types.
1 parent ea8e2a2 commit f19aca6

9 files changed

+693
-462
lines changed

stdlib/public/core/CharacterProperties.swift

Lines changed: 171 additions & 119 deletions
Large diffs are not rendered by default.

stdlib/public/core/CompilerProtocols.swift

Lines changed: 99 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -709,45 +709,49 @@ public protocol ExpressibleByDictionaryLiteral {
709709
/// print(message)
710710
/// // Prints "One cookie: $2, 3 cookies: $6."
711711
///
712-
/// Extending default interpolation behavior
713-
/// ========================================
714-
///
715-
/// Clients which want to add new interpolation behavior to existing types
716-
/// should extend `DefaultStringInterpolation`, the type which implements
717-
/// interpolation for types like `String` and `Substring`, to add an overload of
718-
/// `appendInterpolation(_:)` with their new behavior. See the
719-
/// `DefaultStringInterpolation` and `StringInterpolationProtocol` documentation
720-
/// for more details.
712+
/// Extending the Default Interpolation Behavior
713+
/// ============================================
721714
///
722-
/// Creating a type which supports default string interpolation
723-
/// ===========================================================
715+
/// Add new interpolation behavior to existing types by extending
716+
/// `DefaultStringInterpolation`, the type that implements interpolation for
717+
/// types like `String` and `Substring`, to add an overload of
718+
/// `appendInterpolation(_:)` with their new behavior.
719+
///
720+
/// For more information, see the `DefaultStringInterpolation` and
721+
/// `StringInterpolationProtocol` documentation.
724722
///
725-
/// Clients which want to create new types supporting string literals and
726-
/// interpolation, but which do not need any custom behavior, should conform
727-
/// their type to `ExpressibleByStringInterpolation` and implement an
728-
/// `init(stringLiteral: String)` method. Swift will automatically use
729-
/// `DefaultStringInterpolation` and provide an `init(stringInterpolation:)`
730-
/// implementation which passes the interpolated literal's contents to
731-
/// `init(stringLiteral:)`, so you won't need to implement anything special.
732-
///
733-
/// Creating a type which supports custom string interpolation
734-
/// ==========================================================
723+
/// Creating a Type That Supports the Default String Interpolation
724+
/// ==============================================================
735725
///
736-
/// If a conforming type wants to differentiate between literal and interpolated
737-
/// segments, restrict the types which can be interpolated into it, support
738-
/// different interpolators from the ones on `String`, or avoid constructing a
739-
/// `String` containing the data, it must specify a custom `StringInterpolation`
740-
/// associated type. This type must conform to `StringInterpolationProtocol` and
741-
/// must have a matching `StringLiteralType`.
742-
///
743-
/// See the `StringLiteralProtocol` documentation for more details about how to
744-
/// do this.
726+
/// To create a new type that supports string literals and interpolation, but
727+
/// that doesn't need any custom behavior, conform the type to
728+
/// `ExpressibleByStringInterpolation` and implement the
729+
/// `init(stringLiteral: String)` initializer declared by the
730+
/// `ExpressibleByStringLiteral` protocol. Swift will automatically use
731+
/// `DefaultStringInterpolation` as the interpolation type and provide an
732+
/// implementation for `init(stringInterpolation:)` that passes the
733+
/// interpolated literal's contents to `init(stringLiteral:)`, so you don't
734+
/// need to implement anything specific to this protocol.
735+
///
736+
/// Creating a Type That Supports Custom String Interpolation
737+
/// =========================================================
738+
///
739+
/// If you want a conforming type to differentiate between literal and
740+
/// interpolated segments, restrict the types that can be interpolated,
741+
/// support different interpolators from the ones on `String`, or avoid
742+
/// constructing a `String` containing the data, the type must specify a custom
743+
/// `StringInterpolation` associated type. This type must conform to
744+
/// `StringInterpolationProtocol` and have a matching `StringLiteralType`.
745+
///
746+
/// For more information, see the `StringInterpolationProtocol` documentation.
745747
public protocol ExpressibleByStringInterpolation
746748
: ExpressibleByStringLiteral {
747749

748750
/// The type each segment of a string literal containing interpolations
749-
/// should be appended to. Its `StringLiteralType` should match the
750-
/// `StringLiteralType` of this type.
751+
/// should be appended to.
752+
///
753+
/// The `StringLiteralType` of an interpolation type must match the
754+
/// `StringLiteralType` of the conforming type.
751755
associatedtype StringInterpolation : StringInterpolationProtocol
752756
= DefaultStringInterpolation
753757
where StringInterpolation.StringLiteralType == StringLiteralType
@@ -770,7 +774,7 @@ extension ExpressibleByStringInterpolation
770774

771775
/// Creates a new instance from an interpolated string literal.
772776
///
773-
/// Do not call this initializer directly. It is used by the compiler when
777+
/// Don't call this initializer directly. It's used by the compiler when
774778
/// you create a string using string interpolation. Instead, use string
775779
/// interpolation to create a new string by including values, literals,
776780
/// variables, or expressions enclosed in parentheses, prefixed by a
@@ -782,14 +786,13 @@ extension ExpressibleByStringInterpolation
782786
/// If one cookie costs \(price) dollars, \
783787
/// \(number) cookies cost \(price * number) dollars.
784788
/// """
785-
/// print(message)
786-
/// // Prints "If one cookie costs 2 dollars, 3 cookies cost 6 dollars."
789+
/// // message == "If one cookie costs 2 dollars, 3 cookies cost 6 dollars."
787790
public init(stringInterpolation: DefaultStringInterpolation) {
788791
self.init(stringLiteral: stringInterpolation.make())
789792
}
790793
}
791794

792-
/// Represents the contents of a string literal with interpolations while it is
795+
/// Represents the contents of a string literal with interpolations while it's
793796
/// being built up.
794797
///
795798
/// Each `ExpressibleByStringInterpolation` type has an associated
@@ -809,76 +812,94 @@ extension ExpressibleByStringInterpolation
809812
/// The `StringInterpolation` type is responsible for collecting the segments
810813
/// passed to its `appendLiteral(_:)` and `appendInterpolation` methods and
811814
/// assembling them into a whole, converting as necessary. Once all of the
812-
/// segments have been appended, the interpolation will be passed to an
815+
/// segments are appended, the interpolation is passed to an
813816
/// `init(stringInterpolation:)` initializer on the type being created, which
814817
/// must extract the accumulated data from the `StringInterpolation`.
815818
///
816-
/// In simple cases, types conforming to `ExpressibleByStringInterpolation`
817-
/// can use `DefaultStringInterpolation` instead of writing their own. All they
818-
/// must do is conform to `ExpressibleByStringInterpolation` and implement
819-
/// `init(stringLiteral: String)`; interpolated string literals will then go
820-
/// through that initializer just as any other string literal would.
819+
/// In simple cases, you can use `DefaultStringInterpolation` as the
820+
/// interpolation type for types that conform to the
821+
/// `ExpressibleByStringLiteral` protocol. To use the default interpolation,
822+
/// conform a type to `ExpressibleByStringInterpolation` and implement
823+
/// `init(stringLiteral: String)`. Values in interpolations are converted to
824+
/// strings, and then passed to that initializer just like any other string
825+
/// literal.
821826
///
822-
/// The `appendInterpolation` Method
823-
/// ================================
824-
///
825-
/// Each interpolated segment is translated into a call to a
826-
/// `StringInterpolationProtocol.appendInterpolation(...)` method, with the
827-
/// contents of the interpolation's parentheses treated as the call's argument
828-
/// list. That argument list can include multiple arguments and argument labels.
829-
/// For example:
830-
///
831-
/// | If you write... | Swift calls... |
832-
/// |---------------- | --------------------------------- |
833-
/// | `\(x)` | `appendInterpolation(x)` |
834-
/// | `\(x, y)` | `appendInterpolation(x, y)` |
835-
/// | `\(foo: x)` | `appendInterpolation(foo: x)` |
836-
/// | `\(x, foo: y)` | `appendInterpolation(x, foo: y)` |
837-
///
838-
/// `appendInterpolation` methods should return `Void` and should not be
839-
/// `static`. They otherwise support virtually all features of methods: they can
840-
/// have any number of parameters, can specify labels for any or all of them,
841-
/// can provide default values for parameters, can have variadic parameters, and
842-
/// can have parameters with generic types. Most importantly, they can be
843-
/// overloaded, so a `StringInterpolationProtocol`-conforming type can provide
844-
/// several different `appendInterpolation` methods with different behaviors.
845-
/// `appendInterpolation` methods can also throw; when a user uses one of these,
846-
/// they must mark the string literal with `try` or one of its variants.
827+
/// Handling String Interpolations
828+
/// ==============================
829+
///
830+
/// With a custom interpolation type, each interpolated segment is translated
831+
/// into a call to a special `appendInterpolation` method. The contents of
832+
/// the interpolation's parentheses are treated as the call's argument list.
833+
/// That argument list can include multiple arguments and argument labels.
834+
///
835+
/// The following examples show how string interpolations are translated into
836+
/// calls to `appendInterpolation`:
837+
///
838+
/// - `\(x)` translates to `appendInterpolation(x)`
839+
/// - `\(x, y)` translates to `appendInterpolation(x, y)`
840+
/// - `\(foo: x)` translates to `appendInterpolation(foo: x)`
841+
/// - `\(x, foo: y)` translates to `appendInterpolation(x, foo: y)`
842+
///
843+
/// The `appendInterpolation` methods in your custom type must be mutating
844+
/// instance methods that return `Void`. This code shows a custom interpolation
845+
/// type's declaration of an `appendInterpolation` method that provides special
846+
/// validation for user input:
847+
///
848+
/// extension MyString.StringInterpolation {
849+
/// mutating func appendInterpolation(validating input: String) {
850+
/// // Perform validation of `input` and store for later use
851+
/// }
852+
/// }
853+
///
854+
/// To use this interpolation method, create a string literal with an
855+
/// interpolation using the `validating` parameter label.
856+
///
857+
/// let userInput = readLine() ?? ""
858+
/// let myString = "The user typed '\(validating: userInput)'." as MyString
859+
///
860+
/// `appendInterpolation` methods support virtually all features of methods:
861+
/// they can have any number of parameters, can specify labels for any or all
862+
/// of their parameters, can provide default values, can have variadic
863+
/// parameters, and can have parameters with generic types. Most importantly,
864+
/// they can be overloaded, so a type that conforms to
865+
/// `StringInterpolationProtocol` can provide several different
866+
/// `appendInterpolation` methods with different behaviors. An
867+
/// `appendInterpolation` method can also throw; when a user writes a literal
868+
/// with one of these interpolations, they must mark the string literal with
869+
/// `try` or one of its variants.
847870
public protocol StringInterpolationProtocol {
848871
/// The type that should be used for literal segments.
849872
associatedtype StringLiteralType : _ExpressibleByBuiltinStringLiteral
850873

851874
/// Creates an empty instance ready to be filled with string literal content.
852875
///
853-
/// Do not call this initializer directly. Instead, initialize a variable or
876+
/// Don't call this initializer directly. Instead, initialize a variable or
854877
/// constant using a string literal with interpolated expressions.
855878
///
856879
/// Swift passes this initializer a pair of arguments specifying the size of
857880
/// the literal segments and the number of interpolated segments. Use this
858-
/// information to estimate the amount of storage you will need and
859-
/// pre-allocate it with a method like
860-
/// `RangeReplaceableCollection.reserveCapacity(_:)`.
881+
/// information to estimate the amount of storage you will need.
861882
///
862883
/// - Parameter literalCapacity: The approximate size of all literal segments
863884
/// combined. This is meant to be passed to `String.reserveCapacity(_:)`;
864-
/// it may be slightly larger or smaller than the sum of `String.count`
865-
/// called on each literal segment.
885+
/// it may be slightly larger or smaller than the sum of the counts of each
886+
/// literal segment.
866887
/// - Parameter interpolationCount: The number of interpolations which will be
867888
/// appended. Use this value to estimate how much additional capacity will
868889
/// be needed for the interpolated segments.
869890
init(literalCapacity: Int, interpolationCount: Int)
870891

871892
/// Appends a literal segment to the interpolation.
872893
///
873-
/// Do not call this method directly. Instead, initialize a variable or
894+
/// Don't call this method directly. Instead, initialize a variable or
874895
/// constant using a string literal with interpolated expressions.
875896
///
876-
/// Interpolated expressions do not pass through this method; instead, Swift
877-
/// selects an overload of `appendInterpolation`. See the top-level
878-
/// `StringInterpolationProtocol` documentation for more details.
897+
/// Interpolated expressions don't pass through this method; instead, Swift
898+
/// selects an overload of `appendInterpolation`. For more information, see
899+
/// the top-level `StringInterpolationProtocol` documentation.
879900
///
880901
/// - Parameter literal: A string literal containing the characters
881-
/// that appear next in the string literal.
902+
/// that appear next in the string literal.
882903
mutating func appendLiteral(_ literal: StringLiteralType)
883904

884905
// Informal requirement: Any desired appendInterpolation overloads, e.g.:

stdlib/public/core/Dictionary.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -921,10 +921,10 @@ extension Dictionary {
921921
}
922922

923923
/// Returns a new dictionary containing only the key-value pairs that have
924-
/// non-`nil` values as the result from the transform by the given closure.
924+
/// non-`nil` values as the result of transformation by the given closure.
925925
///
926-
/// Use this method to receive a dictionary of non-optional values when your
927-
/// transformation can produce an optional value.
926+
/// Use this method to receive a dictionary with non-optional values when
927+
/// your transformation produces optional values.
928928
///
929929
/// In this example, note the difference in the result of using `mapValues`
930930
/// and `compactMapValues` with a transformation that returns an optional

0 commit comments

Comments
 (0)