
To print this out we are able to use the IO.examine
perform for fairly printing:
IO.examine(book_lengths)
[17, 12, 9, 9, 21]
Elixir’s assortment varieties
We’ve already seen the Record
kind in motion. Elixir contains these most important assortment varieties:
- Record: An immutable, however designed for modification-by-duplication, homogenous assortment of arbitrary varieties.
- Syntax: Sq. brackets with gadgets:
[x,y,z]
- Syntax: Sq. brackets with gadgets:
- Tuple: Designed for holding values primarily, not manipulation, tuples are like lists however geared in direction of learn efficiency. Consider them an information entry sort of assortment.
- Syntax: Curly braces with gadgets:
{x,y,z}
- Syntax: Curly braces with gadgets:
- Key phrases Record: Ordered key-value pairs, string-only keys, primarily used for named arguments for capabilities
- Syntax: Sq. brackets with pairs:
{x: x1,y: y1,z: z1}
- Syntax: Sq. brackets with pairs:
- Maps: The acquainted key-value pairs, the place keys will be something and the gathering is unordered.
- Syntax: % curly braces with pairs:
%{x => x1, y => y1, z => z1}
%{x: x1, y: y1, z: z1}
- Syntax: % curly braces with pairs:
Maps and atoms
Maps have two types of declaration, and the one to make use of is determined by whether or not the keys are atoms. An atom is a variable whose worth is similar as its identify, a sort of super-constant. An atom is asserted with a colon adopted by a literal.
We may create a map of string keys to integer values like so:
books_and_lengths = %{ "The Bhagavad Gita" => 17, "Tao Te Ching" => 12 }
The next is totally different, and creates a map of atoms to integers, most likely not what we wish on this case:
books_and_lengths = %{ "The Bhagavad Gita": 17, "Tao Te Ching": 12 }
Observe the location of the colon. In a Map
, the colon being instantly subsequent to the kay signifies it’s an atom, and atoms will be quote-enclosed (to help in any other case unlawful characters).
The underside line is to make use of the arrow syntax (=>
) while you desire a regular variable and the important thing and the colon (:
) while you need atoms.
Usually, atoms are declared like this:
:my_atom
Right here’s one other method to declare a map with atom keys:
my_map = %{:atom1 => “foo”, :atom2 => “bar”}
Modules
Elixir helps modules, that are namespaces that collect collectively associated capabilities. It does not maintain state or variables like a category or code block. As you’d count on, you possibly can name different capabilities from inside the similar module, however these calling in from outdoors must preface the calls or import the module.
Right here’s a easy module:
defmodule BookFunctions do
def myFunc
finish
finish
BookFunctions.myFunc()
Sample matching
Syntactic flavors and commonplace library traits go a protracted method to making up the general feeling of utilizing a language. They’re the commonplace options you work together with on a regular basis. However each language has some options that stand out.
Purposeful sample matching is a classy and wonderful function that Elixir brings to the desk, permitting you to carry out conditional perform execution in a switch-like syntax. Let’s say we wish to output small, medium, or lengthy based mostly on the guide title lengths:
defmodule BookFunctions do
def categorize_length(size) do
case size do
size when size <= 10 -> "Quick"
size when size <= 20 -> "Medium"
_ -> "Lengthy"
finish
finish
def print_categories(lengths) do
Enum.every(lengths, fn size ->
class = categorize_length(size)
IO.places("#{size} characters: #{class}")
finish)
finish
finish
A few notes:
BookFunctions
is a module, which you’ve seen.
- In Elixir, return statements are implied, so the
categorize_length()
perform mechanically returns no matter is the results of the final expression.
The case
key phrase is what creates the pattern-matching block, within the categorize_length
perform. The size when size
syntax (technically, a guard clause) lets us do vary checking on the size variable, and if it meets the standards, the ->
operator tells us what to return from the case. (Since that is the ultimate assertion of the perform, it’ll even be the useful return worth.)
We may use this new perform on our book_lengths
like so:
BookBookFunctions.print_categories(book_lengths)
17 characters: Medium
12 characters: Medium
9 characters: Quick
9 characters: Quick
21 characters: Lengthy
Enum.every
is analogous to forEach
in different languages like JavaScript, letting us carry out an operation on every ingredient of a group.
Looping
Elixir doesn’t have for and whereas loops. This could be a bit stunning at first, however it’s according to the immutability favored by useful philosophy. In essence, Elixir doesn’t need you doing mutation throughout loops, and as an alternative needs you to make use of recursion. Recursion retains you within the realm of capabilities, and ideally, you wish to use pure capabilities (that means, capabilities with out side-effects).
A lot of the looping you should do will be dealt with with useful operations like Enum.every
and Enum.map
. The Elixir discussion board has an excellent, in depth dialogue of looping and alternate options.
Comprehensions
One of the crucial direct methods to simulate a for loop is with comprehensions, which you’d be forgiven for mistaking for an precise for loop:
for x <- 0..10, do: IO.places x
See the Elixir docs for extra on comprehensions and the way they simplify assortment operations.
Pipe operator
The pipe operator offers you a clear syntax for chaining perform outcomes collectively. Consider it as a extra elegant type of nesting capabilities. Right here’s a easy instance of the pipe operator on our books_and_lengths
assortment:
books_and_lengths
|> Map.keys()
|> Enum.map(&String.upcase/1)
|> Enum.be a part of(", ")
|> IO.places()
The output is:
The Bhagavad Gita, Tao Te Ching
Concurrency
Though concurrency is a posh matter, it’s one among Elixir’s areas of energy, so let’s take a fast look. Elixir makes use of Actors, one thing like digital threads in that they don’t seem to be full operating-system processes. Actors help message-passing for simplified concurrent communication.
The next instance, demonstrating message dealing with, is from the Elixir docs:
defmodule Instance do
def hear do
obtain do
{:okay, "hey"} -> IO.places("World")
finish
hear()
finish
finish
Discover that the hear
perform is recursive (it calls itself on the finish), which lets it deal with a number of messages. With out the recursion the method would exit.
To launch this Actor, we use spawn
:
pid = spawn(Instance, :hear, [])
Then we are able to ship a message from the primary course of, utilizing the pid
we saved:
ship pid, {:okay, "hey"}
This outputs “World” to the console.
Conclusion
Languages are outlined largely by what they make simple and what they make exhausting. Elixir is clearly devoted to creating it simple for a programmer to remain within the useful programming mentality, and tougher to stray into mutations and side-effects.
The general impact is that you simply have a tendency to jot down good useful programming code, so long as you’re employed with the language and don’t battle it. It’s not exhausting to see why Elixir has captured a lot curiosity, bringing Erlang’s legacy into the fashionable world. It’s a programming language with robust concepts about learn how to do issues and an energetic, enthusiastic group.