Curious case of ‘in’ in Elixir

A laptop and a mounted television.
Not related to the article. Just added to make thumbnail look good ;)

tl;dr

'in' is usually used with list or range. But here we

Don’t try this at home

Just kidding, we can use this, but we might introduce unnecessary bugs in the code and might make the code unreadable as this is not widely practiced. Let’s do this as an experiment to know more about Elixir.

Using ‘in’ with string

Let’s try to find whether a substring is present inside a string.

"lix" in "Elixir"

I want this to give back ‘true’. But it errors as

** (Protocol.UndefinedError) protocol Enumerable not implemented for "ab" of type BitString
(elixir 1.10.4) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir 1.10.4) lib/enum.ex:166: Enumerable.member?/2
(elixir 1.10.4) lib/enum.ex:1682: Enum.member?/2

So let’s implement Enumerable for String.

Now If we run

"lix" in "Elixir"

in iex, it will return ‘true’.

History detour

This curiosity started while I was debugging a code related to ‘from’ in ecto query. How ecto allows us to write code like

from(c in City, select: c)
https://hexdocs.pm/ecto/Ecto.Query.html#from/2

Click on the `(macro) </>` to reach the Elixir codebase which implements this.

Let’s implement a shorter form.

Define macro with ‘in’

we can import this module and use as having("lix" in "Elixir") |> do_something() . We can use the result of ‘having’ function further.This is how ‘in’ is added in ecto to improve readability.