> I have found only one usage of Enum.reduce_while in Elixir's codebase.
This is because under the hood Enum.reduce_while is a call `Enumerable.reduce/3`, so we are invoking this functions direcly. On Tue, 21 Dec 2021 00:47:44 +0100 Stefan Chrobot <ste...@chrobot.io> wrote: > Thanks, that version would work, but agreed - not sure how big of an > improvement that would be over Enum.reduce_while. Trying to think > about this in a more imperative style, it seems that maybe an > equivalent of break is what I'm after? Maybe something close to > Ecto's Repo.transaction semantics? > > for foo <- foos do > case barify(foo) do > {:ok, bar} -> bar > {:error, reason} -> break(reason) > end > end > > I think this would have to work similarly to how Ecto's transactions > work with Multis, that is return {:ok, bars} or {:error, reason, > data_so_far}. > > I have found only one usage of Enum.reduce_while in Elixir's codebase. > Interestingly, the shape of the return value is always the same - a > list of finished tests. > https://github.com/elixir-lang/elixir/blob/main/lib/ex_unit/lib/ex_unit/runner.ex#L340 > > This seems like a separate problem, but maybe something to keep in > mind. > > Best, > Stefan > > > wt., 21 gru 2021 o 00:21 Ben Wilson <benwilson...@gmail.com> > napisał(a): > > > To revisit the example situation from the original post: > > > > ``` > > {sections, _acc} = > > for let {section_counter, lesson_counter} = {1, 1}, section <- > > sections do lesson_counter = if section["reset_lesson_position"], > > do: 1, else: lesson_counter > > {lessons, lesson_counter} = for let lesson_counter, lesson <- > > section["lessons"] do > > {Map.put(lesson, "position", lesson_counter), lesson_counter + 1} > > end > > section = > > section > > |> Map.put("lessons", lessons) > > |> Map.put("position", section_counter) > > > > {section, {section_counter + 1, lesson_counter}} > > end > > ``` > > > > I think that's nice! It focuses on inputs and outputs and reduces > > the overall line noise. > > > > On Monday, December 20, 2021 at 5:28:29 PM UTC-5 José Valim wrote: > > > >> Stefan, this would work if we include all extensions: > >> > >> for reduce {status, acc} = {:ok, []}, status == :ok, foo <- foos do > >> case barify(foo) do > >> {:ok, bar} -> {:ok, [bar | acc]} > >> > >> {:error, _reason} = error -> error > >> end > >> end > >> > >> I am not sure if you find it any better. It is hard to do this > >> with "let" because you don't want to include the element of when > >> it fails. > >> > >> On Mon, Dec 20, 2021 at 9:23 PM Stefan Chrobot <ste...@chrobot.io> > >> wrote: > >>> I went through some of our code and one thing I'd love to see is > >>> a way to replace Enum.reduce_while with the for comprehension. So > >>> the code like this: > >>> > >>> Enum.reduce_while(foos, {:ok, []}, fn foo, {:ok, bars} -> > >>> case barify(foo) do > >>> {:ok, bar} -> {:cont, {:ok, [bar | bars]}} > >>> {:error, _reason} = error -> {:halt, error} > >>> end > >>> end) > >>> > >>> Would the following even work? > >>> > >>> for reduce(result = {:ok, []}), foo <- foos, {:ok, _} <- result do > >>> case barify(foo) do > >>> {:ok, bar} -> {{:ok, [bar | bars]}} > >>> {:error, _reason} = error -> {error} > >>> end > >>> end > >>> > >>> Even if it did, it's not doing a great job of communicating the > >>> intent and still potentially requires a Enum.reverse call. The > >>> intent here is "early exit with some value upon some condition or > >>> pattern mismatch". > >>> > >>> > >>> Best, > >>> Stefan > >>> > >>> pon., 20 gru 2021 o 21:06 Stefan Chrobot <ste...@chrobot.io> > >>> napisał(a): > >>>> I really like this proposal! For me it strikes the perfect > >>>> balance between terseness and explicitness that I've come to > >>>> enjoy in Elixir. > >>>> > >>>> My votes: > >>>> - Naming: let over given; just because it's shorter, > >>>> - Do use parents: let "feels" similar to var!. > >>>> > >>>> Best, > >>>> Stefan > >>>> > >>>> pon., 20 gru 2021 o 19:54 José Valim <jose....@dashbit.co> > >>>> napisał(a): > >>>>> Good point. I forgot to mention the :reduce option will be > >>>>> deprecated in the long term. > >>>>> > >>>>> On Mon, Dec 20, 2021 at 7:53 PM 'eksperimental' via > >>>>> elixir-lang-core < elixir-l...@googlegroups.com> wrote: > >>>>> > >>>>>> The proposal is very concise, > >>>>>> the only thing that would be problematic is the use of > >>>>>> `reduce` for two > >>>>>> different things, > >>>>>> > >>>>>> for <<x <- "AbCabCABc">>, x in ?a..?z, reduce: %{} do > >>>>>> acc -> Map.update(acc, <<x>>, 1, & &1 + 1) > >>>>>> end > >>>>>> > >>>>>> {sum, count} = > >>>>>> for reduce({sum, count} = {0, 0}), i <- [1, 2, 3] do > >>>>>> sum = sum + i > >>>>>> count = count + 1 > >>>>>> {sum, count} > >>>>>> end > >>>>>> > >>>>>> It would lead to misunderstanding as it may not be clear which > >>>>>> one we are talking about when we say "use for reduce" > >>>>>> > >>>>>> > >>>>>> On Mon, 20 Dec 2021 19:11:54 +0100 > >>>>>> José Valim <jose....@dashbit.co> wrote: > >>>>>> > >>>>>> > Hi everyone, > >>>>>> > > >>>>>> > This is the second proposal for-let. You can find it in a > >>>>>> > gist: > >>>>>> > https://gist.github.com/josevalim/fe6b0bcc728539a5adf9b2821bd4a0f5 > >>>>>> > > >>>>>> > Please use the mailing list for comments and further > >>>>>> > discussion. Thanks for all the feedback so far! > >>>>>> > > >>>>>> > >>>>>> -- > >>>>>> 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/61c0d119.1c69fb81.af520.c181SMTPIN_ADDED_MISSING%40gmr-mx.google.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. > >>>>> To view this discussion on the web visit > >>>>> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4LOyoAmXULJQo%2BYX4eFVJZJAoYtKHytoHujCS_kJ6AEuA%40mail.gmail.com > >>>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4LOyoAmXULJQo%2BYX4eFVJZJAoYtKHytoHujCS_kJ6AEuA%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/CACzMe7aXBL1jNM_aWmJJzYOjrK%3Dtf-4%2BLPLJLpccu_G4zr0cAg%40mail.gmail.com > >>> <https://groups.google.com/d/msgid/elixir-lang-core/CACzMe7aXBL1jNM_aWmJJzYOjrK%3Dtf-4%2BLPLJLpccu_G4zr0cAg%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-core+unsubscr...@googlegroups.com. > > To view this discussion on the web visit > > https://groups.google.com/d/msgid/elixir-lang-core/c1fea9e2-f47c-4236-812a-431bc7d76d62n%40googlegroups.com > > <https://groups.google.com/d/msgid/elixir-lang-core/c1fea9e2-f47c-4236-812a-431bc7d76d62n%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/61c11d62.1c69fb81.e1016.4de4SMTPIN_ADDED_MISSING%40gmr-mx.google.com.