Atoms in Elixir

:foo
#=> :foo

is_atom :foo
#=> true

:"foo"
#=> warning: found quoted atom "foo" but the quotes are not
#required. Quotes should only be used to introduce atoms with foreign
#characters in them
#
# :foo

# Looks like :foo. whats does foreign characters mean?

is_atom :"foo"
#=> warning: found quoted atom "foo" but the quotes are not
#required. Quotes should only be used to introduce atoms with foreign
#characters in them
#
# true

:foo == :"foo"
#=> warning: found quoted atom "foo" but the quotes are not
#required. Quotes should only be used to introduce atoms with foreign
#characters in them
#
# true

:
#=> ** (SyntaxError) iex:16: unexpected token: ":" (column 1,
#codepoint U+003A)

:"☺"
#=> :"☺"
# Hmmm. foreign characters mean non-ascii characters?

:1
#=> ** (SyntaxError) iex:16: unexpected token: ":" (column 1,
#codepoint U+003A)

:"1"
#=> :"1"
# 1 is 'foreign characters'?!


:"foo.bar"
#=> :"foo.bar"

:foo.bar
#=> ** (UndefinedFunctionError) function :foo.bar/0 is undefined
#(module :foo is not available)


:Foo
#=> :Foo

is_atom :Foo
#=> true

Foo
#=> Foo

is_atom Foo
#=> true
# no colon prefix needed!

# Is this different from an atom with colon prefix?
:Foo == Foo
#=> false
# Both are atoms but not same

to_string :Foo
#=> "Foo"

to_string Foo
#=> "Elixir.Foo"
# Aha, if the token starts with capital letter, compiler automatically
# converts to this form?

String.to_atom "Foo"
#=> :Foo

String.to_atom "Elixir.Foo"
#=> Foo

:"Elixir.Foo"
#=> Foo

Foo == Elixir.Foo
#=> true

Foo == :"Elixir.Foo"
#=> true

# Whats with the Elixir prefix?

is_atom Elixir
#=> true

is_atom :Elixir
#=> true

:Elixir == Elixir
#=> true
# Wait, What?!
# Looks like :Elixir is special atom


i Elixir
#=> Term
#   Elixir
# Data type
#   Atom
# Reference modules
#   Atom
# Implemented protocols
#   IEx.Info, Inspect, String.Chars, List.Chars
#
# 23:11:51.098 [error] beam/beam_load.c(1428): Error loading module
#   'Elixir': module name in object code is elixir
#
# 23:11:51.100 [error] Loading of
# /usr/local/Cellar/elixir/1.7.4/bin/../lib/elixir/ebin/Elixir.beam
# failed: :badfile

# iex> i Elixir lead to an error!

:"Elixir.Map" == Map
#=> true
# but :__name__ is used to access erlang modules too. Module.__func__
# is just syntatic sugar for :"Elixir.Module"?

:"Elixir.Map".new()
#=> %{}
# indeed! So all Elixir modules are same as erlang modules. And all
# elixir modules are defined under big :Elixir namespace. neat

is_atom File.Stream
#=> true

to_string File.Stat
#=> "Elixir.File.Stat"
# True for nested modules too

# ---------------------------------------------------------------
# Let's try all these different atom notations with keyword list
# ---------------------------------------------------------------

a = [Foo: "bar"]
a[:Foo]
#=> "bar"

a = ["Foo": "bar"]
# a[:Foo]
#=> "bar"

a = [{:Foo, "bar"}]
a[:Foo]
#=> "bar"

a = [{:"Foo", "bar"}]
a[:Foo]
#=> "bar"

a = [{Foo, "bar"}]
a[:Foo]
#=> nil

a[Foo]
#=> "bar"

a = [{Elixir.Foo, "bar"}]
a[Foo]
#=> "bar"

a = [{:"Elixir.Foo", "bar"}]
a[Foo]
#=> "bar"