Qqwy
TypeCheck Core Team
In the topic about Monads, at some point the discussion moved more towards Enumeration:
So I’ll move over the relevant posts, and then we can continue the discussion here
.
Trending in Discussions
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
New
The obligatory hello world thread!
Who are you and where are you from? :stuck_out_tongue:
New
I want to open this thread for you all to discuss and help those who really like Ash but are still hesitant to use it in a real project. ...
New
We’re evaluating API mocking tools for OpenAPI-based projects and would love to hear what other teams are using.
We’re particularly inte...
New
Is there a word for the ~> symbol used in Version strings?
Do you also just call it a Squiggle Arrow™ ?!
New
I’m posting this in response to Jose’s recent tweet (Cr. link) :
People are sleeping on Elixir for a coding harness:
Hot-code swappi...
New
AcmeScript — Writing JS hooks as if I were still using Elixir
I’ve been having fun building a little something over the last few days: Ac...
New
Other Trending Topics
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
There are three potential reasons for members of this forum to have a look at https://vutuv.de
You are tired or annoyed of LinkedIn.
Yo...
New
Aludel - LLM Evaluation Workbench
Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixir-ls
- #ai
- #elixirconf-us
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 6- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Qqwy
As for:
Enumdoes not (contrary to what intuition might suggest) implement the Functor (fun_landsource code) pattern. ThusEnum.mapis not a 'true map` because indeed it (and all functions that are based on it) always returns a list rather than ‘a container with transformed contents but with the same containing structure’.Instead of on
map,Enumis built on the concept ofreduceReducable(fun_landsource code) or, in Haskell parlance, Foldable is a an interface that is implementable for a larger group of datatypes than Mappable, because things like sets and numerical ranges can be reduced but not mapped (since then it would be possible to end up with two values with the same value, which goes against the invariant of a set).So why do you care about Functor-style ‘true’
map? BecauseEnum.mapand similar functions throw away the structure of the container. If you have a (rose) tree, good luck on iterating it usingEnum.mapand in the end attempting to regain the same tree structure as before.I have the feeling (please correct me if I’m wrong, @josevalim) that the current approach of
Enum.mapbeing built on top ofreducewas to be able to use iteration functions with these other data types, and that this choice might’ve been influenced by Ruby, which takes the same approach.josevalim
Those results show you are very likely benchmarking without consolidated protocols. Given how maps work, I would expect your implementation to be slower because the only possible way to efficiently traverse a large map and return a map is by doing conversion to a list, traversing and then going from a list to a map. So by definition your solution has to be slower.
This is not related to Ruby at all. I just said this in another thread but the things that are related mostly belong to the syntax.
You explained why we preferred foldable quite well:
We use foldable because it allows us to support the widest variety of data types, while being efficient and also supporting resources and laziness. Remember that Enum supports resources, so a functor wouldn’t work for most streams either (io, file, stage, etc). You also wouldn’t be able to call a map and return anything that is not a tuple, etc.
EDIT: Introducing reducees « Plataformatec Blog - this article explains how the protocol works with the widest variety of data types as possible. And that was the goal, to have a single protocol instead of multiple ones. There is still space for a functor/traverse but given that even map operations require you to first convert to a list and then back, it does not add much beyond to what we have today.
Qqwy
Just want to make a quick remark on this:
:maps.map/2is the Functor mapping function for maps. The reasoning is as follows: Since maps cannot contain duplicate keys, the structure would be changed if a mapping operation would also allow altering the keys. Thus, the return value of the function passed to map/2 is the value that is used for the current key at all times.Related to this is the Extractable library I wrote a couple of months back, which allows you to enumerate collections in a one-item-per-time fashion, because that is of course one of the things that is impossible using the current Enumerable (You cannot stop in the middle using because of potential resource cleanup that has not yet happened while in
:suspended-mode, as well as the rest of the collection possibly being in a non-standard format. Using:haltdiscards the tail of the collection however, so you cannot use that either.)Why want one-at-a-time? Because not all operations lend themselves to the giving control to the collection paradigm.
Indeed, currently Erlang does not allow you to simply extract a single
{K, V}-pair from a map (hopefully it will be added at some time in the future, there were discussions about it a while back IIRC), and therefore the map needs to be converted into a list and back again each time.Thank you for sharing that blog post here! Very clear explanation of why
.
Enum(erable)is the way it is todayjosevalim
And maps:map2 converts to a list and then converts it back to a map, which goes back to my earlier point of it all being done on lists anyway: otp/lib/stdlib/src/maps.erl at master · erlang/otp · GitHub
BIFs do not accept anonymous function as argument and I don’t believe there is a plan to lift this restriction. So it is probably staying like this for now.
Does it work with resources? Because it was one of the first approaches that we tried but very error prone when it comes to dangling resources.
Qqwy
It does not; that is, resource management is something that needs to be done manually. I’ll edit my earlier post to clarify this further.
I’d love to talk more about this – I also started working on a proof-of-concept iterator library called iter.
However, I think we are veering too far off topic now; since we’re not talking about Monads anymore. I’ll open a new topic
.
EDIT: Done! We’re in the new topic now.
OvermindDL1
I’m doing the same as that is the only erlang api for traversing a map to fold over it, just handling it all internally and hidden from the user.
But yes, they are consolidated.
Here is the bench file (I could easily be doing something wrong, please tell!):
And the results:
The reason mine is faster I’m pretty sure is because of the module call overhead and guards that elixir’s current style uses and exclusively because of that, not because of any algorithmic cost differences.
Here is the definition of the Monad type:
Here is my
Monad’s implementation for lists and maps (and also included is the :ok/:error tuples as an example of those):And I can show the generated output code too if curious?
True true!
I actually quite like how C++ does it. Not really proper categorical setup but highly useful while being descriptive about ‘how’ it can be used too.
Yep, that is definitely want you want for a Foldable!
Yeah that is hard to do perfectly efficiently the way maps are encoded currently.
Indeed! Folding is definitely not flat_mapping, hence why they are different categories. ^.^
That is why
foldis one of the root-bases in the Categorical Type tree (Monad technically inherits from it and others optionally to delegate to fold and flatten to implement flat_map automatically).Hmm, yeah I’ve never seen that done, it makes sense though that it would not call back into the runtime as BIF’s are supposed to be *fast*fast*fast*!
Actually Categorical Types has this covered too, there is a basic 1-type reducer, and there is a basic 2-type reducer, up to N-type reducers.
Most systems only implement up to 2 because with 2 you can reduce over 2 at a time to reduce to a list of lists until you get a final list of all lists to pass to the final reducing function as a list of an element at a time of each sub list.
Ah cool.