Skip to content

Commit

Permalink
Expose ComposedFunction as a public API (#37517)
Browse files Browse the repository at this point in the history
* document ComposedFunction
* add ComposedFunction to News.md
* Give more descriptive names to the fields of ComposedFunction
* export ComposedFunction

Co-authored-by: Jonas Schulze <jonas.schulze7@t-online.de>
Co-authored-by: Takafumi Arakaki <aka.tkf@gmail.com>
  • Loading branch information
3 people authored Sep 24, 2020
1 parent 864582c commit 978123f
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 8 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ Standard library changes
* `RegexMatch` objects can now be probed for whether a named capture group exists within it through `haskey()` ([#36717]).
* For consistency `haskey(r::RegexMatch, i::Integer)` has also been added and returns if the capture group for `i` exists ([#37300]).
* A new standard library `TOML` has been added for parsing and printing [TOML files](https://toml.io) ([#37034]).
* The composition operator `` now returns a `Base.ComposedFunction` instead of an anonymous function ([#37517]).
* A new standard library `Downloads` has been added, which replaces the old `Base.download` function with `Downloads.download`, providing cross-platform, multi-protocol, in-process download functionality implemented with [libcurl](https://curl.haxx.se/libcurl/) ([#37340]).
* The `Pkg.BinaryPlatforms` module has been moved into `Base` as `Base.BinaryPlatforms` and heavily reworked.
Applications that want to be compatible with the old API should continue to import `Pkg.BinaryPlatforms`,
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export
ComplexF64,
ComplexF32,
ComplexF16,
ComposedFunction,
DenseMatrix,
DenseVecOrMat,
DenseVector,
Expand Down
48 changes: 40 additions & 8 deletions base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -871,26 +871,58 @@ julia> fs = [
julia> ∘(fs...)(3)
3.0
```
See also [`ComposedFunction`](@ref).
"""
function end

struct ComposedFunction{F,G} <: Function
f::F
g::G
ComposedFunction{F, G}(f, g) where {F, G} = new{F, G}(f, g)
ComposedFunction(f, g) = new{Core.Typeof(f),Core.Typeof(g)}(f, g)
"""
ComposedFunction{Outer,Inner} <: Function
Represents the composition of two callable objects `outer::Outer` and `inner::Inner`. That is
```julia
ComposedFunction(outer, inner)(args...; kw...) === outer(inner(args...; kw...))
```
The preferred way to construct instance of `ComposedFunction` is to use the composition operator [`∘`](@ref):
```jldoctest
julia> sin ∘ cos === ComposedFunction(sin, cos)
true
julia> typeof(sin∘cos)
ComposedFunction{typeof(sin), typeof(cos)}
```
The composed pieces are stored in the fields of `ComposedFunction` and can be retrieved as follows:
```jldoctest
julia> composition = sin ∘ cos
sin ∘ cos
julia> composition.outer === sin
true
julia> composition.inner === cos
true
```
!!! compat "Julia 1.6"
ComposedFunction requires at least Julia 1.6. In earlier versions `∘` returns an anonymous function instead.
See also [`∘`](@ref).
"""
struct ComposedFunction{O,I} <: Function
outer::O
inner::I
ComposedFunction{O, I}(outer, inner) where {O, I} = new{O, I}(outer, inner)
ComposedFunction(outer, inner) = new{Core.Typeof(outer),Core.Typeof(inner)}(outer, inner)
end

(c::ComposedFunction)(x...) = c.f(c.g(x...))
(c::ComposedFunction)(x...) = c.outer(c.inner(x...))

(f) = f
(f, g) = ComposedFunction(f, g)
(f, g, h...) = (f g, h...)

function show(io::IO, c::ComposedFunction)
show(io, c.f)
show(io, c.outer)
print(io, "")
show(io, c.g)
show(io, c.inner)
end

"""
Expand Down
1 change: 1 addition & 0 deletions doc/src/base/base.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ Base.invokelatest
new
Base.:(|>)
Base.:(∘)
Base.ComposedFunction
```

## Syntax
Expand Down

0 comments on commit 978123f

Please sign in to comment.