[swift-evolution] mandatory "?" suffix for identifiers associated with optional types

Per Melin p at greendale.se
Mon Dec 7 15:58:50 CST 2015

On Mon, Dec 7, 2015 at 8:32 PM, Kevin Ballard <kevin at sb.org> wrote:

> On Mon, Dec 7, 2015, at 03:48 AM, Per Melin wrote:
> Here is one type of mistake that I made long after that I should have
> known better:
> [snip]
> If you find yourself in danger of forgetting that a value is optional, you
> can always adopt a naming convention that makes it apparent. That would
> have the same effect as requiring a postfix-? on optional identifiers,
> except that it's voluntary.

That would have helped not at all in the example you snipped. But let's not
get hung up on that, I'd rather establish how useful it is to have <, <=, >
and >= cover optional values.

> Personally, I find the ability to compare optionals to be very valuable,
> almost as valuable as the ability to use == with optionals (which I doubt
> anyone will argue is a misfeature).
> I have been trying to come up with situations where you would want to
> compare two values, knowing that one or both may be nil, with <, <=, > or
> >=. Other than as for sorting, I can't think of much. I doubt the Swift
> team explicitly made this possible without good reason, so I must be
> missing something.
> Could you please share some examples? It doesn't necessarily have to be
> code, just explain the context where this is valuable.
> Sorting is a common one. Another example is just cases where I need to
> compare two numbers and at least one number may have been generated by an
> optional process. For example:

>     if optAry?.count > 3 {

Instead of:

    if let count = optAry?.count where count > 3 {

Which is twice as long, which of course is inconvenient if you do this a
lot, and you don't need the unwrapped value again. A distinct comparison
operator for optional values could solve that.

>  This can work with non-numeric values too, though usually if I'm
> comparing non-numeric values with < then I'm doing some variant on sorting,
> which we've already addressed. For example, from my current codebase I find
> let sortedJSON = responsesJSON.sort { a, b in
>     let a_name = a["name"] as? String
>     let b_name = b["name"] as? String
>     return a_name?.lowercaseString < b_name?.lowercaseString
> }

Instead of:

  let sortedJSON = responsesJSON.sort { a, b in
      let a_name = a["name"] as? String ?? ""
      let b_name = b["name"] as? String ?? ""
      return a_name.lowercaseString < b_name.lowercaseString


Which I think anyone can accept (except that I find ?? to be an eyesore,
but that is a different topic.)

Please note that I'm absolutely not arguing for the suggestion that started
this thread. I just want to understand if it really is necessary to
overload all the comparison operators for (T?, T?) in the first place.

 (although were I to rewrite this code I'd switch to using
> caseInsensitiveCompare() as lowercaseString is needlessly allocating a new
> string, but it demonstrates the idea)
> I know somewhere in another project I used < with optionals to great
> effect for a non-sorting purpose, but I don't remember where to find it
> anymore.
> In general, my feeling here is that supporting == and < on optionals is
> just a specific case of a generally desired property that is Equatable and
> Comparable should be supported on all types that are simple wrappers around
> existing Equatable/Comparable types. I know this isn't well-defined, but I
> mean that since Optional is really just taking the set of values for a type
> and adding one additional value, if the type is Comparable/Equatable,
> there's an obvious way to define this new inhabiting value as being
> Comparable/Equatable with the type, and so it should be done. Similarly, I
> think that if I have a tuple (T, U) where both T and U are
> Comparable/Equatable, the tuple itself should be (where the Comparable
> implementation compares the T value first, and if it's equal then compares
> the U value). And any larger tuple where every component element is
> Comparable/Equatable should also be Comparable/Equatable. I should also be
> able to opt-in to this kind of automatic Comparable/Equatable generation
> for structs. I should also be able to get this on other enums where only
> one enum variant has associated values, and the associated values are
> comparable/equatable (i.e. a generalization of Optional).
> -Kevin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151207/06f7e079/attachment.html>

More information about the swift-evolution mailing list