keep_zen
For a functor, map(map(functor, fun), fun2) equal as map(functor, fun2*fun).
In Elixir, I think Enum module is a functor, but |> did not optimize it.
Like this:
defmodule A do
def add1(e) do
IO.puts("+1")
e+1
end
def sub1(e) do
IO.puts("-1")
e-1
end
end
1..10
|> Enum.map(&A.add1/1)
|>Enum.map(&A.sub1/1)
The console outputs like:
+1
+1
+1
...
-1
-1
-1
...
-1
If the code have optimzed it should show as:
+1
-1
+1
-1
...
Redefine |>, I think I can do the optimation for Enum.maps. If there is functors’ list, optimize for all functors’ chains,can also be done. I meaning, It not hard to do. But Why it is not happend in Elixir?
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
Hello,
I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
Hi everyone,
I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding.
I sta...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New
Other Trending Topics
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #elixirconf-eu
- #metaprogramming
- #hex










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
dorgan
Enum is not a functor, it always goes from enumerable to lists. It’s also a set of eager funcions, the funcional composition you assume is not used here nor is it common in Elixir.
If you want to consider it a functor, you need to apply its properties yourself, Elixir won’t do it for you. But know that functors as a concept dont exist in elixir the way they exist in Haskell or Ocaml.
I also have to note that the Pipe operator just pipes function calls like the unix Pipe does, it’s not a functional composition operator.
LostKobrakai
You could use
Stream.map, which will apply the mapping functions lazily.keep_zen
Yes, I assume Pipe operator like functional composition operator, can optimaze the
Enum.map, until today.There is so many
Enum.mapchains in my codes, I should optimaze them manualy.LostKobrakai
I’d strongly suggest actually running benchmarks. Just because you can inline things doesn’t mean that the results will be more performant.
keep_zen
I did a test. The chians length is 2 about 30%~40% speed up.
But not test for more long chians.
BartOtten
Try this before anything else as it might save you a lot of rewriting.
There is a small penalty to be paid for using Stream but when you chains take some time that might be negligible; depending on what is the limiting factor.
al2o3cr
Nitpick: your
add1andsub1functions are not functors as they have side-effects - callingputs.keep_zen
Yes. They are not pure functions. If there is no side effect,we do not know if the functions composed together.
keep_zen
The test result is wrong, If remove the IO lines, there is no speed up.
So, this is the why.
krstfk
There’s a lot of confusion here.
Functors (and the likes) are an abstraction that helps to reason about some compositions, they’re not magic.
So what is a functor (in programming):
It’s a data structure, with a (f)map function that has the following properties :
That’s it those are the rules of a functor.
So, is a list, under Enum.map a functor? No. Because, elixir/erlang/ocaml/scala… allow for side effects.
Namely, if you were to write:
Now let’s try this :
So plainly, list under map is not a functor, unless you ignore the side effects. But if you guarantee that
fandgare side effects free, list under map is a functor.Now, nowhere in the functor laws is it specified that one side of the equation should be favoured over the other side.
What you’re talking about is something called
fusion, oroperations fusionorshortcut fusionorstream fusion. These have little to do with functors (at most, functor laws may allow you to prove that these optimisations are safe), and they are not ‘not hard’. Take a look at the map implementation for list in Haskell, look at the rewriting rules. Also, note that those optimisations don’t apply for all instances of functor (check fmap for Maybe).Operations fusions, come with some sort of trade off, and if you have long chains of operations, maybe use Stream.map instead of Enum.map, but I don’t know, benchmark (more on that later). (BTW ops fusion are not that common).
Regarding the pipe operator (
|>) vs functional composition, the main difference is wether you read left to right or right to left (at least in strict languages). Ocaml doesn’t have an infix composition operator either. Again, this is orthogonal to compiler optimisations. But, you may implement it trivially:It’s not that different from the pipe operator (except you read it in the other direction, and it’s a bit more fiddly with anonymous functions):
TLDR; : don’t worry about functional abstractions, you probably don’t need them. Learn the standard library. Then learn OTP abstraction.
( Final note : optimisation
In general we have good frameworks for getting a sense of software complexity. However, for mere mortals, the only way to actually optimise for one’s use case is benchmarking. Put another way constant factors may be extremely important regardless of O)