Thanks! And if we were to add a Collectable.empty, what would be its
implementation for Scrivener.Page?

*José Valim*
www.plataformatec.com.br
Skype: jv.ptec
Founder and Director of R&D


On Tue, May 21, 2019 at 7:15 PM Benjamin Milde <[email protected]>
wrote:

> Take for example https://github.com/drewolson/scrivener_ecto
>
> With a current version of ecto you can happily do this:
>
> ```
> Repo.all(query) |> Repo.preload(:user)
> Repo.one(query) |> Repo.preload(:user)
> ```
>
> but not this:
>
> ```
> Repo.paginate(query)  |> Repo.preload(:user)
> ```
>
> Given that doing some work on results of db calls is quite common I tend
> to end up with lot's of functions pattern matching if results are
> `%Scrivener.Page{}`, a list or an element. Say you also use
> https://github.com/duffelhq/paginator for infinite scrolling pages you
> might end up with yet another "collection" type struct, which implements
> Enumerable so displaying items in views is super easy, but with no simple
> solution on how to handle preloads or mappings.
>
> I've also tried using `Map.update!(elements, :key_of_items, function)` to
> normalize stuff down to handling lists for those places using pagination,
> but now I'm wrapping a lot of computation in those updates.
>
> It's also not just mapping, but I might also e.g. want to intersperse
> items with separators or zip some additional data into the resultset and
> still not lose the pagination information attached to those entries.
>
> My naive approach was that I can already use Collectable to fill items
> back into lists as well as those pagination structs, but while for list and
> maps it's easy to use `Enum.into([])` or `Enum.into(%{})` it's not as easy
> to get a hold of an empty version of one of those pagination structs.
>
> I'm not super into all the theoretic types in functional programming. I
> think I understand what a functor is, but I'm also not super certain I
> understand what you're pointing at.
>
> Am Dienstag, 21. Mai 2019 18:36:54 UTC+2 schrieb José Valim:
>>
>> > All the pagination libs I know for ecto return structs with additional
>> metadata besides the actual results of the db query. Currently one needs to
>> build around those structs specifically to be able to do preloads or other
>> mapping operations or one would loose the metadata.
>>
>> Can you please provide an example? I am just trying to full understand
>> the problem. :)
>>
>> > Having a `SomeProtocol.empty` protocol we could still use everything
>> provided by Enum (even with it returning a list), but have a way to replace
>> items in the container with the new modified ones
>>
>> Wouldn't a functor be better suited then?
>>
>>
>> *José Valim*
>> www.plataformatec.com.br
>> Skype: jv.ptec
>> Founder and Director of R&D
>>
>>
>> On Tue, May 21, 2019 at 6:34 PM Benjamin Milde <[email protected]>
>> wrote:
>>
>>> All the pagination libs I know for ecto return structs with additional
>>> metadata besides the actual results of the db query. Currently one needs to
>>> build around those structs specifically to be able to do preloads or other
>>> mapping operations or one would loose the metadata. Having a
>>> `SomeProtocol.empty` protocol we could still use everything provided by
>>> Enum (even with it returning a list), but have a way to replace items in
>>> the container with the new modified ones without manually pattern matching
>>> between single results, lists of results or structs returned because one
>>> happens to be using pagination. Monadic collection types basically don't do
>>> it much differently. Extract the subject out of the container, do
>>> computation and replace the old value when done. I'd imagine `Enumerable`
>>> and the potential `SomeProtocol` would solve a lot of usecases, where
>>> people usually ask for Enum to retain the outer collection type.
>>>
>>> Am Dienstag, 21. Mai 2019 18:14:49 UTC+2 schrieb José Valim:
>>>>
>>>> My concern is that Collectable.empty cannot be implemented by all
>>>> structs. For example, what does it mean to call empty() on a IO.stream?
>>>> Perhaps it would make sense as a separate protocol?
>>>>
>>>> Also, can you please expand on how Repo.preload could use
>>>> Scrivener.Page in detail? Thanks!
>>>>
>>>>
>>>> *José Valim*
>>>> www.plataformatec.com.br
>>>> Skype: jv.ptec
>>>> Founder and Director of R&D
>>>>
>>>>
>>>> On Tue, May 21, 2019 at 5:46 PM Benjamin Milde <[email protected]>
>>>> wrote:
>>>>
>>>>> I've had quite often needs for doing some computation (mapping) on
>>>>> ecto result, but having a flexible function similar to `Repo.preload`
>>>>> currently needs a whole bunch of boilerplate in terms of differenciating
>>>>> collections from single items and especially returning the same type
>>>>> afterwards (e.g. keep it a collection or single item). I know that
>>>>> Enumerable and Collectable were split consciously, but it would be great 
>>>>> to
>>>>> have something like `Collectable.empty/1`, so one could do some work using
>>>>> `Enum` functions and in the end do: `Enum.into(changed,
>>>>> Collectable.empty(initial))` and it would empty the collectable and fill 
>>>>> it
>>>>> up again using the changed data. This way the `Repo.preload` could e.g.
>>>>> additionally support custom enumerable and collectable collections as 
>>>>> first
>>>>> argument like e.g. `%Scrivener.Page{}`.
>>>>>
>>>>> --
>>>>> 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/19c24b83-fc2a-4af3-950e-eba7f767db14%40googlegroups.com
>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/19c24b83-fc2a-4af3-950e-eba7f767db14%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>> --
>>> 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/1498525e-30fd-4cde-92a0-4b2e01cdbdf3%40googlegroups.com
>>> <https://groups.google.com/d/msgid/elixir-lang-core/1498525e-30fd-4cde-92a0-4b2e01cdbdf3%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
> 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/5dff9895-1921-4794-89b9-d4ff45578880%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/5dff9895-1921-4794-89b9-d4ff45578880%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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/CAGnRm4Kueg013YTHmg7jS5o94Qb0YbEjOWRNbKuENKgPiMJK0g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to