# Operators and functions

**URL:** <https://discourse.julialang.org/t/operators-and-functions/84502>\
**Category:** General Usage\
**Tags:** functions\
**Created:** [July 20, 2022, 5:06am UTC](https://discourse.julialang.org/t/operators-and-functions/84502 "2022-07-20T05:06:10Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [July 20, 2022, 5:06am UTC](https://discourse.julialang.org/t/operators-and-functions/84502/1 "2022-07-20T05:06:10Z")

</div>

How come these work

```julia
==(2).(1:5)
≠(2).(1:5)
>(2).(1:5)

```

and these don’t ?

```julia
+(2).(1:5)
*(2).(1:5)
^(2).(1:5)

```

---

<div class="post-metadata">

**Author:** ![rikh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rikh/32/204104_2.png) [@rikh](https://discourse.julialang.org/u/rikh)\
**Post date:** [July 20, 2022, 6:23am UTC](https://discourse.julialang.org/t/operators-and-functions/84502/2 "2022-07-20T06:23:35Z")

</div>

The syntax `func.(collection)` means applying `func` to the `collection`. For example

```julia
julia> (x -> 2x).(1:5)
5-element Vector{Int64}:
  2
  4
  6
  8
 10

```

In your example, `==(2)`, `≠(2)` and `>(2)` are functions whereas `+(2)`, `*(2)` and `^(2)` are not.

```julia
julia> ==(2) isa Function
true

julia> +(2) isa Function
false

```

For more information, `==(2)` is called a partial function application. This is a term from functional programming which means to fix an argument to a function. Specifically, `==(2)` is equivalent to defining `==(x) = y -> x == y` which is equivalent to `Base.Fix2(==, 2)`. See the documentation of `Base.Fix2` for more information about that function.

For readers who wonder why partial function applications are useful, they are mostly useful in combination with higher order functions, that is, functions which take functions such as `map` or `filter`. For example, compare

```julia
julia> map(x -> x < 2, 1:5)
5-element Vector{Bool}:
 1
 0
 0
 0
 0

julia> filter(x -> x == 2, 1:5)
1-element Vector{Int64}:
 2

julia> filter(s -> contains(s, "ar"), ["foo", "bar"])
1-element Vector{String}:
 "bar"

```

to

```julia
julia> map(<(2), 1:5)
5-element Vector{Bool}:
 1
 0
 0
 0
 0

julia> filter(==(2), 1:5)
1-element Vector{Int64}:
 2

julia> filter(contains("ar"), ["foo", "bar"])
1-element Vector{String}:
 "bar"

```

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [July 20, 2022, 6:52am UTC](https://discourse.julialang.org/t/operators-and-functions/84502/3 "2022-07-20T06:52:15Z")

</div>

Can this notation be used to abbreviate this?

`filter( x-> any( contains.(x,["a","b"]) ), ["aa","bb","cc","dd"] )`

---

<div class="post-metadata">

**Author:** ![rikh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rikh/32/204104_2.png) [@rikh](https://discourse.julialang.org/u/rikh)\
**Post date:** [July 20, 2022, 9:15am UTC](https://discourse.julialang.org/t/operators-and-functions/84502/4 "2022-07-20T09:15:21Z")

</div>

Not that I know of. Sounds like a nice idea though to allow applying AND and OR to functions. What does work here is to move the OR (`any`) inside the `contains`:

```julia
julia> filter(contains(r"a|b"), ["aa", "bb", "cc", "dd"])
2-element Vector{String}:
 "aa"
 "bb"

```

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [July 21, 2022, 12:31am UTC](https://discourse.julialang.org/t/operators-and-functions/84502/5 "2022-07-21T00:31:05Z")

</div>

Could this functional form be available for more functions ?  
2 examples

It would be nice to write this  
`@pipe "A=1,B=2,C=3" |> split(_,',') |> split.(_,'=') `

As  
`"A=1,B=2,C=3" |> split(',') .|> split('=')`

```julia

```

And it would be nice to write this

```julia
conv(x) = 
    try Date( x, dateformat"dduuuyyyy") catch        
    try Currency_Dict[x] catch
    try Buy_Sell_Dict[x] catch
    try parse(Float64,x) catch    
    try Symbol(x) catch     
    end end end end
end

```

as

```julia
conv(x) = x |>
    try Date(dateformat"dduuuyyyy") catch        
    try Currency_Dict catch
    try Buy_Sell_Dict catch
    try parse(Float64) catch    
    try Symbol catch     
    end end end end
end

```

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [July 21, 2022, 2:02am UTC](https://discourse.julialang.org/t/operators-and-functions/84502/6 "2022-07-21T02:02:46Z")

</div>

> [@Lincoln\_Hannah](#):
>
> `"A=1,B=2,C=3" |> split(',') .|> split('=')`

The challenging part about this is that this is the following currently return something when the arguments are strings.

```julia
julia> split(",")
1-element Vector{SubString{String}}:
 ","

julia> split("=")
1-element Vector{SubString{String}}:
 "="

```

Nonetheless, you correctly identified that `split(::Char)` is not currently defined. Thus we could do:

```julia
julia> Base.split(c::AbstractChar) = Base.Fix2(Base.split, c)

julia> split(',')
(::Base.Fix2{typeof(split), Char}) (generic function with 1 method)

julia> "A=1,B=2,C=3" |> split(',') .|> split('=')
3-element Vector{Vector{SubString{String}}}:
 ["A", "1"]
 ["B", "2"]
 ["C", "3"]

help?> Base.Fix2
  Fix2(f, x)

  A type representing a partially-applied version of the two-argument function f, with the second argument fixed to
  the value "x". In other words, Fix2(f, x) behaves similarly to y->f(y, x).

```

A better definition would also allow for the other keyword arguments:

```julia
Base.split(c::AbstractChar; kwargs...) = Base.Fix2(Base.split, dlm; kwargs...)

```

The above could be potentially confusing, so I would prefer the following:

```julia
julia> Base.split(; dlm=isspace) = Base.Fix2(Base.split, dlm)

julia> "A=1,B=2,C=3" |> split(dlm=',') .|> split(dlm='=')
3-element Vector{Vector{SubString{String}}}:
 ["A", "1"]
 ["B", "2"]
 ["C", "3"]

```

The above does not allow for the other keywords. A keyword compatible version would look like this.

```julia
julia> Base.split(; dlm=isspace, kwargs...) = x->Base.split(x, dlm; kwargs...)

julia> "a b c" |> split()
3-element Vector{SubString{String}}:
 "a"
 "b"
 "c"

julia> "a b c" |> split(limit=2)
2-element Vector{SubString{String}}:
 "a"
 "b c"

```

Hot patching `Base` like this is frowned upon. It might be fine in a terminal project, but can create issues for composability. Another approach is to create your own `split` in a module or package and then import that into your namespace.

```julia
julia> module SplitFix2
           split(c::AbstractChar) = Base.Fix2(Base.split, c)
           split(; dlm=isspace, kwargs...) = x->Base.split(x, dlm; kwargs...)
       end
Main.SplitFix2

julia> import .SplitFix2: split

julia> "a b c" |> split(limit=2)
2-element Vector{SubString{String}}:
 "a"
 "b c"

julia> "A=1,B=2,C=3" |> split(dlm=',')
3-element Vector{SubString{String}}:
 "A=1"
 "B=2"
 "C=3"

julia> Base.split == SplitFix2.split
false

julia> @which split
Main.SplitFix2

```

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [July 21, 2022, 12:55pm UTC](https://discourse.julialang.org/t/operators-and-functions/84502/7 "2022-07-21T12:55:08Z")

</div>

Thanks Mark.

Most functions have one argument that is the data input, and so the one I’d like to be passable from a pipe or chain. Maybe I’ll create my own versions with slightly different names (to avoid the issue you mention with split( ::string ) already being defined ).

```julia
splt(dlm) = x -> (split(x,dlm))
fltr(f) = x -> filter( f, x )
Dat(format) = x -> Date( x, format)
pars(typ) = x -> parse(typ,x)
CSV_write(file) = x -> CSV.write( file, x )

```

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [July 21, 2022, 12:57pm UTC](https://discourse.julialang.org/t/operators-and-functions/84502/8 "2022-07-21T12:57:31Z")

</div>

I like your version with `split(dlm=',')` as you’re able to keep the same name.
