Skip to content

Commit

Permalink
Enable multiple function composition in prefix form (#33568)
Browse files Browse the repository at this point in the history
Document the prefix form and extend the prefix form to support composition of 3 or more functions.

Co-Authored-By: Stefan Karpinski <stefan@karpinski.org>
  • Loading branch information
JeffFessler and StefanKarpinski committed Oct 16, 2019
1 parent 3a20608 commit c8313c6
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 2 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ New language features

* `import` now allows quoted symbols, e.g. `import Base.:+` ([#33158]).

* Function composition now supports multiple functions: `∘(f, g, h) = f ∘ g ∘ h`
and splatting `∘(fs...)` for composing an iterable collection of functions ([#33568]).

Language changes
----------------

Expand Down
19 changes: 18 additions & 1 deletion base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -827,17 +827,34 @@ julia> [1:5;] |> x->x.^2 |> sum |> inv
Compose functions: i.e. `(f ∘ g)(args...)` means `f(g(args...))`. The `∘` symbol can be
entered in the Julia REPL (and most editors, appropriately configured) by typing `\\circ<tab>`.
Function composition also works in prefix form: `∘(f, g)` is the same as `f ∘ g`.
The prefix form supports composition of multiple functions: `∘(f, g, h) = f ∘ g ∘ h`
and splatting `∘(fs...)` for composing an iterable collection of functions.
!!!compat "Julia 1.4"
Multiple function composition requires at least Julia 1.4.
# Examples
```jldoctest
julia> map(uppercase∘first, ["apple", "banana", "carrot"])
3-element Array{Char,1}:
'A'
'B'
'C'
julia> fs = [
x -> 2x
x -> x/2
x -> x-1
x -> x+1
];
julia> ∘(fs...)(3)
3.0
```
"""
(f, g) = (x...)->f(g(x...))

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

"""
!f::Function
Expand Down
5 changes: 4 additions & 1 deletion test/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,12 @@ Base.convert(::Type{T19714}, ::Int) = T19714()
Base.promote_rule(::Type{T19714}, ::Type{Int}) = T19714
@test T19714()/1 === 1/T19714() === T19714()

# pr #17155
# pr #17155 and #33568
@testset "function composition" begin
@test (uppercase(x->string(x,base=16)))(239487) == "3A77F"
@test (x -> x-2, x -> x-3, x -> x+5)(7) == 7
fs = [x -> x[1:2], uppercase, lowercase]
@test (fs...)("ABC") == "AB"
end
@testset "function negation" begin
str = randstring(20)
Expand Down

0 comments on commit c8313c6

Please sign in to comment.