Pattern Matching Function (Without Equal Sign)

I was going through elixirschool.com and I am stuck to understand what the author means by specifically this kind of pattern matching. The other kinds I get it, but this one doesn’t make sense.

Functions and Pattern Matching

Behind the scenes, functions are pattern-matching the arguments that they’re called with.

Say we needed a function to accept a map but we’re only interested in using a particular key. We can pattern-match the argument on the presence of that key like this:

defmodule Greeter1 do
  def hello(%{name: person_name}) do
    IO.puts "Hello, " <> person_name
  end
end

This was the output from iex. A bunch of numbers?

{:module, Greeter1,
 <<70, 79, 82, 49, 0, 0, 4, 52, 66, 69, 65, 77, 65, 116, 85,
   56, 0, 0, 0, 133, 0, 0, 0, 14, 15, 69, 108, 105, 120,
   105, 114, 46, 71, 114, 101, 101, 116, 101, 114, 50, 8,
   95, 95, 105, 110, 102, 111, ...>>, {:hello, 1}}

So can anyone elaborate what’s happening here?

That’s the compiled module byte code. You need to call Greeter1.hello(%{name: "something"}) to actually invoke the function.

2 Likes

Basically its the binary representation of the compiled module, you can ignore it when you see it in IEx.

1 Like

Ok, but I do not see any pattern matching here. We just send an argument “something” and it returns “Hello, something”. Where is the pattern matching? Maybe this term is a bit over used?

Thats where the pattern match happens.

2 Likes

But this means that this pattern matching will never fail or give an error, because it will accept all kinds of arguments.

No, that match will fail as soon as you pass something into the function that is not a map, or if it is a map and does not have a key :name.

iex(1)> defmodule Greeter1 do
...(1)>   def hello(%{name: person_name}) do
...(1)>     IO.puts "Hello, " <> person_name
...(1)>   end
...(1)> end
{:module, Greeter1,
 <<70, 79, 82, 49, 0, 0, 4, 248, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 162,
   0, 0, 0, 18, 15, 69, 108, 105, 120, 105, 114, 46, 71, 114, 101, 101, 116,
   101, 114, 49, 8, 95, 95, 105, 110, 102, 111, ...>>, {:hello, 1}}
iex(2)> Greeter1.hello(1)
** (FunctionClauseError) no function clause matching in Greeter1.hello/1

    The following arguments were given to Greeter1.hello/1:

        # 1
        1

    iex:2: Greeter1.hello/1
iex(2)> Greeter1.hello(%{})
** (FunctionClauseError) no function clause matching in Greeter1.hello/1

    The following arguments were given to Greeter1.hello/1:

        # 1
        %{}

    iex:2: Greeter1.hello/1
iex(2)> Greeter1.hello(%{sur_name: "Random"})
** (FunctionClauseError) no function clause matching in Greeter1.hello/1

    The following arguments were given to Greeter1.hello/1:

        # 1
        %{sur_name: "Random"}

    iex:2: Greeter1.hello/1
iex(2)> Greeter1.hello(%{name: "Random"})
Hello, Random
:ok
iex(3)> Greeter1.hello(%{name: "Random", sur_name: "Guy"})
Hello, Random
:ok 
5 Likes

Thank you, now I understand!