I'm with Matthew/Craig. We discussed a couple very ternary-like versions earlier in the thread, which I increasingly think are the best options.
The major objection to this came from Lattner, and his objection, if I have it right, is "this proposal doesn't add enough functionality to justify the additional complexity/confusion" The sticking point, at the moment, is formulating a really persuasive argument for "why we need this." If we can't do that, this proposal is dead. On Tue, Dec 29, 2015 at 5:38 AM, Matthew Johnson via swift-evolution < swift-evolution@swift.org> wrote: > > > Sent from my iPad > > On Dec 29, 2015, at 7:28 AM, Craig Cruden via swift-evolution < > swift-evolution@swift.org> wrote: > > That looks pretty ugly. > > I think the best we can hope for at this point is maybe another keyword > that mirrors switch but is expression based (aka match) — leaving the > ternary ? : expression as is - which is not all that bad since any if else > that becomes a compound expression or more than two resultant values > (chaining) quickly becomes a mess. > > > I agree that this is probably the best path forward at the moment. There > was a post early on showing a ternary-like switch expression. I don't > remember whether there were any specific problems with that idea or not, > but if there aren't that might best route forward. > > > I am not sure that even a “match” expression would be accepted at this > point because there seems to be general resistance to anything more than > the existing paradigm with a few functional decorations — and the way of > doing things is good enough. > > Concurrency is also currently off the table at this point -- the fact that > immutable pure functional code can theoretically be parsed into a > dependance graph which would allow for out of order [within scope] parallel > execution on different threads [not sure if the overhead of doing so would > outweigh the benefits]…. would also not be of sufficient benefit. > > The primary focus of Swift is a language for UI development, not server > development…. > > > On 2015-12-29, at 15:07:57, James Campbell via swift-evolution < > swift-evolution@swift.org> wrote: > > 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: > > > 1. Is documented right in the IDE including code completion, > statements aren’t (you don’t see quick help for `for`!) > 2. 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? > 3. It is simpler to implement, maintain, and change a library function > that a built-in. > 4. 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 > > > _______________________________________________ > 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