> > 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@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution