[swift-evolution] Idea: Properties in Failable Initializers less verbose

Chris Lattner clattner at nondot.org
Wed Jul 26 15:01:32 CDT 2017


> On Jul 26, 2017, at 9:55 AM, Robert Bennett <rltbennett at icloud.com> wrote:
> 
> Is there a reason that a throwing unwrap function/operator isn’t part of the standard library? Seems like it would be handy to be able to have a one-liner for attempting to unwrap and throw if it’s nil.

?! would be the wrong name, since ! is generally reserved for potentially-trapping operations that should be avoided in most cases.

If you’re going to explore this branch of the design tree, the sensible thing seems to be to (conceptually) carve off some chunk of the operator space for throwing operators (e.g. ^ which could be rationalized as connoting “raising” an error).  This would argue for postfix ^ to unwrap-or-throw (as an analog to postfix ?, enabling chaining etc), and would then provide a schema to define other “or throw” operations.

-Chris
 


> Something like
> 
> 
> postfix operator .?!
> 
> extension Optional {
> 	static postfix func .?!(optional: Optional<Wrapped>) throws -> Wrapped {
> 		switch optional {
> 		case let .some(wrapped):
> 			return wrapped
> 		case .none:
> 			throw UnwrapError()
> 		}
> 	}
> }
> 
> init?(data: [String: Any]) {
> 	do {
> 		self.someProperty = try data["some_key”].?!
> 		self.anotherProperty = try data["another_key”].?!
> 	} catch is UnwrapError {
> 		return nil
> 	}
> }
> 
> 
>> On Jul 26, 2017, at 12:13 PM, Chris Lattner via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> 
>>> On Jul 25, 2017, at 2:44 AM, philohan95 via swift-evolution <swift-evolution at swift.org> wrote:
>>> 
>>> I think the current way to initiate models in a Failable Initializer `init?()` is overly verbose and should be shortened down so less boilerplate should be needed.
>>> 
>>> The current way:
>>> 
>>> ```
>>> let someProperty: Any
>>> let anotherProperty: Any
>>> 
>>> init?(data: [String: Any]) {
>>> 	guard
>>> 		let someProperty = data["some_key"],
>>> 		let anotherProperty = data["another_key"]
>>> 	else {
>>> 		return nil
>>> 	}
>>> 
>>> 	self. someProperty = someProperty
>>> 	self. anotherProperty = anotherProperty
>>> }
>>> ```
>> 
>> Guard isn’t really the right answer for this, I’d try something like this (where unwrapOrThrow is the obvious generic function you can define yourself):
>> 
>> init?(data: [String: Any]) {
>> 	do {
>> 		self.someProperty = try unwrapOrThrow(data["some_key”])
>> 		self.anotherProperty = try unwrapOrThrow(data["another_key”])
>> 	} catch {
>> 		return nil
>> 	}
>> }
>> 
>> -Chris
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 



More information about the swift-evolution mailing list