[Proposal] Add Enum.none?/2

194 views
Skip to first unread message

Zvonimir Rudinski

unread,
Jun 18, 2022, 7:35:58 AM6/18/22
to elixir-lang-core

Seeing Enum.all?/2 being available made me assume there was also an Enum.none?/2 (like in Ruby), and I was a bit suprised to learn there was no such thing.
I'm aware that I could just do !Enum.all?/2, but Enum.none?/2 sees much nicer to me.

One more argument that I could make is that !Enum.all?/1 == Enum.none?/1 is not true in all cases.
Example:
If we have [false, true], !Enum.all?/1 will be true, but Enum.none?/1 will be false

I would like your thoughts on this one.

Andrey Yugai

unread,
Jun 18, 2022, 7:41:39 AM6/18/22
to elixir-l...@googlegroups.com
I think negated `Enum.any?` should be equal to `Enum.none?` in all cases. Also do you have an example where `Enum.none?` would be useful?







-------- Original Message --------
--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/0b68e108-825f-49d5-86ec-317caa2a852fn%40googlegroups.com.

Bruce Tate

unread,
Jun 18, 2022, 7:45:28 AM6/18/22
to elixir-l...@googlegroups.com
!Enum.any is what you are looking for. Also, Enum.any? takes an optional function, so Enum.any?(list, &! &1) works, as does Enum.any?(list, fn x -> !x end). 

-bt 

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/0b68e108-825f-49d5-86ec-317caa2a852fn%40googlegroups.com.


--

Regards,
Bruce Tate
CEO

Zvonimir Rudinski

unread,
Jun 18, 2022, 8:29:49 AM6/18/22
to elixir-lang-core
@Andrey yeah that is correct but seeing that Enum.filter and Enum.reject exist I thought that Enum.all? should have a counterpart as well. Not just a negated Enum.any?

Uros Jeknic

unread,
Jun 18, 2022, 1:26:58 PM6/18/22
to elixir-lang-core
I'd like this to be added. Just makes sense to do it. My two cents

Filip Paunkovic

unread,
Jun 18, 2022, 2:40:27 PM6/18/22
to elixir-lang-core
Yeah, I'd like to see this as well. Maybe implement it as a negation of Enum.any?

Adam Lancaster

unread,
Jun 18, 2022, 2:52:36 PM6/18/22
to elixir-l...@googlegroups.com
Personally I think a function like this is easy enough to implement for our own codebases if we need one. I don’t think there is much precedence in other langs for such a function and a core implementation is not likely to be any different from what you would write in your codebase, meaning having it in core is unlikely to save anyone from gotchas or improve the performance of their implementation. 

To me it feels like bloat. 

and given that you can already write:

not Enum.any?(…)

It really doesn’t improve anything much imho. 

Best

Adam

Marijan Sudarevic

unread,
Jun 19, 2022, 7:31:35 PM6/19/22
to elixir-lang-core
I agree with Filip. It can be just an alias for negated Enum.any? 
I don't think it'll be that much of a bloat

Zoran Joka

unread,
Jun 21, 2022, 2:50:36 AM6/21/22
to elixir-lang-core
I would support this. It's handy in Ruby lang.

Vladimir Ilic

unread,
Jun 21, 2022, 2:51:35 AM6/21/22
to elixir-lang-core
i would like to have this too

On Monday, June 20, 2022 at 1:31:35 AM UTC+2 marij...@gmail.com wrote:

Mladen Petkoski

unread,
Jun 21, 2022, 3:01:43 AM6/21/22
to elixir-lang-core
Got my support, i've used something similar in Ruby.

Austin Ziegler

unread,
Jun 22, 2022, 10:50:06 AM6/22/22
to elixir-l...@googlegroups.com
I’ll add my support for an explicit `Enum.none?/2`, even though `!Enum.any?(llst)` or `Enum.any?(list, & !&1)` is equivalent. I haven’t faced this particular problem *in Elixir*, but JavaScript doesn’t have this, and I make the mistake of using `!list.all()` instead of `!list.some()` *every single time* I have to implement it.

It’s a subtle enough difference that I think that the increased readability and reduced error rate are worth the added API space, as simply documenting this particular use case in `Enum.any?/2` would end up begging the question as to why not implement this as a standard function, and leaving it undocumented leads to incorrect implementations.

-a



--

Zach Daniel

unread,
Jun 22, 2022, 11:09:44 AM6/22/22
to elixir-l...@googlegroups.com
I think there is a really important function of a standard library for things like this. This conversation has effectively generated knowledge, specifically that the best way to implement `Enum.none?/2` is simply by negating `Enum.any?/2`. And while it is very easy for anyone to add this code to their project `!Enum.any?/2` what is *not* so easy is knowing that "the best way to implement `Enum.none?/2` is via negating `Enum.any?/2`. We all have that context now, so it is easy to say it shouldn't be in the standard library. I don't think that things only belong in the std library if the std library offers an optimization. Sometimes the important context is that the std library *doesn't* offer an optimization. Personally, I believe things like `Enum.none?/2` belong in the std library.


On Wed, Jun 22, 2022 at 10:49 AM, Austin Ziegler <halos...@gmail.com> wrote:
I’ll add my support for an explicit `Enum.none?/2`, even though `!Enum.any?(llst)` or `Enum.any?(list, & !&1)` is equivalent. I haven’t faced this particular problem *in Elixir*, but JavaScript doesn’t have this, and I make the mistake of using `!list.all()` instead of `!list.some()` *every single time* I have to implement it.

It’s a subtle enough difference that I think that the increased readability and reduced error rate are worth the added API space, as simply documenting this particular use case in `Enum.any?/2` would end up begging the question as to why not implement this as a standard function, and leaving it undocumented leads to incorrect implementations.

-a

To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAJ4ekQtQnsop1Rb4OAL_eF%2BRMHgJR6dXhaxaW0V_URMUw12BRg%40mail.gmail.com.

Kurtis Rainbolt-Greene

unread,
Jun 22, 2022, 1:27:38 PM6/22/22
to elixir-l...@googlegroups.com
While quippy `!Enum.any?` also just doesn't work in some cases:

```
iex(2)> ["a","b","c"] |> !Enum.any?(&String.valid?/1)
** (ArgumentError) cannot pipe ["a", "b", "c"] into !Enum.any?(&String.valid?/1), the :! operator can only take one argument
```

Obviously you can get cute:

```
iex(2)> ["a","b","c"] |> Enum.any?(&String.valid?/1) |> Kernel.!()
false
```

On Wed, Jun 22, 2022 at 8:09 AM Zach Daniel <zachary....@gmail.com> wrote:
I think there is a really important function of a standard library for things like this. This conversation has effectively generated knowledge, specifically that the best way to implement `Enum.none?/2` is simply by negating `Enum.any?/2`. And while it is very easy for anyone to add this code to their project `!Enum.any?/2` what is *not* so easy is knowing that "the best way to implement `Enum.none?/2` is via negating `Enum.any?/2`. We all have that context now, so it is easy to say it shouldn't be in the standard library. I don't think that things only belong in the std library if the std library offers an optimization. Sometimes the important context is that the std library *doesn't* offer an optimization. Personally, I believe things like `Enum.none?/2` belong in the std library.


On Wed, Jun 22, 2022 at 10:49 AM, Austin Ziegler <halos...@gmail.com> wrote:
I’ll add my support for an explicit `Enum.none?/2`, even though `!Enum.any?(llst)` or `Enum.any?(list, & !&1)` is equivalent. I haven’t faced this particular problem *in Elixir*, but JavaScript doesn’t have this, and I make the mistake of using `!list.all()` instead of `!list.some()` *every single time* I have to implement it.

It’s a subtle enough difference that I think that the increased readability and reduced error rate are worth the added API space, as simply documenting this particular use case in `Enum.any?/2` would end up begging the question as to why not implement this as a standard function, and leaving it undocumented leads to incorrect implementations.

-a

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.


--
Kurtis Rainbolt-Greene,
Software Developer & Founder of Difference Engineers

eksperimental

unread,
Jun 22, 2022, 1:50:07 PM6/22/22
to elixir-l...@googlegroups.com
You need to use is like this.

iex(1)> ["a","b","c"] |> Enum.any?(&String.valid?/1) |> Kernel.!()
false
iex(2)> !( ["a","b","c"] |> Enum.any?(&String.valid?/1))
false
> >>>>>>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/0b68e108-825f-49d5-86ec-317caa2a852fn%40googlegroups.com?utm_medium=email&utm_source=footer>
> >>>>>>>>>>> .
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> --
> >>>>>>>>>>
> >>>>>>>>>> Regards,
> >>>>>>>>>> Bruce Tate
> >>>>>>>>>> CEO
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> <https://bowtie.mailbutler.io/tracking/hit/f8218219-d2a8-4de4-9fef-1cdde6e723f6/c7c97460-016e-45fb-a4ab-0a70318c7b97>
> >>>>>>>>>>
> >>>>>>>>>> Groxio, LLC.
> >>>>>>>>>> 512.799.9366 <(512)%20799-9366>
> >>>>>>>>>> br...@grox.io
> >>>>>>>>>> grox.io
> >>>>>>>>>>
> >>>>>>>>> --
> >>>>>>> You received this message because you are subscribed to the
> >>>>>>> Google Groups "elixir-lang-core" group.
> >>>>>>> To unsubscribe from this group and stop receiving emails from
> >>>>>>> it, send an email to elixir-lang-co...@googlegroups.com.
> >>>>>>>
> >>>>>> To view this discussion on the web visit
> >>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/187f642b-209b-4f99-867d-a3c173962b1cn%40googlegroups.com
> >>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/187f642b-209b-4f99-867d-a3c173962b1cn%40googlegroups.com?utm_medium=email&utm_source=footer>
> >>>>>>> .
> >>>>>>>
> >>>>>> --
> >>> You received this message because you are subscribed to the Google
> >>> Groups "elixir-lang-core" group.
> >>> To unsubscribe from this group and stop receiving emails from it,
> >>> send an email to elixir-lang-co...@googlegroups.com.
> >>> To view this discussion on the web visit
> >>> https://groups.google.com/d/msgid/elixir-lang-core/3c24688c-5877-47f0-87c0-e7428345a15en%40googlegroups.com
> >>> <https://groups.google.com/d/msgid/elixir-lang-core/3c24688c-5877-47f0-87c0-e7428345a15en%40googlegroups.com?utm_medium=email&utm_source=footer>
> >>> .
> >>>
> >>
> >>
> >> --
> >> Austin Ziegler • halos...@gmail.comaus...@halostatue.ca
> >> http://www.halostatue.ca/http://twitter.com/halostatue
> >>
> >> --
> >> You received this message because you are subscribed to the Google
> >> Groups "elixir-lang-core" group.
> >> To unsubscribe from this group and stop receiving emails from it,
> >> send an email to elixir-lang-co...@googlegroups.com.
> >> To view this discussion on the web visit
> >> https://groups.google.com/d/msgid/elixir-lang-core/CAJ4ekQtQnsop1Rb4OAL_eF%2BRMHgJR6dXhaxaW0V_URMUw12BRg%40mail.gmail.com
> >> <https://groups.google.com/d/msgid/elixir-lang-core/CAJ4ekQtQnsop1Rb4OAL_eF%2BRMHgJR6dXhaxaW0V_URMUw12BRg%40mail.gmail.com?utm_medium=email&utm_source=footer>
> >> .
> >>
> >
> > --
> > You received this message because you are subscribed to the Google
> > Groups "elixir-lang-core" group.
> > To unsubscribe from this group and stop receiving emails from it,
> > send an email to elixir-lang-co...@googlegroups.com.
> > To view this discussion on the web visit
> > https://groups.google.com/d/msgid/elixir-lang-core/l4pq6nw3.cbf23422-0630-4845-acdc-9c7dde6281e8%40we.are.superhuman.com
> > <https://groups.google.com/d/msgid/elixir-lang-core/l4pq6nw3.cbf23422-0630-4845-acdc-9c7dde6281e8%40we.are.superhuman.com?utm_medium=email&utm_source=footer>
> > .
> >
>
>

Zvonimir Rudinski

unread,
Jun 23, 2022, 5:50:34 PM6/23/22
to elixir-lang-core
Thanks to everyone for the support! I agree with Austin for the JS bit, God only knows how many times I confused !Enum.any/2 with !Enum.all/2.
I expect the opposite of all to be none.
Huge kudos to Kurtis for adding an example where something like Enum.none?/2 would be useful.
I've already forked Elixir and created a branch (I just have to optimize the code a bit), so if Jose decides to re-open the PR it should be ready in no time.
I'll run some benchmarks tomorrow to squeeze as much performance as possible.

Zvonimir Rudinski

unread,
Jun 23, 2022, 6:29:24 PM6/23/22
to elixir-lang-core
The results are in:

TLDR; I was suprised that the initial implementation WAS indeed faster than just negating !Enum.any?

Zvonimir Rudinski

unread,
Jun 23, 2022, 7:02:07 PM6/23/22
to elixir-lang-core
And it uses less memory!
Benchmark shows about 3x less memory usage (tested with small, medium and large list from https://elixirschool.com/en/lessons/misc/benchee), but I forgot to take a screenshot :(
I've also re-tested the speed with small, medium and large list and the results are pretty much the same as in the Imgur URL.

Zach Daniel

unread,
Jun 23, 2022, 9:48:13 PM6/23/22
to elixir-l...@googlegroups.com
not at a computer so i can't test it myself, but I'd be curious to see how implementing it as a negation of the predicate with `Enum.none?/2` instead of a negation of any would perform. Not important, just throwing it out there.

```
def none?(enum, func) do
Enum.all?(enum, fn i -> !func.(i) end)
end
```


Message has been deleted
Message has been deleted

Zvonimir Rudinski

unread,
Jun 26, 2022, 6:51:59 PM6/26/22
to elixir-lang-core
Here are the results: https://imgur.com/xUA9T7Y
Reply all
Reply to author
Forward
0 new messages