Why no Base.Iterators.map?

There is a Base.Iterators.filter, why no map?

I see there used to be an imap function which was something like

    imap(f,a...) = (f(i...) for i in Iterators.zip(a...) )

which is what I have put in my local utilities package. Really useful for extending existing iterators.

Julia has builtin generators, so you can just do (f(x) for x in iterable)


To get the same functionality as map you need the Iterators.zip.

imap(+, 1:10, 21:20) |> collect

Putting Iterators.zip into a generator is getting clunky. Also if you want to strive for something like a point-free style of programming ( using partial application, etc ) you really want a function like imap and not an expression like ( i for i in itr ).

I guess this is a matter of style. I really like functional style programming. It’s super efficient for exploring solutions in a repl.

Julia’s scheme foundation makes this sort of style quite natural after adding a few “missing” functions. Adding a few choice functions like partial and lazy map is easy enough, but would be cool if they were officially supported.

As an aside, I’ve tried to get into Clojure which is FP oriented, but the java foundation always seems to get in the way. Julia’s primary goal isn’t to be an FP language but I find it very natural to express myself in an FP way.

No. zip.

Base is intentionally very minimal in what it contains.
In particular Base.iterators only contains the iterator functions needed to implement other functionality elsewhere in Base.

If you want more complete iterator functionality.
Use IterTools.jl

Which does have imap


While I appreciate the intention here, this makes it sound like its an internal module I shouldn’t really be using. i.e. if a method in Base.Iterators is no longer needed for functionality elsewhere in Base it could be deprecated. The docs say it contains “Methods for working with Iterators”. Seems like imap ( Iterators.map ) fits this description.

Base.Generator(+, 1:10, 11:20) |> collect. Generators support multi arguments just fine, but they are internally implemented using zip.


Ah, so Base.Generator is pretty much what I’m looking for. Names/namespacing is a little odd looking, but it’s the lazy map function supported out-of-the-box I’m looking for.

julia> Base.Generator(sqrt, Iterators.filter(iseven,1:200000000000)) |> x->take(x,3) |> collect
3-element Array{Float64,1}:

compare to

(sqrt(i) for i in filter(iseven,1:200000000000)) |> x->take(x,3) |> collect
ERROR: OutOfMemoryError()

Base.Generator is the implementation of the generator syntax mentioned above.

My second example was just using less typing to do the same thing conceptually. So the functional difference is using filter instead of Iterators.filter.

Sorry, that was not my intent.
Go ahead and use it.
It is exported, it is there for you to use.

You are correct. That could happen.
But now that 1.0 is out, it will not be removed until 2.0.
Also it would most likely be deprecated to a method in IterTools.jl

It is a true statement, but it is not the whole truth.
All methods in Base.Iterators are for working with iterators, but not all methods for working with Iterators are in Base.Iterators.

Some are in IterTools.jl, some are in personal user packages (e.g. MultiResolutionIterators.jl) – it mean it is an infinitely large set, some have never been written


I have a bit of a non-standard constraint on my intended use of Julia at my organization. Not all users will have internet access. So I’m trying to use as few packages as possible. Using as few packages as possible also seems like a less brittle way of writing julia code.

Seems like there is work being done in Pkg to support internal registries and binary artifacts. These two things will likely allow me to set up my own curated list of packages for the internet challenged.

Looking forwards to the future of Julia! 1.0 is already a really solid experience.

FYI Iterators.map has now been merged to master and appears set to land in Julia 1.6.