[swift-evolution] [Pitch] Never as a bottom type

Robert Widmann devteam.codafi at gmail.com
Sun May 14 20:01:21 CDT 2017



> 
> But it has its limits, most notably, it cannot be used as an expression
> 
> let dunno: Int = fatalError("what should I put here?") // cannot convert value of type 'Never'
> 

Though our type lattice doesn’t necessarily have a bottom in the way you’re looking for, you can use Never-returning functions to inhabit a combinator that will do this for you.

func undefined<A>() -> A {
	fatalError("")
}

> It makes sense because Never is not a bottom type. If it were, this statement would be absolutely valid.
> 
> Having a bottom type and a value for it has several advantages:
> 
> - More informative error messages with forced unwrap:
> 
> protocol WonkyAPI {
>     func apiCall() -> Int? //this always return an Int, why is it optional?
> }
> 
> func mycode() {
>     let valueFromAPI = apiCall() ?? fatalError("The API used to always return a value, but now it does not!")
>> }
> 
> It sometimes happen that some part of the code uses an optional but in your particular codepath, the optional is always containing a value (for example after an assignment).
> As of today, you can write
> guard let value = value else { fatalError("something terrible happened") }
> for the same effect with a more verbose syntax.
> 
> - Use as a hole/placeholder during development
> During development it is very likely that you will want to write a piece of functionality but be stuck on an intermediate part of the computation. Assume we have an identifier `undefined` of type `Never` which would represent an impossible value as a bottom type. We would ben able to write:
> 
> func transform(point: CGPoint) -> CGPoint {
>     let translation =  Matrix3D(1, 0, 2,
>                                 0, 1, -2,
>                                 0, 0, 1)
>     let rotation: Matrix3D = undefined //what was it? I forgot
>     return (translation * rotation * point.homogenous).toPoint()
> }
> 
> We can debate on the right naming for undefined. Haskell uses 'undefined', Scala uses `???`. `unimplemented`, `impossible`, `void`are all valid contenders.
> 
> - Eliminate type annotations for generic covariant types
> As of today this is not valid 
> 
> struct Person {
>     let name: String
> }
> 
> var maybeSomeone = nil
> maybeSomeone = Person(name: "Doug”)
> 
> Even though it is clear that maybeSomeone is of type Optional<Person>.
> That is because the compiler cannot guess which type the Optional wraps when `maybeSomeone` is declared. But with a bottom type, a naked nil can be mapped to `Optional<Never>` until the type inference figures out from the context what is the type of Optional. If it cannot because no use or no assignment is done, the compiler could emit an “unreachable” warning just like it does for 
> 
> func unreach() {
>     fatalError("stop here")
>     print("not printed”) // warning: will never be executed
> }
> 
> Should I write a proposal?
> 
> André Videla
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170514/241798c1/attachment.html>


More information about the swift-evolution mailing list