Basic types in Elixir
Tags: webdev, beginners, tutorial, elixir
Published: 2024-06-03 11:43:10

Before introducing the basic data types of Elixir, let's briefly introduce how to identify basic functions. This will help you read the code examples later.

## How to Identify functions and documentation
Functions in Elixir are identified by both their name and their arity. The arity of a function describes the number of arguments the function takes.
![Built-in function example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/po1dwch7f2ytay14s8ld.png)

The Elixir shell defines the `h` function, which you can use to access documents for any function 
![Access documentation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3p0a1454dn78jb52p2vx.png)
`h trunc/1` works because it is defined in the [_**Kernel**_ ](https://hexdocs.pm/elixir/1.17.0-rc.0/Kernel.html)module.
_**Kernel**_ module is Elixir's default environment.
All functions in the _**Kernel**_ module are automatically imported into our namespace.


## Basic types
![Basic types](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t5axx23ntu5jn7edxv0u.png)

### Basic arithmetic
```elixir
iex> 1 + 2 
3
iex> 5 * 5
25
```
Operation `/`
The operation /  always returns float  instead of integer
```elixir
iex > 10 / 2
5.0
```
Operation division or get the division's remainder
* notice that Elixir allows you to drop the parentheses when invoking functions that expect one or more arguments.
```elixir
iex> div(10, 2)
5
iex> div 10, 2
5
iex> rem 10, 3
1
```
Elixir also supports shortcut notations for entering binary, octal, and hexadecimal numbers:

```elixir
iex> 0b1010
10
iex> 0o777
iex> 511
iex> 0x1F
31
```
Floats in Elixir are 64-bit precision.
Float numbers require a dot followed by at least one digit and also support `e` for scientific notation:

```elixir
iex> 1.0
1.0
iex> 1.0e-10
1.0e-10
```
You can invoke the `round` function to get the closest integer to a given float, or the `trunc` function to get the integer part of a float.

```elixir
iex> round(4.58)
5
iex> trunc(2.58)
2
```

### Booleans
Elixir supports `true` and `false` as booleans:

```elixir
iex > true
true
iex> true === false
false
```
Elixir also provides three boolean operators: `or/2`, `and/2`, and `not/1`. 
`or/2` and `and/2`These operators are strict in that they expect something that evaluates to a boolean as their first argument.
Requires only the `left` operand to be a boolean since it short-circuits. If the `left` operand is not a boolean, a `BadBooleanError`exception is raised.
If the `not/1` value is not boolean, an `ArgumentError` exception is raised.

![Boolean operators](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t8zpky83lp0yjrkdpec8.png)

```elixir
iex> true or false
true
iex> false or 30
30
iex> 30 or false
** (BadBooleanError) expected a boolean on left-side of "or", got: 30

iex> true and false
false
iex> false and true
false
iex> true and "hello"
"hello"
iex> false and "hello"
false
iex> "hello" and true
** (BadBooleanError) expected a boolean on the left-side of "and", got: 
"hello"

iex> not false 
true
iex> not true
false
```
### nil
Elixir also provides the concept of `nil`, to indicate the absence of a value and a set of logical operators that also manipulate `nil`: `||/2`, `&&/2` and `!/1`].
For these operators, `false` and `nil` are considered "falsy", all other values are considered "truthy".

```elixir
iex> nil || true
true
iex> false || nil
nil
iex> nil || false
false
iex> nil || 1
1
iex> 1 || nil
1

iex> nil && 13
nil
iex> 13 && nil
nil
iex> nil && false
nil
iex> false && nil
false

iex> !nil
true
```

### Atoms
An atom is a constant whose value is its name. Some other languages call these symbols. 
They are often useful to enumerate over distinct values Often they are used to express the state of an operation, by using values such as `:ok` and `:error`.
Atoms are equal if their names are equal and Elixir allows you to skip the leading `:` for the atoms `false`, `true`, and `nil`.

```elixir
iex> :apple
:apple
iex> :banana
:banana

iex> :apple ==:apple
true
iex> :apple == :banana
false

iex> true == :true
true
iex> is_atom(false)
true
iex> is_atom(:false)
true
```

### String
Strings in Elixir are UTF-8 encoded binaries.
It is a sequence of Unicode characters, typically written between double quoted strings, such as `"hello"` and `"héllò"`.
And you can use the binary concatenation operator `<>/2`. Concatenates two binaries.
If one of the sides isn't binaries, will raise an `ArgumentError`

```elixir
iex> "hello"
hello

iex> "hello" <> "world"
"helloworld"
iex> "hello " <> "world"
"hello world"

iex(1)> "foo" <> x = "foobar"
"foobar"
iex(2)> x
"bar"

iex> x <> "bar" = "foobar"
(ArgumentError) cannot perform prefix match because the left operand of <> has an unknown size
```

Elixir supports string interpolation on both sides and supports any data type that may be converted to a string and can have line breaks in them using escape

```elixir
iex(1)> string = "world"
iex(2)> "hello #{string}!"
 "hello world!"

iex(1)> string = "Hello"
iex(2)> "#{string} world!"
"Hello world!"

iex(1)> number = 24
iex(2)> "i am #{number} years old!"
"i am 24 years old!"

iex(1)> "hello
...(1)>  world"
"hello\nworld"
iex> "hello\nworld"
"helo\nworld"
```

You can use `IO.puts/1`.
This function is from the IO module, the IO function handling input/output (IO).
Notice that the `IO.puts/1` function returns the atom `:ok` after printing.

```elixir
iex> IO.pust("hello\nword")
hello
world
:ok
```

Strings in Elixir are represented internally by contiguous sequences of bytes known as binaries and we can get the number of bytes a string

```elixir
iex> is_binary("hello")
true
iex> is_binary("hellö")
true

iex> byte_size("hello")
5
iex> byte_size("hellö")
6
```
* Notice that the number of bytes in that string is 6, even though it has 5 graphemes. That's because the grapheme "ö" takes 2 bytes to be represented in UTF-8. 
We can get the actual length of the string, based on the number of graphemes, by using the `String.length/1` function will return the number of Unicode graphemes in a UTF-8 string.

```elixir
iex> String.length("hello")
5
iex> String.length("hellö")
5
iex> String.length("涼涼")
2
```

The [`String`]module contains a bunch of functions that operate on strings as defined in the Unicode standard like `downcase/2` and `upcase/2`.
The `downcase/2` gives string to lowercase according to `mode`  and `upcase/2` gives string to uppercase according to `mode`.

```elixir
iex> String.downcase("ABCD")
"abcd"
iex> String.downcase("AB 123 XPTO")
"ab 123 xpto"
iex> String.downcase("OLÁ")
"olá"
iex> String.upcase("abcd") 
"ABCD" 
iex> String.upcase("ab 123 xpto") 
"AB 123 XPTO" 
iex> String.upcase("olá") 
"OLÁ"
```

### Predicate function
We work with different data types, we will learn Elixir provides several predicate functions to check for the type of a value.
For example, the `is_integer` can be used to check if a value is an integer or not.
If you want to know other the predicate functions you can check the below link 👇
[Other the predicate functions](https://hexdocs.pm/elixir/Kernel.html#guards)

```elixir
is_integer(1)
true
is_integer(2.0)
false
```

### Structural comparison
Elixir also provides `==`, `!=`, `<=`, `>=`, `<` and `>` as comparison operators. We can compare numbers but also atoms, string, and booleans can do.
Integers and floats compare the same if they have the same value but if you use the strict comparison operator `===` and `!==` if you want to distinguish between integers and floats they are different.

```elixir
iex> 1 == 1 
true 
iex> 1 != 2 
true 
iex> 1 < 2 
true
iex> "foo" == "foo"
true
iex> "foo" == "bar"
false

iex> 1 == 1.0
true
iex> 1 == 2.0
false
iex> 1 === 1.0
false
```
The comparison operators in Elixir can compare across any data type. We say these operators perform _structural comparison_.
For more information, you can click below link 👇
[Structural vs Semantic comparisons](https://hexdocs.pm/elixir/Kernel.html#module-structural-comparison).

### Other tips
Elixir also supports shortcut notations for entering binary, octal, and hexadecimal numbers:

```elixir
iex> 0b1010
10
iex> 0o777
511
iex> 0x1F
31
```

Float numbers require a dot followed by at least one digit and also support `e` for scientific notation:

```elixir
iex> 1.0
1.0
iex> 1.0e-10
1.0e-10
```

This wraps up today's introduction to basic data types. If you haven't read the previous article, [How to get start Elixir](https://dev.to/rhaenyraliang/how-to-get-start-elixir-3l65), go give it a read. Our next article will delve into lists and tuples as data types. Make sure not to miss it. See you next time, bye!