Skip to content

Instantly share code, notes, and snippets.

@erica
Created March 13, 2018 18:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erica/ca78e9f06e47eb2da6fc09e6528535a1 to your computer and use it in GitHub Desktop.
Save erica/ca78e9f06e47eb2da6fc09e6528535a1 to your computer and use it in GitHub Desktop.

Introducing new syntax

Swift forum feedback included the introduction of a new syntax instead of properties. Enum labels are sometimes written to read like a function:

enum Selection {
    case range(from: Int, to: Int)
    case discreteIndices(in: [Int], inverted: Bool)
}

Using properties could introduce readability issues, as in the following example, where fluency is lost in translation.

let selection = Selection.range(from: 1, to: 2)
selection.range?.to // = .some(2)
selection.discreteIndices?.in.first

"Functional" label style is meant to enhance construction readability. Using these labels in isolation produces potentially confusing property names. Focusing on construction fluency is not a wide-spread concern for many developers, who more often use structure-like property names for their labels. This enables individual instances to address someEnum.box.width (essentially, instance.case.label) instead of someEnum.box.withWidth in the current version of Swift.

"Functional construction" a minority style. Pending implementation of SE-0155, tuple binding operates using property-like accessors:

switch selection {
case let range(range):
    range.to // Int
case let discreteIndices(discreteIndices):
    range.in.first // Int?
}

New grammars based on pattern matching were also suggested:

// using `case` expressions
(case .anotherCase = (case .value = result)?.someOtherProperty)?.name

// using a `matches` operator
selection matches .range(from: _, to: let upperBound) // = .some(2)
(selection matches .discreteIndices(let indices, _))?.first
selection matches let .range(a, b) // produces an (a: Int, b: Int)?

These grammars add weight to the language and lead to more unanswered questions. When bindings are used, as in the second example, to express values rather than bind variables, are those variables made available anywhere in scope? How do these solutions work with pattern matching as a whole?

These solutions also fail to provide key path support to enums.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment