# ! for infix operators

**URL:** <https://discourse.julialang.org/t/for-infix-operators/8257>\
**Category:** General Usage\
**Tags:** question, infix\
**Created:** [January 9, 2018, 10:01pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257 "2018-01-09T22:01:06Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [January 9, 2018, 10:01pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/1 "2018-01-09T22:01:06Z")

</div>

From the docs:

> Predicate function negation: when the argument of ! is a function, it returns a function which computes the boolean negation of f.

Hence, `!iseven` is a function that returns `true` if the argument is not even. I think it would be useful to generalize this behavior for infix operators, like `==`, `≈`, etc. Currently `!==` has its own definition, but `!≈` is undefined. If `!` worked automatically for infix comparison operators, `!≈` would work.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 9, 2018, 11:29pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/2 "2018-01-09T23:29:52Z")

</div>

Try tab completing \napprox for negating isapprox. If all of the Boolean binary operators already have negated forms, I don’t see much to be gained from !

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [January 10, 2018, 1:03pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/3 "2018-01-10T13:03:42Z")

</div>

> [@stevengj](#):
>
> If all of the Boolean binary operators already have negated forms, I don’t see much to be gained from !

Well, the same could be said about having `!fun` define a new function that negates the result of `fun`; you could just define `!fun` directly. Still people find the automatic negation by `!` useful.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 10, 2018, 1:11pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/4 "2018-01-10T13:11:28Z")

</div>

I think that `!≈` is already allowed, it is just not an infix operator anymore.

```julia
julia> f = !≈
(::#57) (generic function with 1 method)

julia> f(1,2)
true

julia> f(1,1)
false

```

I guess it could be parsed and lowered as you suggest, but the parser would have to special case `!=`.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 10, 2018, 1:16pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/5 "2018-01-10T13:16:50Z")

</div>

> [@e3c6](#):
>
> Well, the same could be said about having !fun define a new function that negates the result of fun; you could just define !fun directly. Still people find the automatic negation by ! useful.

The difference is that there is only a small set of boolean infix operators, and all the ones defined in base _already_ have negated forms.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [January 10, 2018, 1:47pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/6 "2018-01-10T13:47:21Z")

</div>

> [@Tamas\_Papp](#):
>
> I guess it could be parsed and lowered as you suggest, but the parser would have to special case !=.

Actually what I was thinking was having `!` behave the same for infix operators as it does for ordinary functions, in general, not just for `≈`.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 10, 2018, 1:59pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/7 "2018-01-10T13:59:26Z")

</div>

Maybe I was not clear: I meant parsed as it would be for ordinary functions (eg as now), but with the result allowed in an infix position.

However, I agree with @stevengj: given that infix ops already have a negated version which is more compact, I don’t see the pressing need for this. Presumably people are using infix for brevity, so the shorter the better. But perhaps you could open an issue so that this is given due consideration in the post-1.0 era.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 10, 2018, 5:46pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/8 "2018-01-10T17:46:34Z")

</div>

I miss this:

```julia
julia> 2 !in [3, 4]
ERROR: syntax: extra token "!" after end of expression

```

This is possible:

```julia
julia> 2 ∉ [3, 4]
true

```

but it’s a bit unsymmetrical and unsatisfactory if you normally use `in` rather than `∈`.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 10, 2018, 5:52pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/9 "2018-01-10T17:52:12Z")

</div>

Also, what if I define my _own_ boolean operator? Would be nice to be able to get automatic negation with `!<op>`.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [January 10, 2018, 6:04pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/10 "2018-01-10T18:04:43Z")

</div>

> [@DNF](#):
>
> Also, what if I define my own boolean operator? Would be nice to be able to get automatic negation with !\<op\>.

I don’t think you can define your own _infix_ boolean operator

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [January 10, 2018, 6:12pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/11 "2018-01-10T18:12:30Z")

</div>

> [@e3c6](#):
>
> I don’t think you can define your own infix boolean operator

> **[GitHub - Ismael-VC/InfixFunctions.jl: Julia infix function hack.](https://github.com/Ismael-VC/InfixFunctions.jl)**
>
> Julia infix function hack. Contribute to Ismael-VC/InfixFunctions.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 10, 2018, 6:41pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/12 "2018-01-10T18:41:25Z")

</div>

> [@e3c6](#):
>
> I don’t think you can define your own infix boolean operator

You can, of course, use one of the many Unicode comparison operators that are parsed as infix operators by Julia but which don’t have a built-in definition in `Base`, like `≷`. But for these it would typically be more natural to define e.g. `≹(x,y) = !(x ≷ y)` using the corresponding Unicode negated operator.

On the other hand, there are some oddball ones like `⩷` that don’t seem to have negated versions in Unicode.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 10, 2018, 7:46pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/13 "2018-01-10T19:46:17Z")

</div>

> [@e3c6](#):
>
> I don’t think you can define your own infix boolean operator

Surely, _any_ infix operator can be boolean if I say so:

```julia
julia> Base.:+(a::String, b::String) = first(a) in b

julia> "hello" + "ahh"
true

julia> "hello" !+ "ab"
ERROR: cannot document the following expression:

!(+"ab")

julia> !+("hello", "ab")
true

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 10, 2018, 7:55pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/14 "2018-01-10T19:55:23Z")

</div>

But honestly, my main point is about `!in`. If my code has lots of

```julia
if a in A

```

in it, but then I want

```julia
if b !in B

```

I don’t think `!(b in B)` or `b ∉ B` is completely satisfactory. So, at least `!in` would be appreciated.

**Edit:** I might also like to do `SomeType !<: Number`, or `x !< y` (to perhaps make a point, while also avoiding unicode). Etc., etc., _ad nauseam_.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 11, 2018, 1:50am UTC](https://discourse.julialang.org/t/for-infix-operators/8257/15 "2018-01-11T01:50:39Z")

</div>

> [@DNF](#):
>
> But honestly, my main point is about `!in`.

What’s the problem with `∉` (tab-completed from `\notin`)?

> … or `x !< y` (to perhaps make a point, while also avoiding unicode). Etc., etc., ad nauseam.

`x !< y` is also known as `x >= y` (or `x ≥ y`), at least for non-NaN values.

---

<div class="post-metadata">

**Author:** ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)\
**Post date:** [January 11, 2018, 3:39am UTC](https://discourse.julialang.org/t/for-infix-operators/8257/16 "2018-01-11T03:39:38Z")

</div>

> [@stevengj](#):
>
> x !\< y is also known as x \>= y

True, and yet these also exist in unicode in negated form: `≮`, `≰`, etc

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 11, 2018, 6:25am UTC](https://discourse.julialang.org/t/for-infix-operators/8257/17 "2018-01-11T06:25:01Z")

</div>

> [@stevengj](#):
>
> What’s the problem with ∉ (tab-completed from \notin)?

A few things:

- It does not look nice to mix `in` and `∉` in the same code
- I may be conservative about using unicode symbols
- Many unicode symbols don’t look very nice in my preferred coding font, typically they are too small and hard to read compared to the surrounding code
- Some unicode symbols may not have negated forms at all.

> [@stevengj](#):
>
> x !\< y is also known as x \>= y (or x ≥ y), at least for non-NaN values.

I may want to make a particular point, e.g. that `x !< y` is an unusual case, and want it to be visually distinctive.

I’m a bit surprised that the preference seems to be relying on the existence of special unicode negated versions, rather than relying on simple composition.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 11, 2018, 6:44pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/18 "2018-01-11T18:44:57Z")

</div>

> [@DNF](#):
>
> I’m a bit surprised that the preference seems to be relying on the existence of special unicode negated versions, rather than relying on simple composition.

Compositions that require changes to the parser are always going to get some pushback — parser changes require a lot of care because there is so much room for unintended consequences.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 11, 2018, 6:50pm UTC](https://discourse.julialang.org/t/for-infix-operators/8257/19 "2018-01-11T18:50:19Z")

</div>

That is of course a valid argument.

I have opened an issue here [! for infix operators · Issue #25512 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/25512) requesting this feature, then I guess we’ll see. This is hardly a critical feature, so the core devs can take their time to consider it.
