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
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.
@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.
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.
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.
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
: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.
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