Skip to content

Commit 887815c

Browse files
Merge pull request #17155 from JuliaLang/sk/funcnegcomp
function composition (f∘g) and negation (!f)
2 parents 7bb7f13 + ab6f431 commit 887815c

File tree

4 files changed

+56
-1
lines changed

4 files changed

+56
-1
lines changed

base/exports.jl

+1
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ export
233233
~,
234234
:,
235235
=>,
236+
,
236237
A_ldiv_B!,
237238
A_ldiv_Bc,
238239
A_ldiv_Bt,

base/operators.jl

+44-1
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,48 @@ julia> [1:5;] |> x->x.^2 |> sum |> inv
665665
"""
666666
|>(x, f) = f(x)
667667

668+
# function composition
669+
670+
"""
671+
f ∘ g
672+
673+
Compose functions: i.e. `(f ∘ g)(args...)` means `f(g(args...))`. The `∘` symbol can be
674+
entered in the Julia REPL (and most editors, appropriately configured) by typing `\circ<tab>`.
675+
Example:
676+
677+
```jldoctest
678+
julia> map(uppercase∘hex, 250:255)
679+
6-element Array{String,1}:
680+
"FA"
681+
"FB"
682+
"FC"
683+
"FD"
684+
"FE"
685+
"FF"
686+
```
687+
"""
688+
(f, g) = (x...)->f(g(x...))
689+
690+
691+
"""
692+
!f::Function
693+
694+
Predicate function negation: when the argument of `!` is a function, it returns a
695+
function which computes the boolean negation of `f`. Example:
696+
697+
```jldoctest
698+
julia> str = "∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε"
699+
"∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε"
700+
701+
julia> filter(isalpha, str)
702+
"εδxyδfxfyε"
703+
704+
julia> filter(!isalpha, str)
705+
"∀ > 0, ∃ > 0: |-| < ⇒ |()-()| < "
706+
```
707+
"""
708+
!(f::Function) = (x...)->!f(x...)
709+
668710
# array shape rules
669711

670712
promote_shape(::Tuple{}, ::Tuple{}) = ()
@@ -989,6 +1031,7 @@ export
9891031
,
9901032
,
9911033
,
1034+
,
9921035
colon,
9931036
hcat,
9941037
vcat,
@@ -1002,6 +1045,6 @@ import ..this_module: !, !=, xor, %, ÷, &, *, +, -,
10021045
/, //, <, <:, <<, <=, ==, >, >=, >>, >>>,
10031046
<|, |>, \, ^, |, ~, !==, ===, >:, colon, hcat, vcat, hvcat, getindex, setindex!,
10041047
transpose, ctranspose,
1005-
, , , , ×, , , , , , , , , , , ,
1048+
, , , , ×, , , , , , , , , , , , ,
10061049

10071050
end

doc/src/stdlib/base.md

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ Base.method_exists
122122
Core.applicable
123123
Core.invoke
124124
Base.:(|>)
125+
Base.:(∘)
125126
```
126127

127128
## Syntax

test/operators.jl

+10
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,13 @@ Base.:/(::T19714, ::T19714) = T19714()
7979
Base.convert(::Type{T19714}, ::Int) = T19714()
8080
Base.promote_rule(::Type{T19714}, ::Type{Int}) = T19714
8181
@test T19714()/1 === 1/T19714() === T19714()
82+
83+
# pr #17155
84+
@testset "function composition" begin
85+
@test (uppercasehex)(239487) == "3A77F"
86+
end
87+
@testset "function negation" begin
88+
str = randstring(20)
89+
@test filter(!isupper, str) == replace(str, r"[A-Z]", "")
90+
@test filter(!islower, str) == replace(str, r"[a-z]", "")
91+
end

0 commit comments

Comments
 (0)