:orphan:

One of the issues that came up in our design discussions around ``Result`` was
that enum cases don't really follow the conventions of anything else in our
system. Our current convention for enum cases is to use
``CapitalizedCamelCase``. This convention arose from the Cocoa
``NSEnumNameCaseName`` convention for constants, but the convention feels
foreign even in the context of Objective-C. Non-enum type constants in Cocoa
are often namespaced into classes, using class methods such as ``[UIColor
redColor]`` (and would likely have been class properties if those were
supported by ObjC). It's also worth noting that our "builtin" enum-like
keywords such as ``true``, ``false``, and ``nil`` are lowercased, more like
properties.

Swift also has enum cases with associated values, which don't have an immediate
analog in Cocoa to draw inspiration from, but if anything feel
"initializer-like".  Aside from naming style, working with enum values also
requires a different set of tools from other types, pattern matching with
``switch`` or ``if case`` instead of working with more readily-composable
expressions. The compound effect of these style mismatches is that enums in the
wild tend to grow a bunch of boilerplate helper members in order to make them
fit better with other types.  For example, ``Optional``, aside from the massive
amounts of language sugar it's given, vends initializers corresponding to
``Some`` and ``None`` cases::

  extension Optional {
    init(_ value: Wrapped) {
      self = .Some(value)
    }

    init() {
      self = .None
    }
  }

``Result`` was proposed to have not only initializers corresponding to its
``Success`` and ``Error`` cases, but accessor properties as well::

  extension Result {
    init(success: Wrapped) {
      self = .Success(success)
    }
    init(error: Error) {
      self = .Error(error)
    }

    var success: Wrapped? {
      switch self {
      case .Success(let success): return success
      case .Error: return nil
      }
    }
    var error: Error? {
      switch self {
      case .Success: return nil
      case .Error(let error): return error
      }
    }
  }

This pattern of boilerplate also occurs in third-party frameworks that make
heavy use of enums. Some examples from Github:

- https://github.com/antitypical/Manifold/blob/ae94eb96085c2c8195d457e06df485b1cca455cb/Manifold/Name.swift
- https://github.com/antitypical/TesseractCore/blob/73099ae5fa772b90cefa49395f237290d8363f76/TesseractCore/Symbol.swift
- https://github.com/antitypical/TesseractCore/blob/73099ae5fa772b90cefa49395f237290d8363f76/TesseractCore/Value.swift

That people inside and outside of our team consider this boilerplate necessary
for enums is a strong sign we should improve our core language design.
I'd like to start discussion by proposing the following:

- Because cases with associated values are initializer-like, declaring and
  using them ought to feel like using initializers on other types.
  A ``case`` declaration should be able to declare an initializer, which
  follows the same keyword naming rules as other initializers, for example::

    enum Result<Wrapped> {
      case init(success: Wrapped)
      case init(error: Error)
    }

  Constructing a value of the case can then be done with the usual initializer
  syntax::

    let success = Result(success: 1)
    let error = Result(error: SillyError.JazzHands)

  And case initializers can be pattern-matched using initializer-like
  matching syntax::

    switch result {
    case Result(success: let success):
      ...
    case Result(error: let error):
      ...
    }

- Enums with associated values implicitly receive ``internal`` properties
  corresponding to the argument labels of those associated values. The
  properties are optional-typed unless a value with the same name and type
  appears in every ``case``. For example, this enum::

    public enum Example {
      case init(foo: Int, alwaysPresent: String)
      case init(bar: Int, alwaysPresent: String)
    }

  receives the following implicit members::

    /*implicit*/
    internal extension Example {
      var foo: Int? { get }
      var bar: Int? { get }
      var alwaysPresent: String { get } // Not optional
    }

- Because cases without associated values are property-like, they ought to
  follow the ``lowercaseCamelCase`` naming convention of other properties.
  For example::

    enum ComparisonResult {
      case descending, same, ascending
    }

    enum Bool {
      case true, false
    }

    enum Optional<Wrapped> {
      case nil
      case init(_ some: Wrapped)
    }

Since this proposal affects how we name things, it has ABI stability
implications (albeit ones we could hack our way around with enough symbol
aliasing), so I think we should consider this now. It also meshes with other
naming convention discussions that have been happening.

I'll discuss the points above in more detail:

Case Initializers
=================

Our standard recommended style for cases with associated values should be
to declare them as initializers with keyword arguments, much as we do
other kinds of initializer::

  enum Result<Wrapped> {
    case init(success: Wrapped)
    case init(error: Error)
  }

  enum List<Element> {
    case empty
    indirect case init(element: Element, rest: List<Element>)
  }

It should be possible to declare unlabeled case initializers too, for types
like Optional with a natural "primary" case::

  enum Optional<Wrapped> {
    case nil
    case init(_ some: Wrapped)
  }

Patterns should also be able to match against case initializers::

  switch result {
  case Result(success: let s):
    ...
  case Result(error: let e):
    ...
  }

Overloading
-----------

I think it would also be reasonable to allow overloading of case initializers,
as long as the associated value types cannot overlap. (If the keyword labels
are overloaded and the associated value types overlap, there would
be no way to distinguish the cases.) Overloading is not essential, though, and
it would be simpler to disallow it.

Named cases with associated values
----------------------------------

One question would be, if we allow ``case init`` declarations, whether we
should also remove the existing ability to declare named cases with associated
values::

  enum Foo {
    // OK
    case init(foo: Int)
    // Should this become an error?
    case foo(Int)
  }

Doing so would help unambiguously push the new style, but would drive a
syntactic wedge between associated-value and no-associated-value cases.
If we keep named cases with associated values, I think we should consider
altering the declaration syntax to require keyword labels (or explicit ``_``
to suppress labels), for better consistency with other function-like decls::

  enum Foo {
    // Should be a syntax error, 'label:' expected
    case foo(Int)

    // OK
    case foo(_: Int)

    // OK
    case foo(label: Int)
  }

Shorthand for init-style cases
------------------------------

Unlike enum cases and static methods, initializers currently don't have any
contextual shorthand when the type of an initialization can be inferred from
context. This could be seen as an expressivity regression in some cases.
With named cases, one can write::

  foo(.Left(x))

but with case initializers, they have to write::

  foo(Either(left: x))

Some would argue this is clearer. It's a bit more painful in ``switch``
patterns, though, where the type would need to be repeated redundantly::

  switch x {
  case Either(left: let left):
    ...
  case Either(right: let right):
    ...
  }

One possibility would be to allow ``.init``, like we do other static methods::

  switch x {
  case .init(left: let left):
    ...
  case .init(right: let right):
    ...
  }

Or maybe allow labeled tuple patterns to match, leaving the name off
altogether::

  switch x {
  case (left: let left):
    ...
  case (right: let right):
    ...
  }

Implicit Case Properties
========================

The only native operation enums currently support is ``switch``-ing. This is
nice and type-safe, but ``switch`` is heavyweight and not very expressive.
We now have a large set of language features and library operators for working
with ``Optional``, so it is expressive and convenient in many cases to be able
to project associated values from enums as ``Optional`` values. As noted above,
third-party developers using enums often write out the boilerplate to do this.
We should automate it. For every ``case init`` with labeled associated values,
we can generate an ``internal`` property to access that associated value.
The value will be ``Optional``, unless every ``case`` has the same associated
value, in which case it can be nonoptional. To repeat the above example, this
enum::

  public enum Example {
    case init(foo: Int, alwaysPresent: String)
    case init(bar: Int, alwaysPresent: String)
  }

receives the following implicit members::

  /*implicit*/
  internal extension Example {
    var foo: Int? { get }
    var bar: Int? { get }
    var alwaysPresent: String { get } // Not optional
  }

Similar to the elementwise initializer for ``struct`` types, these property
accessors should be ``internal``, since they rely on potentially fragile layout
characteristics of the enum. (Like the struct elementwise initializer, we
ought to have a way to easily export these properties as ``public`` when
desired too, but that can be designed separately.)

These implicit properties should be read-only, until we design a model for
enum mutation-by-part.

An associated value property should be suppressed if:

- there's an explicit declaration in the type with the same name::

    enum Foo {
      case init(foo: Int)

      var foo: String { return "foo" } // suppresses implicit "foo" property
    }

- there are associated values with the same label but conflicting types::

    enum Foo {
      case init(foo: Int, bar: Int)
      case init(foo: String, bas: Int)

      // No 'foo' property, because of conflicting associated values
    }

- if the associated value has no label::

    enum Foo {
      case init(_: Int)

      // No property for the associated value
    }

  An associated value could be unlabeled but still provide an internal argument
  name to name its property::

    enum Foo {
      case init(_ x: Int)
      case init(_ y: String)

      // var x: Int?
      // var y: String?
    }

Naming Conventions for Enum Cases
=================================

To normalize enums and bring them into the "grand unified theory" of type
interfaces shared by other Swift types, I think we should encourage the
following conventions:

- Cases with associated values should be declared as ``case init``
  initializers with labeled associated values.
- Simple cases without associated values should be named like properties,
  using ``lowercaseCamelCase``. We should also import Cocoa ``NS_ENUM``
  and ``NS_OPTIONS`` constants using ``lowercaseCamelCase``.

This is a big change from the status quo, including the Cocoa tradition for
C enum constants, but I think it's the right thing to do. Cocoa uses
the ``NSEnumNameCaseName`` convention largely because enum constants are
not namespaced in Objective-C. When Cocoa associates constants with
class types, it uses its normal method naming conventions, as in
``UIColor.redColor``.  In Swift's standard library, type constants for structs
follow the same convention, for example ``Int.max`` and ``Int.min``. The
literal keywords ``true``, ``false``, and ``nil`` are arguably enum-case-like
and also lowercased. Simple enum cases are essentially static constant
properties of their type, so they should follow the same conventions.

