This is what I found:

>From the original PR: https://github.com/elixir-lang/elixir/pull/6634 (this 
has a lengthy discussion on the merits).

The original discussion about including 
both: https://groups.google.com/g/elixir-lang-core/c/LlZCz0iYgfc/m/5XLRvg8XAgAJ 
(not very detailed, discussion happened in PR it seems).

A discussion from one before 
that: https://groups.google.com/g/elixir-lang-core/c/WtKXtP0XFqc/m/73gSelgJBgAJ 
(there was disagreement about the best data structure for the actual use 
case)

That's all I found.

Best regards,
Oliver

On Wednesday, March 20, 2024 at 11:40:15 AM UTC+1 José Valim wrote:

> Can you please provide a link to the previous discussions? I recall 
> dealing with some complexities around finding and not finding elements as 
> well. Thanks!
>
> On Wed, Mar 20, 2024 at 11:37 AM 'oliver....@googlemail.com' via 
> elixir-lang-core <elixir-l...@googlegroups.com> wrote:
>
>> Hello, okay I checked.
>>
>> Well, there was a discussion 7 years ago when Access.filter/1 was 
>> introduced but Access.find/1 was not.
>>
>> Maybe opinions might have changed since then?
>>
>> When going into the PR from back then I find the reasoning not very 
>> strong on not merging Access.find/1 because "it could be expressed by a 
>> more strictly defined Access.filter/1". 
>>
>> I don't find that to be true. It has pretty much has the same use cases 
>> as Enum.find/2 when used with get_in/2, for example. 
>>
>> Writing a very convoluted filter predicate to catch only the first 
>> occurrence when you really need to do that - we basically found that to be 
>> very unelegant. I really tried to cram our use case into the 
>> Access.filter/1 approach and it was not good.
>>
>> An added benefit is that we do not walk the rest of the list - once an 
>> element is found, the tail is just appended in updates. It has therefore a 
>> slightly better performance for its specific use case over Access.filter/1. 
>> You also don't get a list you have to Access.all after. I mean, it's 
>> basically like Enum.find/2 instead of Enum.filter/2.
>>
>> Btw, our use case was as follows:
>>
>> We have a data structure representing a testcase to be run. Later on we 
>> want to verify some counter updates done in that TC. We reuse the data 
>> structure describing the TC. For this particular requirement regarding the 
>> counter updates only the first occurrence of a particular procedure will 
>> behave different. It has no other criteria it is different or can be told 
>> apart by, so we just update the first occurrence for this check with a flag 
>> for easier post-processing of the counter data. This flag has no relevance 
>> to other parts of our testing system, and if TC authors add it manually, 
>> they might forget. We simply use internally Access.find/1 to specifically 
>> pick that one.
>>
>> When you have very clear, distinct criteria like in a DB row update (like 
>> there's only one "Jane Smith" with ID 42) then there would be no be 
>> advantage over Access.filter/1. So it's situational, but in the situations 
>> it's useful it's hard to express otherwise. For example once you 
>> Access.filter/1 you can no longer do something like Access.at/1 because it 
>> directly moves you into the elements.
>>
>> Sorry for the long post, but I hope it conveys the rationale.
>>
>> Best regards, 
>> Oliver
>>
>>
>>
>>
>> On Wednesday, March 20, 2024 at 10:07:33 AM UTC+1 an.le...@gmail.com 
>> wrote:
>>
>>> Right now I’m a bit drowning in work but IIRC there already was a 
>>> proposal for this, has anyone searched the mailing list?
>>>
>>> On Wed, Mar 20, 2024, at 12:17 AM, Jean Klingler wrote:
>>>
>>> I like it. It would be to `Access.filter` what `Enum.find` is to 
>>> `Enum.filter`.
>>> I think it would be a nice addition as it can express operations that 
>>> would be quite verbose otherwise.
>>>
>>> Le mer. 20 mars 2024 à 02:30, 'oliver....@googlemail.com' via 
>>> elixir-lang-core <elixir-l...@googlegroups.com> a écrit :
>>>
>>> Hi.
>>>
>>> I already made a PR but was redirected here. ;-)
>>>
>>> This new function Access.find/1 would basically work like Enum.find/2 
>>> but for get_in/2 and similar functions.
>>>
>>> It can be used for scenarios like:
>>> - Popping the first found element.
>>> - Updating only the first found match in a list.
>>> - To get_in/2 an element directly instead of piping from get_in/2 into 
>>> Enum.find/2.
>>>
>>> The implementation is very similar to Access.filter/1 and Access.at/1.
>>>
>>> We added this functions as utility function in our own project because 
>>> we couldn't really find an elegant way to do such pointed updates with the 
>>> existing functions.
>>>
>>> These are the examples I would have included in the doc string:
>>>
>>>       iex> list = [%{name: "john", salary: 10}, %{name: "francine", 
>>> salary: 30}]
>>>       iex> get_in(list, [Access.find(&(&1.salary > 20)), :name])
>>>       "francine"
>>>
>>>       iex>  get_and_update_in(list, [Access.find(&(&1.salary <= 40)), 
>>> :name], fn prev ->
>>>       ...> {prev, String.upcase(prev)}
>>>       ...>  end)
>>>       {"john", [%{name: "JOHN", salary: 10}, %{name: "francine", salary: 
>>> 30}]}
>>>
>>>       iex> list = [%{name: "john", salary: 10}, %{name: "francine", 
>>> salary: 30}]
>>>       iex> pop_in(list, [Access.find(&(&1.salary <= 40))])
>>>       {%{name: "john", salary: 10}, [%{name: "francine", salary: 30}]}
>>>
>>>       iex> list = [%{name: "john", salary: 10}, %{name: "francine", 
>>> salary: 30}]
>>>       iex> get_in(list, [Access.find(&(&1.salary >= 50)), :name])
>>>       nil
>>>
>>>       iex> get_and_update_in(list, [Access.find(&(&1.salary >= 50)), 
>>> :name], fn prev ->
>>>       ...>   {prev, String.upcase(prev)}
>>>       ...> end)
>>>       {nil, [%{name: "john", salary: 10}, %{name: "francine", salary: 
>>> 30}]}
>>>
>>> Thanks,
>>> Oliver
>>>
>>>
>>> -- 
>>> 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/44ed5beb-1730-46d7-931a-217825cc4432n%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/elixir-lang-core/44ed5beb-1730-46d7-931a-217825cc4432n%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/CANnyoha%2BwMRpTy_H2%3Dwy8sWjSQgXPpY-cbaL65Tx7D_AK7o1GA%40mail.gmail.com
>>>  
>>> <https://groups.google.com/d/msgid/elixir-lang-core/CANnyoha%2BwMRpTy_H2%3Dwy8sWjSQgXPpY-cbaL65Tx7D_AK7o1GA%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/61e2ada8-1ba6-4945-9013-2cec1d1cf457n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/elixir-lang-core/61e2ada8-1ba6-4945-9013-2cec1d1cf457n%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-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/05347e87-a2ff-41b2-81a1-b30fc423adcbn%40googlegroups.com.

Reply via email to