blackode

blackode

Elixir Pocket Syntax - short snippets to make your life easier

This is a wiki - anyone at Trust Level 1 or higher can help keep it updated.

Elixir Pocket Syntax

Uncommon Logical stuff of Elixir modules,definitions and some coding snippets that makes our life easy.

1. Creating Private Functions

Code

defp defname(arguments) do
  # your definition goes here 
end

Example

defmodule MyModule do
  @doc "This is the public function can be called out side"
  def public_function do
    IO.puts "I am a public function"
  end

  defp private_function do
    IO.puts "I am private function"
  end
end

Description

Here defp stands for the private function which means you cannot call that function out side module by importing like this MyModule.private_function.This can be used only inside the another functions in the module it has been defined in. In our example it can be called inside the public_function.

2. Pipe Operations `|>’

Code

id |> getName() |> toUpperCase()

Example

defmodule MyModule do
  def function do
    admin = getNameById(id) |> toUpperCase |> isAdmin
    IO.puts admin
  end
end

Description

Here the out put of the getNameById is passed as the first parameter to the toUpperCase in which it returns name as all capitals letters and that name is passed to the isAdmin function to check that the person is admin or not finally a boolean true or false is returned.

The only thing |> does, is to take the return value of the left-hand-side and insert it as first argument in the function on the right-hand-side. This allows you to write above example, instead of writing:

isAdmin(toUpperCase(getNameById(id)))

As above example reads left-to-right (or top-to-bottom), this is more natural to read.

In a typical “object-oriented” language, the code to achieve a similar aim would look like this:

getNameById(id).toUpperCase().isAdmin()

So, you can think of |> as being the Elixir version of . (though without the class lookup).

3. Import specific functions

Code

import :math, only: [sqrt: 1]
import :math, except: [sin: 1, cos: 1]

Example

defmodule MyModule do
  import :math, only: [sqrt: 1]

  def function do
    sqrt 4
  end
end

Description

In the above example only the sqrt function is loaded is imported to the the module. This means that this specific function can be accessed like sqrt(4) (or, without the brackets, sqrt 4). All other functions, even ones in the :math module still need to be accessed by prefixing the full module name, such as :math.sin(2).

4. Functions with Default Values

Code

def fall_velocity(distance, gravity \\ 9.8) do
  # code
end

Example

import :math, only: [sqrt: 1]
defmodule MyModule do
  def fall_velocity(distance, gravity \\ 9.8) do
    velocity=sqrt 2*gravity*distance
    IO.puts "the falling velocity is #{velocity}"
  end
end

Description

By adding default arguments, Elixir underwater adds multiple versions of the function for you, with different arities (taking a different amount of parameters). In above example, a fall_velocity/1 and a fall_velocity/2 is defined. The underwater implementation of fall_velocity/1 is as follows:

def fall_velocity(distance), do: fall_velocity(distance, 9.8)

So: the shorter version(s) of a function will call the longest version with the later argument(s) filled in with the specified default value(s).

Defaults With Pattern-Matching

If your function has multiple clauses, it must have a function head (like a clause without a body), and the default(s) must be defined only there.

Example

defmodule MyModule do
  def greet(name, greeting \\ "Hello")

  def greet("", _) do
    IO.puts "Please tell me your name."
  end

  def greet(name, greeting) do
    IO.puts "#{greeting}, #ecto::tag name}"
  end
end

5. Documentation and specifications

Code

defmodule Mymdule do
  @moduledoc """
  Explanation about the module
  """

  @vsn 0.1 # module version

  @doc """
    your documentation here can have multiple 
    lines of text 
    line1
    line2 
    etc
  """
  @spec function_name(number()) :: number()
  def function_name do
    # code
  end
end

How to use?

h(Modulename.function_name)
s(Modulename.function_name)

Description

Here h() stands for help when you type like that you will be displayed with the @doc text and similarly when you type s() you will be getting the function specifications it explains what parameters has to pass and what it returns when you call or simply what has to give to the function and what it will give in return.

6. Using Erlang From Elixir

Code

:application.which_applications
:erlang.module_info

Description

here the list_applications returns the list of applications being executed in an Erlang VM .This is the way to use the function from Elixir.
The erlang would be like this

application:which_applications() # moduleName:functionName() 

7. Observer GUI

Code

:observer.start

Description

You will see the Graphical representation of all process and sub prcesses.

8. Single Line definitions

Code

defmodule MyModule do
  def callme, do: IO.puts "This is the single line definition"
  # no need of end here
end

# one line with module (useful in iex):
defmodule MyModule, do: def callme, do: IO.puts "This is the single line definition"

Explanation

The definition name and do block are separated by the ,and no end after the do statement.

9. Single Line if

Code

message = if condition, do: "condition returns false", else: "otherwise"
IO.puts "This prints when #{message}"

10. Aliases

You can define the aliases in two ways

Code

defmodule MyModule do
  alias Geometry.Rectangle, as: Rectangle

  def my_function do
    Rectangle.area({1, 2}, {3, 4})
  end
end
#The above style is most formal one 

defmodule MyModule do
  alias Geometry.Rectangle

  def my_function do
    Rectangle.area({1, 2}, {3, 4})
  end
end
#This is the fast style of aliasing .

Explanation

This line alias Geometry.Rectangle, as: Rectangle of code states that we are naming the alias with name Rectangle You can any kinda name but adding the last name of the module scope is too good choice. By default if you don’t specify the any value for as:something then it assigns the default one i.e the last scope in name here Rectangle

11. String inner inner binary representation

A common trick in Elixir is to concatenate the null byte <<0>> to a string to see its inner binary representation:

Code

iex> "hełło" <> <<0>>
<<104, 101, 197, 130, 197, 130, 111, 0>>

12. Specifying the binary

Code

<<variable::size>>
<<2::4, 4::5>> # this is the 4+5=9 bits binary
<<2::size(4), 4::size(4)>> 
# both are same 

If you do not the size of the binary you can make call some thing like this

<<x::4, y::binary>>

Explanation

The above code line states that first 4 bits are to stored in the x variable. The remaining bits we are storing as the binary blocks in the the variable y which means that rest of the length should multiply by the number 8 as the binary means 8 bits.The size of the tail must be evenly divisible by 8.

<<x::4, y::binary, t::5>> This is the wrong representation, It raised the compilation error . The unsized binary should be at the last i mean tail of the string as followed <<x::4, t::5, y::binary>>

13. Importing constants to another module

defmodule Constants do
  @moduledoc false
  # This module contains compile time constants so that they don't have to be
  # defined in multiple places, but don't also have to be built up repeatedly.

  @doc false
  defmacro __using__(_) do
    quote do
      @constant1 10000
      @constant2 20000
    end
end

Explanation

Here you need to define macro __using__to define the constants. In side the module just use Contants

Code

defmodule MyModule do
  use Constants

  def calleme, do: IO.puts "constant 1 value = #{@constant1}"
end

Note

make sure both are at the same hierarchy . According to you above code.If you need you can change but be sure you have to change the use path/to/module/ also :thanks:

14. Updating maps

Consider that you have Map like the below one I have shown …

person = %{name: "John", age: 22, place: "York Street"}

Here if you want to change the name field of the person map , you can simply do like this.

new_person = %{person | name: "Jopra"}

You see that actually It won’t rewrite the person data it gives you the new copy of the person data with the name field changing to our update . The person data is immutable here.
You can also update multiple keys here unlike the firsr example I have shown on this snippet.

new_person = %{person | name: "Jopra", age: "secret"}

15 hd and tl list functions

list = [1,2,3,4,5]
hd list # returns the first element in the list    1
tl list # returns the tail list i.e only the tail part of the list  [2,3,4,5]

Most Liked

michalmuskala

michalmuskala

You can easily see how the code will be grouped with quote and Macro.to_string:

iex(1)> quote(do: foo 1 |> bar()) |> Macro.to_string |> IO.puts
foo(1 |> bar())
:ok
iex(2)> quote(do: foo(1) |> bar()) |> Macro.to_string |> IO.puts
foo(1) |> bar()
:ok
taiansu

taiansu

Pipe operator has higher precedence, so

getNameById id |> toUpperCase
#well actually become
getNameById(toUpperCase(id))

Use

admin = getNameById(id) |> toUpperCase
#or
admin = id |> getNameById |> toUpperCase

to generate

getNameById(id).toUpperCase()
josevalim

josevalim

Creator of Elixir

Those are great suggestions. The only one that called my attention on this one.

If a module needs to exports constants, then it would be preferable to simply list those constants as functions and any other piece of code may call it as necessary.

NobbZ

NobbZ

defmodule myModule do
    def function() do
        admin = getNameById id |> toUpperCase |> isAdmin
        IO.puts admin
    end
end

getNameById(id).toUpperCase().isAdmin()

Your “description” looks like you want to call toUppercase() on the result of getNameById(id), while your example does something different! It does first pass id to toUppercase and that result to isAdmin and finally passes that result to getNameById.

Just look at the following example in iex:

iex(1)> IO.inspect 1 |> to_string  # What you have written
"1"   # this line was printed
"1"   # this line shows what was returned
iex(2)> IO.inspect(1) |> to_string # What you have described
1     # This line was printed
"1"   # This line shows what was returned

Parenthesises are optional but important.

AstonJ

AstonJ

Nice one @blackode :023:

Are you happy for me to turn this into a wiki so that others can help edit/add to it?

I also agree with @benwilson512 about Elixir conventions, removing camelCase where it’s generally not used is a particular necessity.

Where Next?

Popular in Wikis Top

Eiji
At start some definitions: HTTPS (is a protocol for secure communication over a computer network which is widely used on the Internet) -...
New
axelson
Preamble This Wiki is intended to be a community-maintained (see the Contribution Guidelines if interested) resource of common “gotchas” ...
New
Rich_Morin
I’d like to start a discussion of data serialization formats, in the context of Elixir. The rest of this note is a combination of persona...
New
ibgib
Popular Elixir Packages List of popular Atom.io Elixir Packages. These can be installed via atom’s package center or a command line with ...
New
blackode
This is a wiki - anyone at Trust Level 1 or higher can help keep it updated. Elixir Pocket Syntax Uncommon Logical stuff of Elixir modul...
New
gmile
:httpc HTTP client is part of Erlang standard library, and as such can be easily used in Elixir code too. One particular advantage of usi...
New
shavit
To transcode the video there is FFMPEG. On Demand When a user uploads a video, the app renames and copy the file to a path, then call F...
New
BartOtten
A wiki for Doom Emacs Doom is a configuration framework for GNU Emacs. It focuses on performance and customizability. It can be a founda...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
blackode
Hi and Hello Every Elixirian. After Learning the Elixir basics, I struck then. I have no idea of how to put my Elixir Knowledge in pract...
New

Other popular topics Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New

We're in Beta

About us Mission Statement