Set.prototype.toggle

# Cyril Auburtin (6 years ago)

It would help to avoid this scenario:

if (cond) {
  set.add(x);
} else {
  set.delete(x);
}
// set.toggle(x, cond);

It's similar to Element's classList

# Cyril Auburtin (6 years ago)

extending Set is possible

class SetWithToggle extends Set {
  toggle(value, force = !this.has(value)) {
    if (force) {
      this.add(value);
    } else {
      this.delete(value);
    }
    return this;
  }
}

2017-10-28 17:15 GMT+02:00 Cyril Auburtin <cyril.auburtin at gmail.com>:

# dante federici (6 years ago)

What's the case for toggle other than nice to have? In general, I find toggle actions to be implicitly dependent on existing state -- that is, anywhere you have toggle you can just as easily say add(value) or delete(value).

# Naveen Chawla (6 years ago)

"Nice to have" is good a case as any, since it applies for all features that were ever introduced, and all that ever will be.

I'm just curious in what cases this is useful?

I'm only asking because I expect a set to represent a single condition for entry/presence in the set e.g. "People", "Dogs", etc. I'm curious under what circumstances the condition for entry/presence changes, that would necessitate a "toggle"? And if that condition changes, then wouldn't that apply across the set, necessitating a transformation to a filtered derived set, not just for a single element? Basically, I'm interested to know, in what circumstances are you trying to do this?

# Cyril Auburtin (6 years ago)

My use-case was a choice-list form, with React. I used a Set to store the current selected values in state.

It's updated with checkbox 'change' event, and depending on .checked, you delete or add (so .toggle).

When you have several of those choice-lists, it becomes even more helpful. You can also have to manipulate the set after, for example set.toggle('A', set.has('A-') && set.has('A+')) (adding A in the set if it contains A- and A+, removing it else)

I've just seen this facebook/immutable-js#610 similar topic.

Last argument for it, Set.prototype.delete returns the number of deleted item, Set.prototype.add the amended set, this inconsistency is annoying when combining them

2017-10-29 10:25 GMT+01:00 Naveen Chawla <naveen.chwl at gmail.com>:

# Jordan Harband (6 years ago)

Set.prototype.delete returns a boolean indicating whether a deletion was done.

I think the minor convenience of "toggle" (avoiding an if statement, or a ternary, in a single use case) isn't worth the complexity and confusion of having an API with a boolean argument - which is something that there's zero precedent in the language for, even if the ecosystem has it, and something that I suspect would block any progress on such an API.

# dante federici (6 years ago)

I guess a better way to phrase my argument is:

What situation are you in where you don't know the current state?

That is, consider the following:

if (enabled) {
  set render state to "enabled", set action to "delete"
} else {
  set render state to "disabled", set action to "add"
}

versus:

set action to "toggle"
if (enabled) {
  set render state to "enabled"
} else {
  set render state to "disabled"
}

What I'm trying to say is that "toggle" is ambiguous without checking the current state. Adding a set toggle method only serves to allow "drift" -- where you have a state assumption of "enabled" but the set is actually disabled, or vice versa. Set should be explicit -- this doesn't mean you need to litter your code with guards, but instead the state of an application using a set should know if it needs to remove or add, and the use of a "toggle" implies the state of the set is ambiguous. Either way. I don't think the UI checkbox use case is compelling enough to add to the prototype for Set.

# Andrea Giammarchi (6 years ago)

having an API with a boolean argument - which is something that there's

zero precedent in the language

not sure about strictly JS but classList, which is a Set of strings, has a classList.toggle(name, true) which does the same.

although I agree this is a not so needed method so it's probably not worth to have a precedent in the JS side

# Isiah Meadows (6 years ago)

And for these general kinds of uses, I've almost always found booleans better and easier than anything else - negation is literally toggling. classList.toggle is probably the only exception I regularly run into.