Lazy - fun project exploring lazy sequences in Erlang

This is a small fun/toy project that we have been entertaining for a while, to emulate lazy sequences as found in other languages.
In a nutshell, instead of iterating over a concrete list, lazy uses generators (built-in or custom write-your-own) that produce values on the fly and only when needed, topped off with a lists-like API.

4 Likes

Nice. A while back I implemented something similar inside fez to cover the api for fsharp "Seq"s:

What I have found though is that I have never missed not having lazy sequences when programming erlang but maybe one doesn’t miss what one doesn’t have :slight_smile:

3 Likes

Gleam has another similar module here: gleam/iterator - gleam_stdlib

Quite fun to see how each implementation differs!

3 Likes

Yeah, I feel the same when it comes to the pipe operator :wink:

So yes, this was just a fun project to see if and how we could pull it off, and as we got in the swing of it, we added function after function, which was a drag to test and document afterwards :blush: But it turned out quite nice IMO and so we decided to show it off here :sweat_smile: It might even be useful to someone.

What surprised me was that both libraries have a lot of the functions in common, often with the same or at least similar names even. Did you model it on and take inspiration from the lists module? At least this is what we did :wink:

Personally, I’m a bit torn on the topic of lazy evaluation, and lazy sequences in particular. They are quite cool, but somewhat less predictable than non-lazy ones, more so if you allow for infinite sequences. You might go chugging along nice and lazy, taking the low memory usage for granted and all, and suddenly through some lapse it may explode into memory all at once, or you end up in an infinite loop as you run down an infinite sequence.

I think Erlang is wise not to have laziness built in into lists like other languages do (or maybe that wasn’t a conscious decision). It’s predictable by default, but it does not block the way for implementations like ours (or Gleams), which you may use (or implement yourself) if you need it and hopefully understand the hidden risks.

3 Likes

I think the documentation could use a few more warnings, for cases we outlined in lazy here. You have some more functions in there that may run into that scenario than we do, namely all, any and find.

3 Likes

It’s based on the Gleam list module, which was designed based off the list modules of Erlang, Elixir, Elm, OCaml, and others.

I pretty much only use it for when a sequence would otherwise be too large to fit in memory, such as if reading a very large file. There are Gleamers who tend to use it over lists though, and languages such as Python and Ruby seem to do well using lazy sequences by default. Not that they’re overly performance focused languages.

A great suggestion, thank you

3 Likes

You’re welcome :blush:

We added most of the missing functions to lazy yesterday, btw.
Ah, the kids, they grow so fast (or so people say) :sweat_smile: But it is just so much fun once you’re into it :smile_cat:

3 Likes

FWIW, we released lazy as a Hex package.

2 Likes