Proposal: Replace ?? by an (optional) argument to ?


(Amir Michail) #1

Examples:

* instead of x ?? false, you would have x?(false)
* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty

I think this change would result in cleaner looking code.


(Austin Zheng) #2

In addition to the conflict in meaning, the original proposal won't work as-is because only operators can start with a '?'. An 'ifNil' function taking an autoclosure argument would be expressible within the language grammar without requiring special-case exceptions.

That being said, my opinion is that changes that break existing code should come with commensurate benefit (as with the C for loop discussion). I don't think one exists, although if someone wants to make an argument in favor of it I would be happy to reconsider.

WRT to ?? not being well-known, given that the concept it deals with (non-optional fallback expression to an expression of optional type) is not really expressible in most mainstream languages, I would consider it okay.

Austin

···

On Jan 25, 2016, at 6:52 PM, Rob Mayoff via swift-evolution <swift-evolution@swift.org> wrote:

`x?(false)` already has a meaning. If `x` is of type `Optional<(Bool) -> ()>`, then `x?(false)` means “if x is None, do nothing; if x is Some(f), call f(false)”.

I don't think the end is "the most important position", and I don't think the default value is necessarily "the least important part of the expression".

I like the existing ?? operator more than this idea.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Nate Birkholz) #3

-1

?? Is compact and expressive and useful quite often. It's clear and simple and clearly related to similar symbols. When writing objective-c code I often find myself wishing for ?? as it often is more useful than the ternary operator.

···

Sent from my iPhone, please excuse brevity and errors

On Jan 25, 2016, at 6:03 PM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Examples:

* instead of x ?? false, you would have x?(false)
* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty

I think this change would result in cleaner looking code.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Erica Sadun) #4

Not loving this. I'm quite happy with ??-coalescing and don't see
a compelling reason it needs to be "cleaner". I find your suggested
enhancement less readable. Looks like an optional chaining across
a function.

-- E

···

On Jan 25, 2016, at 7:03 PM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Examples:

* instead of x ?? false, you would have x?(false)
* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty

I think this change would result in cleaner looking code.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Rob Mayoff) #5

`x?(false)` already has a meaning. If `x` is of type `Optional<(Bool) ->
()>`, then `x?(false)` means “if x is None, do nothing; if x is Some(f),
call f(false)”.

I don't think the end is "the most important position", and I don't think
the default value is necessarily "the least important part of the
expression".

I like the existing ?? operator more than this idea.


(Amir Michail) #6

Not loving this. I'm quite happy with ??-coalescing and don't see
a compelling reason it needs to be "cleaner". I find your suggested
enhancement less readable. Looks like an optional chaining across
a function.

?? puts the least important part of the expression in the most important position — namely, the end.

···

On Jan 25, 2016, at 9:28 PM, Erica Sadun <erica@ericasadun.com> wrote:

-- E

On Jan 25, 2016, at 7:03 PM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Examples:

* instead of x ?? false, you would have x?(false)
* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty

I think this change would result in cleaner looking code.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Craig Cruden) #7

I agree - ?? looks better — at least better than the example shown…. the suggested replacement looks messy and is not an improvement (occasional swift coder - as such I am less biased than other Swiftees).

···

On 2016-01-26, at 9:28:50, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

Not loving this. I'm quite happy with ??-coalescing and don't see
a compelling reason it needs to be "cleaner". I find your suggested
enhancement less readable. Looks like an optional chaining across
a function.

-- E

On Jan 25, 2016, at 7:03 PM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Examples:

* instead of x ?? false, you would have x?(false)
* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty

I think this change would result in cleaner looking code.

_______________________________________________
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


(Andrew Bennett) #8

I agree with Rob, also I prefer it without excessive brackets, brackets
tend to get mismatched because you have to go hunting for the start or end
of the expression:

    a ?? b ?? c ? d

versus:

    a?(b?(c?(d))))

I think it makes chaining cleaner and clearer.

Granted the first expression is longer, but this isn't true with styles
that require whitespace inside the brackets. Did you notice that each
expression had a mistake?

···

On Tue, Jan 26, 2016 at 1:52 PM, Rob Mayoff via swift-evolution < swift-evolution@swift.org> wrote:

`x?(false)` already has a meaning. If `x` is of type `Optional<(Bool) ->
()>`, then `x?(false)` means “if x is None, do nothing; if x is Some(f),
call f(false)”.

I don't think the end is "the most important position", and I don't think
the default value is necessarily "the least important part of the
expression".

I like the existing ?? operator more than this idea.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Lily Ballard) #9

This change as proposed is impossible. The syntax `x?(false)` already has a well-defined and necessary meaning, which is optional chaining on function application. By that I mean that if `x` has the type `(Bool) -> Void` then invoking it looks exactly like `x?(false)`. You often see this in code that invokes `optional` delegate methods or optional completion blocks.

Furthermore, I think the ?? operator is already great and does something unique enough to warrant its own syntax.

-Kevin Ballard

···

On Jan 25, 2016, at 6:03 PM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Examples:

* instead of x ?? false, you would have x?(false)
* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty

I think this change would result in cleaner looking code.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Howard Lovatt) #10

I am no fan of the ?? operator since it tends to disappear in an expression, a bit like ?: does, and it fails the test of being well known or well established (see API guidelines). Also it isn't used often, therefore I would suggest a method, ifNil, added to Optional instead:

  x.ifNil(false)

···

On 26 Jan 2016, at 1:32 PM, Craig Cruden via swift-evolution <swift-evolution@swift.org> wrote:

I agree - ?? looks better — at least better than the example shown…. the suggested replacement looks messy and is not an improvement (occasional swift coder - as such I am less biased than other Swiftees).

On 2016-01-26, at 9:28:50, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

Not loving this. I'm quite happy with ??-coalescing and don't see
a compelling reason it needs to be "cleaner". I find your suggested
enhancement less readable. Looks like an optional chaining across
a function.

-- E

On Jan 25, 2016, at 7:03 PM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Examples:

* instead of x ?? false, you would have x?(false)
* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty

I think this change would result in cleaner looking code.

_______________________________________________
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


(Thorsten Seitz) #11

Not loving this. I'm quite happy with ??-coalescing and don't see
a compelling reason it needs to be "cleaner". I find your suggested
enhancement less readable. Looks like an optional chaining across
a function.

?? puts the least important part of the expression in the most important position — namely, the end.

I think that’s actually a very good place as it is the option that is considered last.

-Thorsten

···

Am 26.01.2016 um 03:30 schrieb Amir Michail via swift-evolution <swift-evolution@swift.org>:

On Jan 25, 2016, at 9:28 PM, Erica Sadun <erica@ericasadun.com> wrote:

-- E

On Jan 25, 2016, at 7:03 PM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Examples:

* instead of x ?? false, you would have x?(false)
* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty

I think this change would result in cleaner looking code.

_______________________________________________
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


(Lily Ballard) #12

Correction: `x` has type `((Bool) -> Void)?`.

-Kevin Ballard

···

On Jan 31, 2016, at 5:05 PM, Kevin Ballard via swift-evolution <swift-evolution@swift.org> wrote:

This change as proposed is impossible. The syntax `x?(false)` already has a well-defined and necessary meaning, which is optional chaining on function application. By that I mean that if `x` has the type `(Bool) -> Void` then invoking it looks exactly like `x?(false)`. You often see this in code that invokes `optional` delegate methods or optional completion blocks.

Furthermore, I think the ?? operator is already great and does something unique enough to warrant its own syntax.

-Kevin Ballard

On Jan 25, 2016, at 6:03 PM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Examples:

* instead of x ?? false, you would have x?(false)
* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty

I think this change would result in cleaner looking code.

_______________________________________________
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


(Trent Nadeau) #13

Null/nil coalescing operators are used across several languages (see
https://en.wikipedia.org/wiki/Null_coalescing_operator) The ?? operator in
particular is also used for this purpose in C# and PHP 7.

···

On Mon, Jan 25, 2016 at 9:43 PM, Howard Lovatt via swift-evolution < swift-evolution@swift.org> wrote:

I am no fan of the ?? operator since it tends to disappear in an
expression, a bit like ?: does, and it fails the test of being well known
or well established (see API guidelines). Also it isn't used often,
therefore I would suggest a method, ifNil, added to Optional instead:

  x.ifNil(false)

> On 26 Jan 2016, at 1:32 PM, Craig Cruden via swift-evolution < > swift-evolution@swift.org> wrote:
>
> I agree - ?? looks better — at least better than the example shown…. the
suggested replacement looks messy and is not an improvement (occasional
swift coder - as such I am less biased than other Swiftees).
>
>
>> On 2016-01-26, at 9:28:50, Erica Sadun via swift-evolution < > swift-evolution@swift.org> wrote:
>>
>> Not loving this. I'm quite happy with ??-coalescing and don't see
>> a compelling reason it needs to be "cleaner". I find your suggested
>> enhancement less readable. Looks like an optional chaining across
>> a function.
>>
>> -- E
>>
>>> On Jan 25, 2016, at 7:03 PM, Amir Michail via swift-evolution < > swift-evolution@swift.org> wrote:
>>>
>>> Examples:
>>>
>>> * instead of x ?? false, you would have x?(false)
>>> * instead of x?.isEmpty ?? false, you would have x?(false).isEmpty
>>>
>>> I think this change would result in cleaner looking code.
>>>
>>>
>>> _______________________________________________
>>> 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

--
Trent Nadeau


(Howard Lovatt) #14

Plenty of languages have something along these lines, however the syntax isn't standard and therefore I don't see that ?? is well established. How can it be, if languages all do their own thing? Note: I wasn't proposing eliminating the concept, just suggesting that it isn't worthy of an operator and an operator tends to be invisible in an expression where as a method call isn't.

···

On 26 Jan 2016, at 2:35 PM, Trent Nadeau <tanadeau@gmail.com> wrote:

Null/nil coalescing operators are used across several languages (see https://en.wikipedia.org/wiki/Null_coalescing_operator) The ?? operator in particular is also used for this purpose in C# and PHP 7.

On Mon, Jan 25, 2016 at 9:43 PM, Howard Lovatt via swift-evolution <swift-evolution@swift.org> wrote:
I am no fan of the ?? operator since it tends to disappear in an expression, a bit like ?: does, and it fails the test of being well known or well established (see API guidelines). Also it isn't used often, therefore I would suggest a method, ifNil, added to Optional instead:

  x.ifNil(false)

> On 26 Jan 2016, at 1:32 PM, Craig Cruden via swift-evolution <swift-evolution@swift.org> wrote:
>
> I agree - ?? looks better — at least better than the example shown…. the suggested replacement looks messy and is not an improvement (occasional swift coder - as such I am less biased than other Swiftees).
>
>
>> On 2016-01-26, at 9:28:50, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:
>>
>> Not loving this. I'm quite happy with ??-coalescing and don't see
>> a compelling reason it needs to be "cleaner". I find your suggested
>> enhancement less readable. Looks like an optional chaining across
>> a function.
>>
>> -- E
>>
>>> On Jan 25, 2016, at 7:03 PM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> Examples:
>>>
>>> * instead of x ?? false, you would have x?(false)
>>> * instead of x?.isEmpty ?? false, you would have x?(false).isEmpty
>>>
>>> I think this change would result in cleaner looking code.
>>>
>>>
>>> _______________________________________________
>>> 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

--
Trent Nadeau


(Greg Titus) #15

After thinking about it some more, it’s not really the position that is the problem.

I think the problems with ?? are as follows:

* not specialized to a boolean context (i.e, it is too general for most cases)
* “??" is too catchy for something this minor
* true/false contain too many letters for something this minor

I think you must be writing some (from my point of view) very unusual code indeed if most of the optional types you are dealing with are “Bool?”. If you are only dealing with optional booleans, then certainly, “??” would not be a very helpful construct.

In my experience ?? is most often used to conveniently end/resolve an optional chain with a default value, e.g.:

let x = array.first?.value ?? 0

as opposed to:

let x: Int
if let f = array.first {
  x = f.value
} else {
  x = 0
}

or perhaps:

let x: Int
if array.isEmpty {
  x = 0
} else {
  x = array[0].value
}

Optionals and optional-chaining are not rare (at least in my use of Swift), they are generally not in a boolean context, they are generally not minor, and “??” as an operator name is well suited to ‘resolving’ them with a default value.

It seems to me that if your list of items here is really your problem with “??”, then it seems as though you aren’t really using the operator as intended.

  - Greg

···

On Jan 30, 2016, at 9:27 AM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

I would like to type something like this:

if x?.isEmpty || nil { … }
if x?.isNotEmpty && !nil { … }

So one might consider turning “|| nil” into a suffix, say |nil.
Similarly, one might consider turning “&& !nil” into a suffix, say &!nil.

So maybe:

if x?.isEmpty |nil { … }
if x?.isNotEmpty &!nil { … }

-Thorsten

-- E

On Jan 25, 2016, at 7:03 PM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Examples:

* instead of x ?? false, you would have x?(false)
* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty

I think this change would result in cleaner looking code.

_______________________________________________
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


(Amir Michail) #16

Not loving this. I'm quite happy with ??-coalescing and don't see
a compelling reason it needs to be "cleaner". I find your suggested
enhancement less readable. Looks like an optional chaining across
a function.

?? puts the least important part of the expression in the most important position — namely, the end.

I think that’s actually a very good place as it is the option that is considered last.

After thinking about it some more, it’s not really the position that is the problem.

I think the problems with ?? are as follows:

* not specialized to a boolean context (i.e, it is too general for most cases)
* “??" is too catchy for something this minor
* true/false contain too many letters for something this minor

I would like to type something like this:

if x?.isEmpty || nil { … }
if x?.isNotEmpty && !nil { … }

So one might consider turning “|| nil” into a suffix, say |nil.
Similarly, one might consider turning “&& !nil” into a suffix, say &!nil.

So maybe:

if x?.isEmpty |nil { … }
if x?.isNotEmpty &!nil { … }

···

On Jan 30, 2016, at 11:31 AM, Thorsten Seitz <tseitz42@icloud.com> wrote:

Am 26.01.2016 um 03:30 schrieb Amir Michail via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

On Jan 25, 2016, at 9:28 PM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

-Thorsten

-- E

On Jan 25, 2016, at 7:03 PM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Examples:

* instead of x ?? false, you would have x?(false)
* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty

I think this change would result in cleaner looking code.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Ilya Belenkiy) #17

I also think that the existing syntax is perfect. The fact that it's about
optionals and not Boolean values is the whole purpose of the operator, and
it feels very natural.

···

On Sat, Jan 30, 2016 at 12:28 PM Amir Michail via swift-evolution < swift-evolution@swift.org> wrote:

On Jan 30, 2016, at 11:31 AM, Thorsten Seitz <tseitz42@icloud.com> wrote:

Am 26.01.2016 um 03:30 schrieb Amir Michail via swift-evolution < > swift-evolution@swift.org>:

On Jan 25, 2016, at 9:28 PM, Erica Sadun <erica@ericasadun.com> wrote:

Not loving this. I'm quite happy with ??-coalescing and don't see
a compelling reason it needs to be "cleaner". I find your suggested
enhancement less readable. Looks like an optional chaining across
a function.

?? puts the least important part of the expression in the most important
position — namely, the end.

I think that’s actually a very good place as it is the option that is
considered last.

After thinking about it some more, it’s not really the position that is
the problem.

I think the problems with ?? are as follows:

* not specialized to a boolean context (i.e, it is too general for most
cases)
* “??" is too catchy for something this minor
* true/false contain too many letters for something this minor

I would like to type something like this:

if x?.isEmpty || nil { … }
if x?.isNotEmpty && !nil { … }

So one might consider turning “|| nil” into a suffix, say |nil.
Similarly, one might consider turning “&& !nil” into a suffix, say &!nil.

So maybe:

if x?.isEmpty |nil { … }
if x?.isNotEmpty &!nil { … }

-Thorsten

-- E

On Jan 25, 2016, at 7:03 PM, Amir Michail via swift-evolution < > swift-evolution@swift.org> wrote:

Examples:

* instead of x ?? false, you would have x?(false)
* instead of x?.isEmpty ?? false, you would have x?(false).isEmpty

I think this change would result in cleaner looking code.

_______________________________________________
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


(Thorsten Seitz) #18

Why should ?? be specialized to a boolean context? There are lots of cases where you might want to use a default value for a missing optional, e.g.

label.text = document.name ?? "Unnamed document"

As your use case seems to be making "isEmpty" return true on missing optionals you can easily define the following

extension Optional {
    var isEmpty: Bool {
        return self == nil || isEmpty
    }
}

if x.isEmpty { ... } // x is an optional

-Thorsten

-Thorsten

···

Am 30.01.2016 um 18:27 schrieb Amir Michail <a.michail@me.com>:

not specialized to a boolean context (i.e, it is too general for most cases)


(Amir Michail) #19

not specialized to a boolean context (i.e, it is too general for most cases)

Why should ?? be specialized to a boolean context? There are lots of cases where you might want to use a default value for a missing optional, e.g.

?? can stay as is and something else could be specialized to a boolean context.

···

On Jan 31, 2016, at 4:03 AM, Thorsten Seitz <tseitz42@icloud.com> wrote:

Am 30.01.2016 um 18:27 schrieb Amir Michail <a.michail@me.com>:

label.text = document.name ?? "Unnamed document"

As your use case seems to be making "isEmpty" return true on missing optionals you can easily define the following

extension Optional {
   var isEmpty: Bool {
       return self == nil || isEmpty
   }
}

if x.isEmpty { ... } // x is an optional

-Thorsten

-Thorsten