Wednesday, April 2, 2025

Intro to Elixir: A contemporary tackle purposeful programming



To print this out we will use the IO.examine perform for fairly printing:

  IO.examine(book_lengths) [17, 12, 9, 9, 21]  

Elixir’s assortment sorts

We’ve already seen the Record kind in motion. Elixir contains these principal assortment sorts:

  • Record: An immutable, however designed for modification-by-duplication, homogenous assortment of arbitrary sorts.
    • Syntax: Sq. brackets with objects:  [x,y,z]
  • Tuple: Designed for holding values primarily, not manipulation, tuples are like lists however geared in the direction of learn efficiency.  Consider them a knowledge entry form of assortment.
    • Syntax: Curly braces with objects: {x,y,z}
  • 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}
  • Maps: The acquainted key-value pairs, the place keys could be something and the gathering is unordered.
    • Syntax: P.c curly braces with pairs:
      • %{x => x1, y => y1, z => z1}
      • %{x: x1, y: y1, z: z1}

Maps and atoms

Maps have two types of declaration, and the one to make use of relies on whether or not the keys are atoms. An atom is a variable whose worth is similar as its identify, a form 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 immediately subsequent to the kay signifies it’s an atom, and atoms could be quote-enclosed (to help in any other case unlawful characters).

The underside line is to make use of the arrow syntax (=>) if you need a regular variable and the important thing and the colon (:) if you need atoms.

Usually, atoms are declared like this:

 :my_atom 

Right here’s one other solution 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 anticipate, you possibly can name different capabilities from throughout the similar module, however these calling in from exterior have to 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 normal library traits go an extended solution 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 complicated and beautiful characteristic 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 primarily based on the e-book title lengths:

 defmodule BookFunctions do   def categorize_length(size) do     case size do       size when size  "Quick"       size when size &lt= 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’s going to even be the purposeful 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 aspect of a group.

Looping

Elixir doesn’t have for and whereas loops. This generally is a bit surprising at first, however it’s in keeping with the immutability favored by purposeful philosophy. In essence, Elixir doesn’t need you doing mutation throughout loops, and as a substitute 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 it’s essential to do could be dealt with with purposeful operations like Enum.every and Enum.map. The Elixir discussion board has a very good, intensive dialogue of looping and options.

Comprehensions

One of the direct methods to simulate a for loop is with comprehensions, which you’d be forgiven for mistaking for an precise for loop:

 for 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 part of(", ")    |> IO.places()  

The output is:

 The Bhagavad Gita, Tao Te Ching 

Concurrency

Though concurrency is a fancy matter, it’s certainly one of Elixir’s areas of power, 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, "good day"} -> 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 will ship a message from the primary course of, utilizing the pid we saved:

 ship pid, {:okay, "good day"} 

This outputs “World” to the console.

Conclusion

Languages are outlined largely by what they make straightforward and what they make laborious. Elixir is clearly devoted to creating it straightforward for a programmer to remain within the purposeful programming mentality, and more durable to stray into mutations and side-effects. 

The general impact is that you simply have a tendency to jot down good purposeful programming code, so long as you’re employed with the language and don’t struggle it. It’s not laborious 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 the way to do issues and an lively, enthusiastic neighborhood.


Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles