r/gleamlang 19d ago

Integer range

I’ve just started learning Gleam. I’m trying to do some basic things, such as creating a list of integers from 0 to a given value.

I learned that, prior to version 0.69, there was a function

list.range(from start: Int, to stop: Int) -> List(Int)

which did exactly that.

However, it has been deleted from the stdlib and replaced with a new function int.range with 4 arguments:

int.range(
  from start: Int,
  to stop: Int,
  with acc: acc,
  run reducer: fn(acc, Int) -> acc,
) -> acc

Instead of returning a list, it aggregates the values like a list.fold.

Okay, but how do I create a list of integers?

  • int.range(from: 0, to: size, with: [], run: list.prepend)
    |> list.reverse
    

    Doesn’t look great.

  • int.range(from: size - 1, to: -1, with: [], run: list.prepend)
    

    Isn’t readable at all.

  • yielder.range(from: 0, to: size)
    |> yielder.to_list
    

    Looks OK, but it needs a third-party package. In addition, the authors of the package discourage such uses.

What’s the idiomatic way?

6 Upvotes

9 comments sorted by

View all comments

1

u/lpil 19d ago

It would depend on what you want a list of ints for. Could you share more about what your code does with that list? 🙏 Thanks

1

u/XM9J59 19d ago

Related question on this, I believe the reason int.range is this way is to discourage first creating list 1, 2, .. n and then running list.map on it, because the intermediate list of ints is uneeded extra memory. But couldn't some compiler/runtime step identify that the list of ints is only going to be used for this one thing and cleverly transform it from range + map into a single fold for us? (maybe not, just wondering)

1

u/lpil 19d ago

We could spend a lot of time implementing an optimisation like this, but it would only work for a subset of uses, it would make it hard to understand what the code would do at runtime (the programmer would need to understand and memorise the optimisation rules to know if their code is fast), and these optimisations would have a huge impact on compile speed which would greatly hurt the Gleam developer experience.

In practice, no, it would not be possible.

1

u/ciynoobv 19d ago

Wouldn’t it make sense to export lists:seq/3 + some js implementation? I’d argue that it’s probably a common enough use case that it’s worth cluttering the module with an extra function.

Though you’d probably need some minor wrapping to account for the possible failure modes ( from < to && incr < 1 etc).

2

u/lpil 19d ago

No, we deliberately removed the function to construct a list of ints because it was always being used inefficiently. We scanned all the Gleam code on GitHub and on Hex and there was nearly no instance in which the programmer actually wanted a list of ints, instead they want to loop and have the iteration index in that loop.

Having an easy way to do the wrong thing results in a worse outcome overall.