if you type "for comprehension" on Google, this is the first result: https://elixir-lang.org/getting-started/comprehensions.html which doesn't report those options
Usually I check the API docs too, but I also assume that the information content is more or less equivalent to the Getting Started section Il giorno venerdì 15 gennaio 2021 alle 09:54:42 UTC+1 José Valim ha scritto: > Maybe you are reading an outdated version of the docs? > > Here is latest: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#for/1 > > On Fri, Jan 15, 2021 at 9:47 AM Luca Campobasso <[email protected]> > wrote: > >> That's much better, Qqwy, thanks. This is a much more explicative answer >> :) >> >> I cannot see however this: "It allows you to pass the extra options >> `:reduce`, `:into` and/or `:uniq` to abstract away common transformations >> of the result." >> Is it true? I cannot see it in the docs. There is only the "into" option. >> >> Il giorno mercoledì 13 gennaio 2021 alle 14:30:40 UTC+1 [email protected] >> ha scritto: >> >>> I think my last message may have been too short, not explaining my >>> reasoning well enough. >>> >>> The main concern I have is that if you have a very flexible function >>> whose set of internal operations depends on its arguments, >>> it is no longer immediately obvious (i.e. obvious from only looking at >>> the code where it is used) what the particular order of these operations >>> will be. >>> >>> For instance: >>> >>> ``` >>> Enum.operation_by(names, :count, &String.downcase/1, &filter_fun/1) >>> ``` >>> >>> When is `String.downcase` run here, and what impact will it have on the >>> result? >>> >>> If one were to write a longer pipeline with more, simpler, steps, then >>> it becomes easier to read and comprehend. >>> >>> For instance, we might have either >>> >>> ``` >>> names >>> |> Enum.filter(&filter_fun/1) >>> |> Enum.map(&String.downcase/1) >>> |> Enum.count() >>> ``` >>> >>> or >>> >>> ``` >>> names >>> |> Enum.map(&String.downcase/1) >>> |> Enum.filter(&filter_fun/1) >>> |> Enum.count() >>> ``` >>> >>> in each case resolving the ambiguity. >>> >>> Of course, we're leaving some runtime efficiency on the table by having >>> multiple smaller steps. >>> >>> When this really becomes a problem, we can replace a particular pipeline >>> with `for`: >>> >>> `for` is a much higher-level abstraction than doing manual recursion, >>> because: >>> >>> - It has its own generator syntax to filter on a pattern match. >>> - Besides being also able to filter by functions. >>> - It allows you to pass the extra options `:reduce`, `:into` and/or >>> `:uniq` to abstract away common transformations of the result. >>> >>> Such a for-loop might be slightly harder to read than a pipeline of >>> simple steps, >>> but it will be more performant because no intermediate enumerables are >>> constructed any more. >>> And it will still be clear in which order the steps are performed. >>> >>> Example: >>> >>> ``` >>> for name <- names, >>> filter_fun.(String.downcase(name)), >>> reduce: 0 do >>> acc -> acc + 1 >>> end >>> ``` >>> >>> So this is why I am not currently convinced that this proposal is a good >>> idea. >>> >>> To summarize: In most cases the clarity of having more simpler steps in >>> a pipeline is preferable, >>> and in the cases where performance really does become critical, we >>> already have `for`. >>> >>> I hope that contextualizes my earlier reply a little :-) >>> >>> ~Qqwy/Marten >>> On Tuesday, January 12, 2021 at 11:20:52 PM UTC+1 [email protected] >>> wrote: >>> >>>> Well I didn't cook up a proposal, just had an idea and thought I could >>>> write, at this moment I have nothing as a concrete proposal written in >>>> code. >>>> Looking through the API, I thought it could be applied to, for example, >>>> map, zip, reduce, sum, take, into, shuffle, scan, basically anything that >>>> goes through a list. >>>> >>>> Il giorno martedì 12 gennaio 2021 alle 23:14:40 UTC+1 José Valim ha >>>> scritto: >>>> >>>>> >>>>> >>>>>> While I understand that there's no `Enum.filter` written explicitly >>>>>> in the code, there's still this step of sort of filtering out, written >>>>>> one >>>>>> way or the other, which at high level looks like filtering e.g. the >>>>>> simplest example is this: >>>>>> ``` >>>>>> def count(enumerable, fun) do >>>>>> reduce(enumerable, 0, fn entry, acc -> >>>>>> if(fun.(entry), do: acc + 1, else: acc) >>>>>> end) >>>>>> end >>>>>> ``` >>>>>> >>>>> >>>>> Can you please tell me which functions you believe this pattern could >>>>> be applied at? You mentioned count and filter and other _by functions, >>>>> but >>>>> I am still struggling to see how it applies to max_by, dedup_by, >>>>> chunk_by, >>>>> etc. >>>>> >>>>> Otherwise, it is best to revisit it once there is a more concrete >>>>> proposal (even if not efficient at first). >>>>> >>>>> -- >> 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 [email protected]. >> > To view this discussion on the web visit >> https://groups.google.com/d/msgid/elixir-lang-core/c3357aae-6d97-4480-89a4-b39787528af9n%40googlegroups.com >> >> <https://groups.google.com/d/msgid/elixir-lang-core/c3357aae-6d97-4480-89a4-b39787528af9n%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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/deeab50c-b357-4f14-9070-f39b5cb212e8n%40googlegroups.com.
