# Why \`∋\` (\`\\ni\`) is not a method of \`contains\`?

**URL:** <https://discourse.julialang.org/t/why-ni-is-not-a-method-of-contains/128748>\
**Category:** General Usage\
**Tags:** operator\
**Created:** [May 6, 2025, 11:00am UTC](https://discourse.julialang.org/t/why-ni-is-not-a-method-of-contains/128748 "2025-05-06T11:00:17Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [May 6, 2025, 11:00am UTC](https://discourse.julialang.org/t/why-ni-is-not-a-method-of-contains/128748/1 "2025-05-06T11:00:17Z")

</div>

`in(x)` is a convenient function generator to check whether other variables are contained in `x` (e.g. for filtering). I was looking for a generator of functions that do the opposite (check if other variables contain `x`), and I have found it in `∋` (escaped as `\ni`), but this function does not have a readable ascii alternative name.

Working with strings, there is `occursin` that generalizes the behavior of `in` (so that it works with substrings, not only with characters), and its reverse `contains`. I think that `contains` would be a suitable name for the opposite of `in` for other types. However, `contains` only works with strings and characters, if I’m not mistaken. Why is it that? Would it be a good idea to extend its behavior?

---

<div class="post-metadata">

**Author:** ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)\
**Post date:** [May 6, 2025, 1:56pm UTC](https://discourse.julialang.org/t/why-ni-is-not-a-method-of-contains/128748/2 "2025-05-06T13:56:27Z")

</div>

I agree that `filter(contains(x), y)` is more legible than `filter(∋(x), y)`, but I also feel that `y in x` is much more legible than `contains(x, y)`, so I don’t see much advantage in having a two argument version of what you are proposing.

A disadvantage of having such methods in `Base` is that one could argue that `contains` is not doing the same thing in the `AbstractString` version as in the collection version because one is looking for a sequence (or a match of a regular expression) whereas the other is looking for a single element. Coupled with the fact that this `filter` example is somewhat rare and that one can use `∋`, this might explain avoiding implementing these methods, but maybe the reason is just that nobody ever submitted such a PR.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [May 6, 2025, 2:20pm UTC](https://discourse.julialang.org/t/why-ni-is-not-a-method-of-contains/128748/3 "2025-05-06T14:20:56Z")

</div>

I don’t think there’s a better answer than “that’s the way it (currently) is” here. The names and operations here have slowly iterated and improved, and I don’t think there’s a blocker preventing this from continuing to _find_ more optimal behaviors. There’s this open issue:

> <https://github.com/JuliaLang/julia/issues/47219>
>
> \`contains\`, \`occursin\`, \`startswith\`, \`endswith\` all require \`AbstractString\` (o…r similar) arguments. I don't see why they couldn't be generic.
> 
> The only problem is that they currently are unclear on whether the first argument is an element or a sequence of elements: does \`occursin\` mean "is an element of" or "is a subsequence of"? The docs say it's the latter but \`occursin('a', "abc")\` works.

And there’s a bit of history in [this old comment of mine](https://github.com/JuliaLang/julia/issues/30368#issuecomment-447398148) (up to 2018), but that needs an [additional bullet point from 2020](https://github.com/JuliaLang/julia/issues/35031).

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [May 6, 2025, 2:30pm UTC](https://discourse.julialang.org/t/why-ni-is-not-a-method-of-contains/128748/4 "2025-05-06T14:30:15Z")

</div>

I expect `contains` could be a suitable arg-reverse of `in` and a PR to that end could be accepted. In the meantime, if you want an ascii version (without pretty syntax) you can look at what `in(x)` does:

```julia
julia> in(1:5)
(::Base.Fix2{typeof(in), UnitRange{Int64}}) (generic function with 1 method)

julia> ni3 = Base.Fix1(in, 3)
(::Base.Fix1{typeof(in), Int64}) (generic function with 1 method)

julia> ni3(1:5)
true

julia> ni3(6:10)
false

```

Most of the curried operators use `Base.Fix2` to capture the function and second argument. There’s no pretty syntax for it, but we can use its twin `Base.Fix1` to instead store the first argument like above.
