What if you could wrap the existing switch statement in a closure and return a value from that closure like so
Let value = { switch (other) { Case .Some(let value): Return value // because this is in a closure the closure will return the value not the function this is in Case .None: Return "hello" }} Sent from my iPhone > On 29 Dec 2015, at 07:53, Howard Lovatt via swift-evolution > <swift-evolution@swift.org> wrote: > > You can replace the proposed statement `which` (another thread), the existing > statement `?:` (this thread), and the global function `??` (which is an odd > ball) with matching library methods. > > A library method is likely slower than a built in at this stage until the > optimiser improves, but a library function: > > Is documented right in the IDE including code completion, statements aren’t > (you don’t see quick help for `for`!) > Having a library function allows the use case to be throughly investigated. > Is worth while as a language statement? What exact features are useful? EG > should `which` support pattern matching, general boolean expressions, or > simply be `Equatable` as shown below? > It is simpler to implement, maintain, and change a library function that a > built-in. > There is no need for a keyword. > > First `which`: > > // Alternative to introducing `which` statement > > final > class Which<I: Equatable, R> { > private > var result: R? > > private > let which: I > > init(_ which: I) { > self.which = which > } > > func match(value: I, @noescape matchResult: () throws -> R) rethrows -> > Self { > if self.result == nil && self.which == value { > self.result = try matchResult() > } > return self > } > > func matchDefault(@noescape defaultResult: () throws -> R) rethrows -> R { > switch self.result { > case .None: > return try defaultResult() > case .Some(let value): > return value > } > } > } > > > // Demo > enum Color { > case Red, Blue, Green > } > > // Which with a default value > let i1 = Which(Color.Red) // i = 16711680 > .match(.Red) { 0xFF0000 } > .match(.Green) { 0x00FF00 } > .match(.Blue) { 0x00000FF } > .matchDefault { 0 } > > // Which that throws an error if it defaults > let i2: Int! = Which(Color.Green) // i = 16711680 > .match(.Red) { 0xFF0000 } > .match(.Green) { 0x00FF00 } > .match(.Blue) { 0x00000FF } > .matchDefault { nil } // Cant type call to fatalError as no return, > hence nil and type Int! (note !) > > Note runtime check for default rather than static check via compiler, not as > good but not a big deal most of the time. The vast majority of languages > don't do a compiler check on `switch`. > > Similarly the `?:` statement can be replaced: > > // Replacement for `?:` operator > > struct IfFalse<R> { > private > let result: R? > > func ifFalse(@noescape falseResult: () throws -> R) rethrows -> R { > switch self.result { > case .None: > return try falseResult() > case .Some(let value): > return value > } > } > } > > extension Bool { > func ifTrue<R>(@noescape trueResult: () throws -> R) rethrows -> > IfFalse<R> { > switch self { > case true: > return IfFalse(result: try trueResult()) > case false: > return IfFalse(result: nil) > } > } > } > > > // Demo > let sB = true.ifTrue{"True"}.ifFalse{"False"} // "True" - for some reason > needs {} and not () thinks () form throws > > Whilst the `??` operator is already a library function it is difficult to see > in an expression, it gets buried, and is inconsistent in style because it is > a non-mathematical operator and a symbol rather than a keyword or keyword > followed by a symbol. The space either side of the `??` operator also makes > it look like both arguments are of equal importance, whereas it is the left > hand side that is important and the right hand side is just a catch. > > // Replacement for `??` operator > > extension Optional { > func ifNil(@noescape nilResult: () throws -> Wrapped) rethrows -> Wrapped > { > switch self { > case .None: > return try nilResult() > case .Some(let value): > return value > } > } > } > > > // Demo > let o: String? = nil > let sO = o.ifNil{"Nil"} // "Nil" - for some reason needs {} and not () thinks > () form throws > > > Sent from my iPad > >> On 29 Dec 2015, at 4:00 AM, Thorsten Seitz via swift-evolution >> <swift-evolution@swift.org> wrote: >> >> No exhaustiveness checking is a serious deficiency :-( >> >> -Thorsten >> >>> Am 17.12.2015 um 08:09 schrieb Brent Royal-Gordon via swift-evolution >>> <swift-evolution@swift.org>: >>> >>> Actually, this *almost* does what you want. No @autoclosure for the values >>> and no exhaustiveness checking, but otherwise... >> _______________________________________________ >> 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
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution