Noob question on MatchError binding variables

I have learned a bit about binding and pattern matching, but I am very confused about the source of the error below. If seems certain capital letters can’t be bound, but certain small-caps can. Is this a thing? What I’m I missing. For example

iex(1)> a = 122
122
iex(2)> a = 2
2
iex(3)> N = 300
** (MatchError) no match of right hand side value: 300

iex(3)> N = 8
** (MatchError) no match of right hand side value: 8

What exactly is the difference between N and a?

Capital letters denote module names. Variables must start with a lower case value.

4 Likes

Hi @daot,

You’re in the right place!

Capital letters in Elixir are reserved for module names which are represented in CamelCase.

This link here can help you further down in detail:

Thanks.

2 Likes

Ok. I finally found the answer.
Anything starting with a capital letter is an alias for an atom, so it can’t be a variable to be bound.

I’ll leave it here for other noobs like myself :slight_smile:

3 Likes

This is not correct. Capitalized names denote atoms, nothing else. The fact that they might under some circumstances point to existing modules is just a coincidence.

3 Likes

Thank you for the clarification @mudasobwa . What does point to modules mean exactly. I see for example:

iex(1)> IO.puts(N)
Elixir.N
:ok

I assume this does not mean that N is a module of Elixir. What does Elixir.N mean in this context?

@mudasobwa is technically correct, but there’s a bit more going on here. Let’s start with something simple. All modules have a name, and that name is an atom.

iex(1)> is_atom(Enum)
true
iex(2)> is_atom(:erlang)
true

In elixir syntax, if you start with : you make an atom. Here are some examples:

iex(3)> :foo
:foo
iex(4)> :"foo 111"
:"foo 111"
iex(5)> :Foo
:Foo
iex(6)> 

Elixir, as a language on the BEAM VM, also needs to create its modules with atom names. However Elixir didn’t want to worry about conflicts between existing erlang module names and new Elixir module names. Thus, Every elixir module name (an atom) is prefixed with :Elixir. This gets annoying to type though, so if you write a capital letter identifier like Enum this is what is technically called an “alias” for the atom :'Elixir.Enum'

However as @mudasobwa has noted, just that all module names are atoms doesn’t mean that all atoms are module names. You can make atoms with any text value you like, and the same is true of aliases, which are simply a “shorthand” for certain atoms.

P.S.

You might think that the whole issue with conflicting with Erlang modules would be solved by just making things capital, IE Elixir could use :Foo and if erlang had :foo that would be fine since :Foo != :foo. However both of those modules, when compiled, would result in Foo.beam and foo.beam files, which would conflict on file systems that are case insensitive.

3 Likes

That is not a trivial question that can be answered in a couple sentenses. Basically, :N is an atom, and N is an atom, but the latter is a syntactic sugar for :"Elixir.N":

:"Elixir.N" == N
#⇒ true

This is done to ease integration into ErlangVM. You might check whether the module exists with Code.ensure_loaded?/2.

3 Likes

Worth mentioning that nil, true, and false also are atoms:

iex> :true == true
true
3 Likes

I just tweeted this for other reasons, but it now seems on topic here too. If you can explain this, then you’ve got a solid understanding of Elixir atoms and pattern matching

iex(1)> :false = false
false
iex(2)> :false == false
true
1 Like

:false = false returns false for the same reason %{} = %{foo: :bar} returns %{foo: :bar}. The value of the match expression is the matched value.

:false == false though is true for the same reason %{} == %{foo: :bar} is false. Two values are comapred for equalitiy, which they either are, or are not.

1 Like

You’ve got a solid understanding of Elixir atoms and pattern matching. But I wish you’d given others the chance to demonstrate that to themselves before answering so quickly :slight_smile:

1 Like

Sorry, I was not aware that it was meant as an exercise for the reader but considered it a question instead.

2 Likes