SE-0199: Adding toggle method to Bool

Hi Swift Community,

The review of SE-0199 “Adding toggle method to Bool begins now and runs through February 19th, 2018.

Reviews are an important part of the Swift evolution process. All reviews should be made in this thread on the Swift forums or, if you would like to keep your feedback private, directly in email to me as the review manager.

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available on the Swift Evolution website.

As always, thank you for participating in Swift Evolution.

Ben Cohen
Review Manager

3 Likes

Quick bit of additional review manager guidance: during the pitch, there was some discussion of other enhancements to be made to Swift's boolean handling. If you have an idea for a proposal related to Bool that is not an alternative/point against this proposal, we encourage you to raise them as a new thread in the pitches category of the evolution forum.

Note that replacing logic operators such as ! or && with functions or keywords are on the commonly rejected proposals list.

Thanks!
Ben

3 Likes

My evaluation of the proposal is that it's a sensible addition that addresses a real deficiency in method chaining. It fits well with the feel and direction of Swift, as justified in the proposal text. The name is fitting and one that found the most acceptance in the community. I followed the previous discussion in depth and read this proposal in all its stages.

8 Likes

What he said. +1.

+1 as well.

As I've said before in the original discussion, I would vote mildly against.

I think this is easy enough to add to your own code and rare enough that it doesn't stand the test of being "significant enough to warrant a change to Swift". Unless there is a fundamental movement towards making more of the language fundamentally functional, this is imo an outlier case that does not fit in the current direction of Swift.

That said, I wouldn't be devastated if the proposal was accepted and Bool expanded to include it. It's handy. I just don't think it's that handy.

11 Likes

I echo what @Erica_Sadun says. I don't think it's super useful, but it's not harmful.

!!( -1. I do not think this passes the test for something that needs to live in the standard library. I do not think the name is a slam dunk as most people tend to believe. To me the name does not tell me that this mutating. I can't think of a better name than not for this.

Is the problem being addressed significant enough to warrant a change to Swift?

No but I can see how It may be helpful.

Does this proposal fit well with the feel and direction of Swift?

No. The code needed to support this in a project is so minimal, plus people can then call the method something that matches their liking (like "flip", "invert"). I am not saying that this piece of code is not awesome but baking "toggle" to the standard library is not something I want.
It reminds me a lot of the ?= optional assignment operator. Something useful but it has not place in the standard library at this time.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

n/a

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Read the previous thread.
)

1 Like

I don't think of this as a positive; if it's truly broadly useful (i.e., for chaining), then it would be very annoying for readers of code if every project had a distinct name for this. In the standard library, we do vend mutating and nonmutating versions of functions where both are useful, even when the name is controversial (e.g., formUnion).

A distinction from the optional assignment operator is that toggle enables much more concise use sites in the form of method chaining, whereas that proposed operator offered no practical benefit comparable to that.

5 Likes

+1 for the proposal, same arguments as @xwu.

(I followed the discussion thread.)

Not a huge fan, echoing what @Erica_Sadun said. If it were to be accepted however, I would suggest invert() as the spelling.

3 Likes

Mildly against. I think Erica put it best. I also wouldn’t mind if it were added.

I'm trying to parse "making more of the language fundamentally functional". Do you mean functional as in functionality or functional programming?

I wouldn't say this is functional programming (it embraces mutation, rather than avoiding it).

If you meant that it's bad to add more functionality to the standard library, I don't understand the objection (unless you think it's unnecessary functionality, in which case: point taken).

4 Likes

I’m against this proposal. The arguments for this proposal would also align with a proposal for adding the ++ operator back. They are both more terse and allow you to write a long dot-notation variable only once. In my coding practices, I personally haven’t encountered many situations where I want to arbitrarily toggle a Boolean. I am typically setting it equal to some form of a logical expression. Maybe it is just me, but I also feel like this functionality could lead to some bad programming practices for beginners. To make this proposal more acceptable, it would help to have some anecdotal evidence of how this is useful more than just when using a long dot-notation. To me, that reason alone does not justify adding it to Swift.

1 Like

+1 for the proposal. I also agree with @xwu on this one.

I followed the previous discussion thread.

Some feedback in support of the proposal that was sent to me off-list. Posting here with their permission. Replying to @zzt4 since it provides a use case:

I often reach for toggle when toggling something stored in a data structure to avoid the redundant subscript and better handle optionals.

Given a simple model type for a to-do list task:

struct Task {
   var id: Int
   var body: String
   var isCompleted: Bool
}

and a dictionary of tasks by ID:

var tasksById: [Int:Task]

If you want the optional-chaining no-op on nil behavior:

// without `toggle`
let handler1: (Int) -> Void = { id in
   if let value = self.tasksById[id]?.isCompleted {
       self.tasksById[id]?.isCompleted = !value
   }
}

Combining toggle with optional chaining is a big improvement:

// with `toggle`
let handler2: (Int) -> Void = { id in
   self.tasksById[id]?.isCompleted.toggle()
}

If you want trapping behavior on nil, it’s cleaner:

// trapping alternative without `toggle`
let handler3: (Int) -> Void = { id in
   self.tasksById[id]!.isCompleted = !self.tasksById[id]!.isCompleted
}

But still improved by toggle:

// trapping alternative with `toggle`
let handler4: (Int) -> Void = { id in
    self.tasksById[id]!.isCompleted.toggle()
}
14 Likes

+1 from me.

It's mildly useful, but it's also the sort of thing that tends to end up in just about everyone's personal set of standard library extensions, so it might as well be in the standard library.

6 Likes

+1 as xwu and davedelong.

There are a couple of differences with operators like ++:

  • toggle is more descriptive, as it isn't a custom operator (and is discoverable through today's autocomplete)
  • the code samples above (e.g. in combination with optional chaining or nested properties) show how there is a clear expressive difference (whereas x.y.z += 1 isn't much longer than x.y.z++). In a way, toggle is closer to += than it is to ++.
  • there isn't a return value as ++ had, which caused code that had subtle/confusing behavior.
  • there aren't prefix and postfix variants like ++ and -- have.

edit: here's a list of disadvantages of ++ and friends, I think the proposal holds up well.

12 Likes

+1 for the proposal, it really improves handling of optionals, specifically with optional chaining use case