Julia's infix as synonym for ∉ operator?

Hello everyone.

I think there’s somebody raising the question in the past but since there’s no news or recent development then, I would like to talk about it again.

Julia has the infix operator in and its equivalence . The language also support the reverse, which is , but by my understanding, there’s no such thing as !in or not in like in Python.

Of course, I would happy to use !(a in b) in my code, but I think it’s reasonable to expect the non-ascii operators have an ascii-typeable equivalent. Plus, not everybody is happy using or in their code, so an infix operator to pair with in is reasonable idea.

Please let me know what do you think about this issue, and is there any new development regarded to it. Thank you in advance !

5 Likes

I don’t think there is much want for an infix ascii \notin. Julia allows you to pick your favourite of two “styles”,

  • traditional ascii, !(a in b); or
  • mathematical a ∉ b,

and that’s good enough for most people. It seems like your proposal falls in between these two styles. Personally, I’d encourage going the whole way and just using ∉. Remember it’s ascii-typaple with \notin<tab>.

4 Likes

Thanks for replying. Yes, of course I know how to type and use Unicode inputs by using \ and <tab> , but that doesn’t stop myself from asking why the language supports so many mathematics operators even like or but not a simple negation infix to pair with in . Please don’t get me wrong, I’ll happy to keep using !(a in b) and also in my code, but in the meantime, it’s a question about the language’s design that got me thinking time to time.

1 Like

Because that’d require having a new reserved keyword in the parser, for limited benefits. The ASCII version of logical negotiation (!) has always been there and it’s not going anywhere.

2 Likes

I suppose a Julian version of not in would be !in. That doesn’t work, but when typed before another method, it seems to make a method that can’t be called? What even is going on here:

julia> 3 in [3]
true
julia> 3 !in [3]
ERROR: syntax: extra token "!" after end of expression

julia> in
in (generic function with 35 methods)
julia> !in
#84 (generic function with 1 method)

julia> !+
#84 (generic function with 1 method)
julia> !+(1,1)
ERROR: MethodError: no method matching !(::Int64)

julia> !println
#84 (generic function with 1 method)
julia> (!println)("huh?")
huh?
ERROR: MethodError: no method matching !(::Nothing)
!(f::Function) = (x...)->!f(x...)

julia> !in([1,2,3], 4)
true

It may be called as a normal function, just not as an infix.

1 Like

Seems like !in([1,2,3], 4) still parses as in then ! separately. Parentheses can help call the actual !in:

julia> @which !in([1,2,3], 4)
!(x::Bool) in Base at bool.jl:35

julia> @which (!in)([1,2,3], 4)
(::Base.var"#84#85")(x...) in Base at operators.jl:1117

So I suppose the intention is to create methods to apply later, like map(!in, args...), without having to write the whole (x...)->!in(x...).

Would it be a breaking change to allow infix syntax for this, you know, parse 3 !in [4] as (!in)(3, [4]) or even just !in(3, [4])? Wouldn’t need to register a bunch of new !_ operators, just parse our way to the !(f::Function) method we already got.

Well, I certainly disagree with that statement: ! for infix operators · Issue #25512 · JuliaLang/julia · GitHub (and the request received some support.)

I would very much like to be able to write a !in B, but there are some problems with generalizing it, due to !== not being the negation of ==.

5 Likes

More discussion here: ! for infix operators and Add infix "!in" as synonym for ∉ ? · Issue #15353 · JuliaLang/julia · GitHub

Thanks for replying. Then I would agree with what @Benny and @jishnub said, as the version of not in should be !in, but it just doesn’t work like that. By adding the parenthesis, it becomes a normal function, not an infix anymore.