Skip to content

Instantly share code, notes, and snippets.

@AfricanSwift
Last active October 28, 2019 17:49
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AfricanSwift/bfeab7d930785ed5096939ce24bd6cbf to your computer and use it in GitHub Desktop.
Save AfricanSwift/bfeab7d930785ed5096939ce24bd6cbf to your computer and use it in GitHub Desktop.
Evolution Proposal: Default values for enum associated values

Default values for enum associated values

  • Proposal: SE-XXXX
  • Author: African Swift
  • Status: Draft
  • Review manager:

Introduction

Support default values for enum associated values.

Motivation

Swift like many other languages allows specification of more than one function with the same name in the same scope; allowing us to implement different function semantics for flexible specification.


Let's say we start off with an example: *Create a Person with two parameters:*
  • firstname
  • surname
func createPerson(firstname: String, surname: String) -> Person { }

... then down the line, we are asked to add an additional parameter for the person's age. To support this we create a new function with the same name, same parameters, except that we now add the new age parameter.

func createPerson(firstname: String, surname: String, age: Int) -> Person { }

The traditional approach (duplicate function names) achieves flexible specification, but does so at the expense of some boilerplate.


An alternative approach to flexible specification is to create **Parameter Objects**. ####For example: ```swift struct PersonParameter { let firstname: String let surname: String let age: Int?

init(firstname: String, surname: String, age: Int? = nil) { self.firstname = firstname self.surname = surname self.age = age } }

func createPerson(_ person: PersonParameter) -> Person { }

 > *Parameter objects while providing the greatest degree of flexibility, does so at the expense of heft; both in definition and in use.*


<br>
Swift also provides a third option: **Default Parameters**, which similar to the previous options, also accommodates flexible specification, whilst maintaining backward compatibility, 

Again we start out with a function to create a Person with two parameters `firstname` and `surname`: 
```swift
func createPerson(firstname: String, surname: String) -> Person { }

... then again down the line, when we need an additional parameter (for example: a person's age ), we can adding it with a default value; by doing this ensures that all the places where this function was already used will work fine, and so too any new places where the age parameter is required.

func createPerson(firstname: String, surname: String, age: Int? = nil) -> Person { }
  • Default parameters is certainly the simplest option; providing a balance between versatility and flexibility, suitable to most use cases.*

Proposed solution

Swift enum cases with associated values are quite similar to function parameters, except that currently flexible specification with enum associated values, is only possible by using Parameter Objects.

The proposed solution is to enhance Swift enum associated values to support default values in a functionally equivalent way to default parameters on functions.

Detailed design

Similar to the earlier function examples, we define a person case with associated values for firstname and surname:

enum ... { 
   case person(firstname: String, surname: String) 
}

... then as we did for the function, we now have to modify the case specification to support a person's age, but unlike functions, we are only left with imperfect choices:

  • break the API
  • or, create a new case.

Ideally it should be possible to assign defaults to *enum associated values*, with a functionally equivalent outcome, for example: ```swift enum ... { case person(firstname: String, surname: String, age: Int? = nil) } ``` ... In this way we would similarly be able to ensure that all the places where the *associated value case* was used would continue to work fine, and so too any new places where the `age` *Associated Value* is required.

Impact on existing code

This proposal is considered additive, so no impact is envisaged.

Alternatives considered

Do nothing

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