Fl4m3Ph03n1x
Is it possible to have lazy evaluation on list comprehensions?
Background
I have some code that uses list comprehensions in elixir and performs some long operations. I need this code to be lazily evaluated instead of running immediately (eager evaluation).
Code
Imagine I have a list comprehension like the following:
for a <- long_operation(),
b <- longer_operation() do
a + b
end
Now, here a and b will be eagerly evaluated, so as to return a + b. However, both long_operation() and longer_operation() take a very long time to run (as the name implies) and I will only absolutely run them if I have to.
I want to come up with a solution that allows for my code to be lazily evaluated. Say, for example, to have a data structure or some other construct where I can then call run() to actually do the hard work.
Research
My first idea was to just put everything inside of anonymous functions:
for a <- fn -> long_operation() end,
b <- fn -> longer_operation() end do
a + b
end
This worked as well as you would expect, i.e., it didn’t. The main reason being: “You cannot sum two functions”.
And it makes sense.
My next option is then to have a data-structure hold the values of these computations, and have the list comprehension return said data-structure.
I would then call run() or something similar, and then the operation would be executed.
You can probably think of this as the IO construct in languages like Scala or Haskell (pardon for the poor comparison).
Other people have suggested the use of GenServers to achieve this, but this avenue does not sit well with me for two main reasons:
- I am adding a runtime dependency to a code that should not even know
GenServers exist in the first place. - Also I fail to see how this would help in any way.
Problem
The issue here is that I believe this will force me to implement a mini AST with the instructions of what needs to be executed when I call run(). Not only do I lack the knowledge to do this, It also sounds overkill at first glance.
Surely, Elixir has a way to have expressions being lazily evaluated that I am not aware of.
So this brings me to the question:
- What mechanisms does Elixir use to have lazy evaluation?
- Are there any data-structures/libraries out there that do this? (lazy evaluation)
Please let me know!
Most Liked
LostKobrakai
I don’t want to judge too hard here, but this – like a few prev. topics of yours – seems to come from a place of shoehorning features available in other languages into elixir. Doing things lazily is totally possible, but I don’t see why there would be the need to do so in a for comprehention.
What’s the problem with this?
a = fn -> long_operation() end
b = fn -> longer_operation() end
a.() + b.()
Anonymous functions and Stream, where stream is specifically for enumerables (so not single values) and it also often uses anonymous functions.
msimonborg
FWIW, I think the difference is in how one asks the question:
“How do you implement this feature/concept from X language in Elixir”
vs.
“In X language you can solve this problem with Y feature/concept. How do you solve this problem in Elixir?”
The first question is centered on how to use concepts and solutions in a language that maybe doesn’t natively or easily support it. The second question centers the problem itself and leads to answers that go directly to idiomatic solutions to common problems. The second question will still produce answers about how those original concepts can be used in Elixir if they exist. ![]()
Fl4m3Ph03n1x
I am OK with that, in previous topics I did create some datatypes that implement the Enumerable protocol to a good level of success. It’s mostly a matter how getting the reduce part of the protocol to actually reduce what I want, which is easier said than done.
I am not sure how to reply to this.
On one hand, you are not wrong. I am absolutely exploring concepts from places that are alien to Elixir and playing around, testing the waters and seeing what I can use and what I cannot.
On the other hand, I don’t see this as being bad. I see this as being positive. I am also of the opinion that I am not the only person doing these kind of experiments.
When I first started creating a desktop application for Elixir many people suggested I moved away and that “this was not the purpose of Elixir”. And today we have things like elixir-desktop.
You may argue, “Yes, but you would have to be delusional to compare you silly questions to a project like elixir-desktop”, which I would agree, however the point I am trying to make here is that many of the new tools and functions elixir has now, come from alien places. Some of them stick around. Others don’t. I make no claim that anything I do will stick to anyone ![]()
But if it helps clear the air, then please be kind enough to consider this an academic exercise ![]()
This is quite interesting. Do you know where I could contact the developers and ask this question? Perhaps some mailing list?
Last Post!
donghyun
Hi @Fl4m3Ph03n1x, this might be not related to the topic practically but I just really want to let you know.
I’ve recently been studying several functional programming concepts and I’m very impressed, which I guess so were you. I have so many questions because I want to figure it out how can make code better agains as many cases as possible, so I’ve been exploring just like you. And when I search my questions in this forum, to be honest, I can always find your posts, which it gives me a lot of help!
Just want to let you know that there are some guys like me ![]()
And thanks for all you geniuses in forum giving insight me!
Popular in Questions
Other popular topics
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
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









