# Specify a method to \`!in\`

**URL:** <https://discourse.julialang.org/t/specify-a-method-to-in/18451>\
**Category:** General Usage\
**Created:** [December 8, 2018, 3:42am UTC](https://discourse.julialang.org/t/specify-a-method-to-in/18451 "2018-12-08T03:42:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![garrison](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrison/32/209519_2.png) [@garrison](https://discourse.julialang.org/u/garrison)\
**Post date:** [December 8, 2018, 3:42am UTC](https://discourse.julialang.org/t/specify-a-method-to-in/18451/1 "2018-12-08T03:42:53Z")

</div>

In a function that takes a function as argument, it is clear how to provide a method specific to a named function (e.g. `in` by using `::Base.Fix2{typeof(in),T}`). But it is unclear to me how to do the same thing for `!in`. If I make a method with signature `::Base.Fix2{typeof(!in),T}`, it is never called. In code:

```julia
julia> struct A end;

julia> g(::Base.Fix2{typeof(in),A}) = nothing;

julia> g(::Base.Fix2{typeof(!in),A}) = nothing;

julia> g(in(A()))

julia> g(!in(A()))
ERROR: MethodError: no method matching g(::getfield(Base, Symbol("##54#55")){Base.Fix2{typeof(in),A}})
Closest candidates are:
  g(::Base.Fix2{getfield(Base, Symbol("##54#55")){typeof(in)},A}) at REPL[3]:1
  g(::Base.Fix2{typeof(in),A}) at REPL[2]:1
Stacktrace:
 [1] top-level scope at none:0

```

Am I correct to expect this to 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:** [December 8, 2018, 4:12am UTC](https://discourse.julialang.org/t/specify-a-method-to-in/18451/2 "2018-12-08T04:12:10Z")

</div>

`in(A)` produces a `Fix2` object, but `!in(A)` produces a generic function. To make this work you’d want to define something like:

```julia
Base.:!(f::Base.Fix2{typeof(∈)}) = Base.Fix2(∉, f.x)
Base.:∉(A) = Base.Fix2(∉, A)

```

Note, however, that this is type piracy, so if multiple packages try to do this then they will conflict.

---

<div class="post-metadata">

**Author:** ![garrison](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrison/32/209519_2.png) [@garrison](https://discourse.julialang.org/u/garrison)\
**Post date:** [December 10, 2018, 3:19am UTC](https://discourse.julialang.org/t/specify-a-method-to-in/18451/3 "2018-12-10T03:19:27Z")

</div>

Thanks, this is helpful. I was hoping for a more general/straightforward solution, but this makes sense.

> [@stevengj](#):
>
> Note, however, that this is type piracy, so if multiple packages try to do this then they will conflict.

So a better place to do this might be in Base?

Actually, if modifying Base (or willing to commit type piracy), I believe an even simpler solution is the following:

```julia
!(f::typeof(in)) = ∉
!(f::typeof(∉)) = in # might as well while we are at it

```

This could perhaps be done just after `!f::Function` is defined in Base.

---

<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:** [December 10, 2018, 6:43am UTC](https://discourse.julialang.org/t/specify-a-method-to-in/18451/4 "2018-12-10T06:43:23Z")

</div>

What would be the purpose of this?

---

<div class="post-metadata">

**Author:** ![garrison](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrison/32/209519_2.png) [@garrison](https://discourse.julialang.org/u/garrison)\
**Post date:** [December 11, 2018, 1:31am UTC](https://discourse.julialang.org/t/specify-a-method-to-in/18451/5 "2018-12-11T01:31:36Z")

</div>

Good question. My goal has been to fill out all the methods of UniqueVectors with the most efficient versions possible. I noticed, though, that [the `!in` method](https://github.com/garrison/UniqueVectors.jl/blob/33fd6081016f06be2cc6fe1f0a0efe074ce9e48a/src/UniqueVectors.jl#L73-L74) was not being called, despite me defining it; hence the question here. Examining this more, though, this method is actually no better than the fallback, so it’s completely unnecessary.

---

<div class="post-metadata">

**Author:** ![garrison](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrison/32/209519_2.png) [@garrison](https://discourse.julialang.org/u/garrison)\
**Post date:** [December 11, 2018, 1:46am UTC](https://discourse.julialang.org/t/specify-a-method-to-in/18451/6 "2018-12-11T01:46:39Z")

</div>

Then again, in `Base` it might be desirable to define an override method for `findall` for `!in`, [just as there is currently one for `in`](https://github.com/JuliaLang/julia/blob/73c8eb45926f9aa5c570d790d35a72a70e5f6655/base/array.jl#L2253). I have no specific use for this method at the moment, but it seems useful and could be implemented more efficiently than the current fallback method (which performs linear search in the predicate for each element of the array being searched).

---

<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:** [December 11, 2018, 7:38am UTC](https://discourse.julialang.org/t/specify-a-method-to-in/18451/7 "2018-12-11T07:38:42Z")

</div>

My understanding is that such a method could be defined already, dispatching on `typeof(!in)`.

It is true that `!!in` would fail to call the method the method for `in`, and your proposal would remedy that. But instead, it would be better if `!(!f) === f` was implemented in general.

---

<div class="post-metadata">

**Author:** ![garrison](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrison/32/209519_2.png) [@garrison](https://discourse.julialang.org/u/garrison)\
**Post date:** [December 11, 2018, 12:16pm UTC](https://discourse.julialang.org/t/specify-a-method-to-in/18451/8 "2018-12-11T12:16:09Z")

</div>

> [@Tamas\_Papp](#):
>
> My understanding is that such a method could be defined already, dispatching on `typeof(!in)` .

This does not work – see the original post for a minimal example.

---

<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:** [December 11, 2018, 12:25pm UTC](https://discourse.julialang.org/t/specify-a-method-to-in/18451/9 "2018-12-11T12:25:47Z")

</div>

Right, I missed the closure part.
