Fl4m3Ph03n1x

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

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

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. :smiley:

Fl4m3Ph03n1x

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 :smiley:

But if it helps clear the air, then please be kind enough to consider this an academic exercise :smiley:

This is quite interesting. Do you know where I could contact the developers and ask this question? Perhaps some mailing list?

Last Post!

donghyun

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 :smile:
And thanks for all you geniuses in forum giving insight me!

Where Next?

Popular in Questions Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New

We're in Beta

About us Mission Statement