Skip to content

Broadcasting as functor map #32081

@HarrisonGrodin

Description

@HarrisonGrodin

Currently, broadcasting is heavily specialized to work with array-like (i.e. linear, indexable, and finite) data structures. However, the notion of mapping a function over a parameterized datatype F{T} applies to many data structures, such as options (Some(3) vs nothing) and trees. In fact, this operation is exactly "functor map", which applies over all functor datatypes.

Functors require that for a given type and its associated "mapping" function (often referred to as fmap or <$>), the following laws hold (using Haskell notation):

fmap id = id
fmap (f . g)  ==  fmap f . fmap g

In other words, a functor must (a) ensure that mapping the identity function has no effect, and (b) ensure that mapping the function composition f ∘ g is the same as first mapping g and then mapping f.

From this mathematical definition, we have derived the "broadcasting" functor map operation f.(x) with x::F{T} for some type F which forms a functor. (Note that the second functor law guarantees that "fusion" is valid!)

This issue proposes that broadcasting be extended to work more seamlessly with other (i.e. non-linear and non-indexable) datatypes, including the fusion feature.

julia> string.(float.(Some(3)))
Some("3.0")

julia> string.(float.(nothing))
nothing
julia> struct Node{T}
           l::Union{Nothing,Node{T}}
           x::T
           r::Union{Nothing,Node{T}}
       end
       const Tree{T} = Union{Nothing,Node{T}}
Union{Nothing, Node{T}} where T

julia> string.(float.(Tree(nothing, 3, Tree(nothing, 4, nothing)))
Tree{String}(nothing, "3.0", Tree{String}(nothing, "4.0", nothing))

There are a few edge cases to consider, such as combining multiple different functor type in a single broadcast call (e.g. f.([1,2,3], Tree(...))). Additionally, a slight redesign of broadcasting may be necessary, due to its design focus on axes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    broadcastApplying a function over a collectiondesignDesign of APIs or of the language itselfspeculativeWhether the change will be implemented is speculative

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions