[swift-evolution] ternary operator ?: suggestion

Charles Constant charles at charlesism.com
Tue Dec 29 08:54:46 CST 2015


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 at swift.org> wrote:

>
>
> Sent from my iPad
>
> On Dec 29, 2015, at 7:28 AM, Craig Cruden via swift-evolution <
> swift-evolution at 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 at 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 at 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 at 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 at 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>  _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> 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/20151229/66277494/attachment.html>


More information about the swift-evolution mailing list