Stream: helpdesk (published)

Topic: Design: Iterators/Generators vs Arrays


view this post on Zulip Alec (Jan 01 2023 at 21:49):

I have been experimenting with generators (e.g. in the form of Iterators.map and (something... for x in 1:n)) and finding that it can be very nice for composing separate parts of a calculation together and avoiding a bunch of intermediate allocations. However, I'm having a hard time creating generalized functions on them. I think the lack of a formal contract of "this object is an iterable" and not being able to peek into a generator's eltype to dispatch are the specific reasons why I'm having a hard time. I think I also don't really see lazy iterators/generators used heavily in Julia. Should I just bite the bullet and focus on arrays? Not sure if it matters, but I'm speaking of various applications of survival arrays, timepoints, cashflows, etc from the JuliaActuary ecosystem.

view this post on Zulip Sukera (Jan 01 2023 at 21:51):

it depends very heavily on what you're trying to do with iterators - if all your data is already tabular, staying tabular is going to be an advantage

view this post on Zulip Jakob Nybo Nissen (Jan 02 2023 at 11:24):

I've had the same problem as you. My solution was to just not dispatch on iterators in my code. It sucks though.

view this post on Zulip DrChainsaw (Jan 02 2023 at 13:20):

Also agree. In case you missed it, there are a couple of holy-trait functions which can help in some cases: https://docs.julialang.org/en/v1/manual/interfaces/

I often do wonder why something like itertype is not in that list though.

view this post on Zulip Sukera (Jan 02 2023 at 13:31):

You can (in theory) always use eltype as a "trait" for dispatching to an internal function, though be prepared to have a lengthy fallback for Any..

view this post on Zulip Alexander (Jan 06 2023 at 19:23):

Lazy calculations, arrays, tables - in Julia there's no need to choose, you easily get all three :)

julia> using FlexiMaps, Tables

julia> xs = 1:10

# apply lazily computed map
julia> ys = mapview(i -> (;i, i2=i^2), xs)
10-element ...:
 (i = 1, i2 = 1)
 (i = 2, i2 = 4)
...

# ys is an abstractvector with the correct eltype
julia> eltype(ys)
NamedTuple{(:i, :i2), Tuple{Int64, Int64}}

julia> ys isa AbstractVector
true

# and it's a table, so all Tables.jl integrations work
julia> columntable(ys)
(i = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], i2 = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100])

Last updated: Oct 02 2023 at 04:34 UTC