From a71efe08da054c06d5066f01a52d27dae3f196ab Mon Sep 17 00:00:00 2001 From: Carlos Parada Date: Thu, 17 Feb 2022 15:02:24 -0800 Subject: [PATCH 1/4] Document `map` behavior --- base/abstractarray.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 9c3cb23865dff..7c324062a7323 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -2936,6 +2936,11 @@ mapany(f, itr) = Any[f(x) for x in itr] Transform collection `c` by applying `f` to each element. For multiple collection arguments, apply `f` elementwise, and stop when when any of them is exhausted. +Note that `f` makes no guarantees about the order in which `f` is called on elements. In +addition, `f` is assumed to be [pure](https://en.wikipedia.org/wiki/Pure_function) when +working with data structures exhibiting sparsity, such as sparse or diagonal arrays, and +will only be called once on duplicated elements. + See also [`map!`](@ref), [`foreach`](@ref), [`mapreduce`](@ref), [`mapslices`](@ref), [`zip`](@ref), [`Iterators.map`](@ref). # Examples From 64a654e281b37b31fcfe1e0897cbd1a9fba60cd4 Mon Sep 17 00:00:00 2001 From: Carlos Parada Date: Thu, 17 Feb 2022 15:07:42 -0800 Subject: [PATCH 2/4] clearer wording --- base/abstractarray.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 7c324062a7323..4f01c0e292a42 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -2937,9 +2937,9 @@ Transform collection `c` by applying `f` to each element. For multiple collectio apply `f` elementwise, and stop when when any of them is exhausted. Note that `f` makes no guarantees about the order in which `f` is called on elements. In -addition, `f` is assumed to be [pure](https://en.wikipedia.org/wiki/Pure_function) when -working with data structures exhibiting sparsity, such as sparse or diagonal arrays, and -will only be called once on duplicated elements. +addition, `f` is assumed to be [pure](https://en.wikipedia.org/wiki/Pure_function). Using +an impure function together with `f` can cause bugs when working with some data structures, +e.g. sparse or diagonal arrays, as `f` will only be called once on duplicated elements. See also [`map!`](@ref), [`foreach`](@ref), [`mapreduce`](@ref), [`mapslices`](@ref), [`zip`](@ref), [`Iterators.map`](@ref). From 06fb5e7838c583b63c6b35de5cfaa48ecb071bad Mon Sep 17 00:00:00 2001 From: Carlos Parada Date: Sun, 3 Apr 2022 12:46:34 -0700 Subject: [PATCH 3/4] Add more docs --- base/abstractarray.jl | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 5c02ec13ac5fc..2c5e3b2682642 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -2787,6 +2787,11 @@ colons go in this expression. The results are concatenated along the remaining d For example, if `dims` is `[1,2]` and `A` is 4-dimensional, `f` is called on `A[:,:,i,j]` for all `i` and `j`. +Note that `mapslices` makes no guarantees about the order of execution. In addition, `f` is +assumed to be [pure](https://en.wikipedia.org/wiki/Pure_function) when working with sparse +data structures. Using an impure function with `mapslices` may cause bugs on sparse or +diagonal arrays, as `f` may only be called once on duplicated elements. + See also [`eachcol`](@ref), [`eachslice`](@ref). # Examples @@ -2940,10 +2945,10 @@ mapany(f, itr) = Any[f(x) for x in itr] Transform collection `c` by applying `f` to each element. For multiple collection arguments, apply `f` elementwise, and stop when when any of them is exhausted. -Note that `f` makes no guarantees about the order in which `f` is called on elements. In -addition, `f` is assumed to be [pure](https://en.wikipedia.org/wiki/Pure_function). Using -an impure function together with `f` can cause bugs when working with some data structures, -e.g. sparse or diagonal arrays, as `f` will only be called once on duplicated elements. +Note that `map` makes no guarantees about the order of execution. In addition, `f` is assumed +to be [pure](https://en.wikipedia.org/wiki/Pure_function) when working with sparse data +structures. Using an impure function with `map` may cause bugs on sparse or diagonal arrays, +as `f` may only be called once on duplicated elements. See also [`map!`](@ref), [`foreach`](@ref), [`mapreduce`](@ref), [`mapslices`](@ref), [`zip`](@ref), [`Iterators.map`](@ref). @@ -3002,6 +3007,11 @@ end Like [`map`](@ref), but stores the result in `destination` rather than a new collection. `destination` must be at least as large as the smallest collection. +Note that `map!` makes no guarantees about the order of execution. In addition, `f` is assumed +to be [pure](https://en.wikipedia.org/wiki/Pure_function) when working with sparse data +structures. Using an impure function with `map!` may cause bugs on sparse or diagonal arrays, +as `f` may only be called once on duplicated elements. + See also: [`map`](@ref), [`foreach`](@ref), [`zip`](@ref), [`copyto!`](@ref). # Examples From 923443f59027f36a5298db0ec8795257a9fe8e20 Mon Sep 17 00:00:00 2001 From: Carlos Parada Date: Sun, 3 Apr 2022 13:09:27 -0700 Subject: [PATCH 4/4] document other functions --- base/iterators.jl | 8 ++++++-- base/reduce.jl | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/base/iterators.jl b/base/iterators.jl index 1b96a24a9c16f..65452fbada9ab 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -27,8 +27,12 @@ export enumerate, zip, rest, countfrom, take, drop, takewhile, dropwhile, cycle, """ Iterators.map(f, iterators...) -Create a lazy mapping. This is another syntax for writing -`(f(args...) for args in zip(iterators...))`. +Create a lazy mapping. + +When calling `Iterators.map`, `f` is assumed to be +[pure](https://en.wikipedia.org/wiki/Pure_function) if working with sparse +data structures. Using an impure function with `map` may cause bugs on sparse or diagonal +arrays, as `f` may only be called once on duplicated elements. !!! compat "Julia 1.6" This function requires at least Julia 1.6. diff --git a/base/reduce.jl b/base/reduce.jl index 13e1b69c79ede..b4fa5eb851552 100644 --- a/base/reduce.jl +++ b/base/reduce.jl @@ -277,6 +277,11 @@ In general, it will be necessary to provide `init` to work with empty collection intermediate collection needs to be created. See documentation for [`reduce`](@ref) and [`map`](@ref). +Note that `mapreduce` makes no guarantees about the order of execution. In addition, `f` is +assumed to be [pure](https://en.wikipedia.org/wiki/Pure_function) when working with sparse +data structures. Using an impure function with `mapreduce` may cause bugs on sparse or +diagonal arrays, as `f` may only be called once on duplicated elements. + !!! compat "Julia 1.2" `mapreduce` with multiple iterators requires Julia 1.2 or later.