Folds.jl provides a unified interface for sequential, threaded, and distributed folds.
julia> using Folds
julia> Folds.sum(1:10)
55
julia> Folds.sum(1:10, ThreadedEx()) # equivalent to above
55
julia> Folds.sum(1:10, DistributedEx())
55
Most of the functions can be used with iterator comprehensions:
julia> Folds.sum(y for x in 1:10 if isodd(x) for y in 1:x^2)
4917
and Transducers.jl:
julia> using Transducers
julia> 1:10 |> Filter(isodd) |> MapCat(x -> 1:x^2) |> Folds.sum
4917
Folds.jl interoperates with various packages. For example, StructArrays.jl can be used as an input and/or output:
julia> using StructArrays
julia> table = StructVector(
x = [:a, :a, :b, :a, :b],
y = [1, 2, 3, 4, 5],
);
julia> Folds.copy(StructVector, (row for row in table if row.x === :a))
3-element StructArray(::Vector{Symbol}, ::Vector{Int64}) with eltype NamedTuple{(:x, :y), Tuple{Symbol, Int64}}:
(x = :a, y = 1)
(x = :a, y = 2)
(x = :a, y = 4)
It also works with OnlineStats.jl by treating it as a reducing function (or more precisely a monoid):
julia> using OnlineStats
julia> Folds.reduce(Mean(), 1:10)
Mean: n=10 | value=5.5
Folds.jl decouples the implementation and the execution mechanism ("executor"). Additional executors can be installed from FoldsThreads.jl, FoldsCUDA.jl (rather WIP), and FoldsDagger.jl (very WIP).