# Question: Why is \`toggle\` function not a standard part of Set packages API?

**URL:** <https://discourse.elm-lang.org/t/question-why-is-toggle-function-not-a-standard-part-of-set-packages-api/7255>\
**Category:** Learn\
**Created:** [April 17, 2021, 1:39pm UTC](https://discourse.elm-lang.org/t/question-why-is-toggle-function-not-a-standard-part-of-set-packages-api/7255 "2021-04-17T13:39:51Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Janiczek](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/janiczek/32/4516_2.png) [@Janiczek](https://discourse.elm-lang.org/u/Janiczek)\
**Post date:** [April 17, 2021, 1:39pm UTC](https://discourse.elm-lang.org/t/question-why-is-toggle-function-not-a-standard-part-of-set-packages-api/7255/1 "2021-04-17T13:39:51Z")

</div>

What the title says.

I mainly have this in mind:

```elm
toggle : a -> Set a -> Set a
toggle x xs =
    if Set.member x xs then
        Set.remove x xs

    else
        Set.insert x xs

```

It is frequently useful to me and I’d expect it to be a part of the stdlib, not just `*-extra` packages. Is everybody else modelling stuff (eg. multi-select checkboxes/dropdowns) differently so that you don’t need that kind of function?

---

<div class="post-metadata">

**Author:** ![MartinS](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/martins/32/3137_2.png) [@MartinS](https://discourse.elm-lang.org/u/MartinS)\
**Post date:** [April 17, 2021, 2:00pm UTC](https://discourse.elm-lang.org/t/question-why-is-toggle-function-not-a-standard-part-of-set-packages-api/7255/2 "2021-04-17T14:00:14Z")

</div>

I’ve installed set-extra sometimes in order to have this function. I could see it being a part of elm/core.

---

<div class="post-metadata">

**Author:** ![edkelly303](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/edkelly303/32/1510_2.png) [@edkelly303](https://discourse.elm-lang.org/u/edkelly303)\
**Post date:** [April 17, 2021, 4:13pm UTC](https://discourse.elm-lang.org/t/question-why-is-toggle-function-not-a-standard-part-of-set-packages-api/7255/3 "2021-04-17T16:13:10Z")

</div>

Agreed - I think every time I have used a Set in Elm I have defined this exact function.

---

<div class="post-metadata">

**Author:** ![Sebastian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/sebastian/32/98_2.png) [@Sebastian](https://discourse.elm-lang.org/u/Sebastian)\
**Post date:** [April 17, 2021, 10:40pm UTC](https://discourse.elm-lang.org/t/question-why-is-toggle-function-not-a-standard-part-of-set-packages-api/7255/4 "2021-04-17T22:40:09Z")

</div>

I have similar functions but always with a boolean to indicate if you should add or remove. E.g.

```auto
toggle : a -> Bool -> Set a -> Set a

```

For me the boolean is important to make the function idempotent. I always have my messages carry the desired state e.g. `Toggle True`, (never just `Toggle`). Unsure about the tradeoffs of these two approaches.

---

<div class="post-metadata">

**Author:** ![Janiczek](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/janiczek/32/4516_2.png) [@Janiczek](https://discourse.elm-lang.org/u/Janiczek)\
**Post date:** [April 18, 2021, 11:52am UTC](https://discourse.elm-lang.org/t/question-why-is-toggle-function-not-a-standard-part-of-set-packages-api/7255/5 "2021-04-18T11:52:52Z")

</div>

Hi Sebastian,

ah, interesting. In such cases I just use `SetFoo` and `UnsetFoo` messages (or `AddFoo` and `RemoveFoo`), which I guess is isomorphic to your `ToggleFoo Bool` message, but is two messages instead of one and the two `update` handlers use `Set.insert` and `Set.remove` respectively.

---

<div class="post-metadata">

**Author:** ![norpan](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/norpan/32/548_2.png) [@norpan](https://discourse.elm-lang.org/u/norpan)\
**Post date:** [April 20, 2021, 6:35am UTC](https://discourse.elm-lang.org/t/question-why-is-toggle-function-not-a-standard-part-of-set-packages-api/7255/6 "2021-04-20T06:35:49Z")

</div>

With multi-select I just make the message reflect the desired state, so if a checkbox should be set the message includes `True` and if it should not be set it includes `False`. This also makes the intent of the messages independent of the current state, which is a good thing in my opinion.

---

<div class="post-metadata">

**Author:** ![jessta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/jessta/32/660_2.png) [@jessta](https://discourse.elm-lang.org/u/jessta)\
**Post date:** [April 21, 2021, 12:43am UTC](https://discourse.elm-lang.org/t/question-why-is-toggle-function-not-a-standard-part-of-set-packages-api/7255/7 "2021-04-21T00:43:12Z")

</div>

Yeah, I agree. I think it’s very rare for someone to actually want to `toggle` a value like that.  
ie. “I don’t know/care what the current value of this is just make it the opposite of that”

It’s more common for `toggle` to be used when someone thinks they knows the state of the value and wants to implicitly set it to the other state.

This leads to all kinds of races and other bugs resulting from the assumption of the state being wrong and thus the `toggle` having the opposite of the desired effect.

multi-select checkboxes/dropdowns is a great example of the kind of thing where the event from the user has a specific intention that isn’t to `toggle` but to explicitly add/remove a selection, or enabled/disabled a checkbox.

I think actually wanting to `toggle` is rare enough that having it included in core would just encourage people to create these kinds of bugs.

---

<div class="post-metadata">

**Author:** ![dta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dta/32/1917_2.png) [@dta](https://discourse.elm-lang.org/u/dta)\
**Post date:** [April 24, 2021, 5:00am UTC](https://discourse.elm-lang.org/t/question-why-is-toggle-function-not-a-standard-part-of-set-packages-api/7255/8 "2021-04-24T05:00:24Z")

</div>

On the other hand, setting the value directly, rather than using something like `toggle` is susceptible to the [stale update bug](https://discourse.elm-lang.org/t/preventing-invalid-states-in-update-function/7060).

I’ve thought a lot about how to avoid both of these classes of bugs, and have never come up with a good solution.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [May 4, 2021, 5:00am UTC](https://discourse.elm-lang.org/t/question-why-is-toggle-function-not-a-standard-part-of-set-packages-api/7255/9 "2021-05-04T05:00:38Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
