Fork me on GitHub


Working with and creating sigils.

Table of Contents

Sigils Overview

Elixir provides an alternative syntax for representing and working with literals. A sigil will start with a tilde ~ followed by a character. The Elixir core provides us with some built in sigils however, it is possible to create our own when we need to extend the language.

A list of available sigils include:

A list of delimiters include:

Char List

The ~c and ~C sigils generate character lists respectively. For example:

iex> ~c/2 + 7 = #{2 + 7}/
'2 + 7 = 9'

iex> ~C/2 + 7 = #{2 + 7}/
'2 + 7 = #{2 + 7}'

We can see the lowercased ~c interpolates the calculation, whereas the uppercased ~C sigil does not. We will see that this uppercase / lowercase sequence is a common theme throughout the built in sigils.

Regular Expressions

The ~r and ~R sigils are used to represent Regular Expressions. We create them either on the fly or for use within the Regex functions. For example:

iex> re = ~r/elixir/

iex> "Elixir" =~ re

iex> "elixir" =~ re

We can see that in the first test for equality, that Elixir does not match with the regular expression. This is because it is capitalized. Because Elixir supports Perl Compatible Regular Expressions (PCRE), we can append i to the end of our sigil to turn off case sensitivity.

iex> re = ~r/elixir/i

iex> "Elixir" =~ re

iex> "elixir" =~ re

Further, Elixir provides the Regex API which is built on top of Erlang’s regular expression library. Let’s implement Regex.split/2 using a regex sigil:

iex> string = "100_000_000"

iex> Regex.split(~r/_/, string)
["100", "000", "000"]

As we can see, the string "100_000_000" is split on the underscore thanks to our ~r/_/ sigil. The Regex.split function returns a list.


The ~s and ~S sigils are used to generate string data. For example:

iex> ~s/the cat in the hat on the mat/
"the cat in the hat on the mat"

iex> ~S/the cat in the hat on the mat/
"the cat in the hat on the mat"

What is the difference? The difference is similar to the Character List sigil that we looked at. The answer is interpolation and the use of escape sequences. If we take another example:

iex> ~s/welcome to elixir #{String.downcase "school"}/
"welcome to elixir school"

iex> ~S/welcome to elixir #{String.downcase "school"}/
"welcome to elixir \#{String.downcase \"school\"}"

Word List

The word list sigil can come in handy time to time. It can save both time, keystrokes and arguably reduce the complexity within the codebase. Take this simple example:

iex> ~w/i love elixir school/
["i", "love", "elixir", "school"]

iex> ~W/i love elixir school/
["i", "love", "elixir", "school"]

We can see that what is typed between the delimiters is separated by whitespace into a list. However, there is no difference between these two examples. Again, the difference comes with the interpolation and escape sequences. Take the following example:

iex> ~w/i love #{'e'}lixir school/
["i", "love", "elixir", "school"]

iex> ~W/i love #{'e'}lixir school/
["i", "love", "\#{'e'}lixir", "school"]


A NaiveDateTime can be useful for quickly creating a struct to represent a DateTime without a timezone.

For the most part, we should avoid creating a NaiveDateTime struct directly. However, it is very useful for pattern matching. For example:

iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07") == {:ok, ~N[2015-01-23 23:50:07]}

Creating Sigils

One of the goals of Elixir is to be an extendable programming language. It should come as no surprise then that you can easily create your own custom sigils. In this example, we will create a sigil to convert a string to uppercase. As there is already a function for this in the Elixir Core (String.upcase/1), we will wrap our sigil around that function.

iex> defmodule MySigils do
...>   def sigil_u(string, []), do: String.upcase(string)
...> end

iex> import MySigils

iex> ~u/elixir school/

First we define a module called MySigils and within that module, we created a function called sigil_u. As there is no existing ~u sigil in the existing sigil space, we will use it. The _u indicates that we wish use u as the character after the tilde. The function definition must take two arguments, an input and a list.

Share This Page