# 1. Variaveis

### **📋 ÍNDICE**

1. Visão Geral
2. Tipos Básicos
3. Operadores Aritméticos
4. Booleanos e nil
5. Átomos (Symbols)
6. Strings
7. Comparação Estrutural
8. Pattern Matching
9. O Operador Pin (^)
10. Resumo Rápido

***

### 🔍 **1. VISÃO GERAL**

#### **1.1 O que são Variáveis em Elixir?**

**DEFINIÇÃO:** Em Elixir, variáveis são referências a valores imutáveis armazenados na memória. Diferente de linguagens imperativas, você não "modifica" uma variável; você a "rebinde" a um novo valor.

**CARACTERÍSTICAS:**

* Imutabilidade: Uma vez atribuído, o valor não muda
* Rebind: Você pode associar a variável a um novo valor
* Case-sensitive: `nome` é diferente de `Nome`
* Snake Case: Convenção para nomes de variáveis (ex: `usuario_logado`)
* Sem tipagem estática: O tipo é inferido em tempo de execução

**EXEMPLOS:**

```elixir
  nome = "João"        # binding: nome -> "João"
  idade = 25           # binding: idade -> 25
  nome = "Maria"       # rebind: nome agora aponta para "Maria"
```

#### **1.2 Imutabilidade na Prática**

```elixir
# Em Elixir, os valores são imutáveis
lista = [1, 2, 3]
nova_lista = [0 | lista]  # Isso cria uma NOVA lista

IO.inspect(lista)      # [1, 2, 3] - original permanece inalterado!
IO.inspect(nova_lista) # [0, 1, 2, 3]

# O mesmo vale para strings e outros tipos
texto = "Hello"
novo_texto = String.upcase(texto)

IO.inspect(texto)      # "Hello" - original permanece!
IO.inspect(novo_texto) # "HELLO"
```

#### **1.3 Nomenclatura e Convenções**

```elixir
# ✅ Convenções corretas
nome_usuario = "joao"
idade_pessoa = 30
lista_compras = ["pão", "leite", "ovos"]
funcao_privada = fn -> :ok end

# ❌ Evitar
NomeUsuario = "joao"     # Módulos usam PascalCase
idade_pessoa! = 30       # ! é usado para funções com efeitos colaterais
$valor = 100             # Caracteres especiais não são permitidos
```

***

### 📊 **2. TIPOS BÁSICOS**

#### **2.1 Inteiros (Integers)**

```elixir
# Inteiros em diferentes bases
1          # decimal
0x1F       # hexadecimal (31)
0b1010     # binário (10)
0o777      # octal (511)

# Operações com inteiros
10 + 5     # 15
10 - 5     # 5
10 * 5     # 50

# Divisão inteira retorna float!
10 / 2     # 5.0 (NÃO é 5)

# Para divisão inteira, use div/2
div(10, 2)   # 5
div 10, 2    # 5 (parênteses opcionais)

# Resto da divisão
rem(10, 3)   # 1
rem 10, 3    # 1

# Predicados de tipo
is_integer(10)   # true
is_integer(10.0) # false
is_number(10)    # true
is_number(10.0)  # true
```

#### **2.2 Floats (Números de Ponto Flutuante)**

```elixir
# Representação
1.0        # float
1.0e-10    # notação científica (1.0 × 10⁻¹⁰)
3.14159    # pi aproximado

# Precisão: 64-bit (IEEE 754)

# Operações
1.0 + 2.0  # 3.0
10 / 2     # 5.0 (sempre retorna float)

# Arredondamento
round(3.58)   # 4
round(3.49)   # 3

# Truncamento
trunc(3.58)   # 3
trunc(3.49)   # 3

# Predicados
is_float(3.14)   # true
is_float(10)     # false
is_number(3.14)  # true
```

#### **2.3 Tabela de Predicados por Tipo**

| Tipo         | Predicado      | Exemplo Verdadeiro                   | Exemplo Falso       |
| ------------ | -------------- | ------------------------------------ | ------------------- |
| **Inteiro**  | `is_integer/1` | `is_integer(42)`                     | `is_integer(3.14)`  |
| **Float**    | `is_float/1`   | `is_float(3.14)`                     | `is_float(42)`      |
| **Número**   | `is_number/1`  | `is_number(42)` ou `is_number(3.14)` | `is_number("42")`   |
| **Booleano** | `is_boolean/1` | `is_boolean(true)`                   | `is_boolean(1)`     |
| **Átomo**    | `is_atom/1`    | `is_atom(:ok)`                       | `is_atom("ok")`     |
| **String**   | `is_binary/1`  | `is_binary("hello")`                 | `is_binary(123)`    |
| **Lista**    | `is_list/1`    | `is_list([1,2,3])`                   | `is_list({1,2,3})`  |
| **Tupla**    | `is_tuple/1`   | `is_tuple({1,2,3})`                  | `is_tuple([1,2,3])` |

***

### ➗ **3. OPERADORES ARITMÉTICOS**

#### **3.1 Operadores Básicos**

```elixir
# Operadores padrão
1 + 2   # 3   (adição)
5 - 3   # 2   (subtração)
4 * 3   # 12  (multiplicação)
10 / 2  # 5.0 (divisão - sempre retorna float!)

# Divisão inteira
div(10, 3)   # 3
div 10, 3    # 3 (sem parênteses)

# Resto da divisão (módulo)
rem(10, 3)   # 1
rem 10, 3    # 1
```

#### **3.2 Operadores Especiais**

```elixir
# Exponenciação (através de função)
# Nota: Elixir não tem operador **, use :math.pow/2
:math.pow(2, 3)   # 8.0

# Precedência de operadores
2 + 3 * 4    # 14 (multiplicação primeiro)
(2 + 3) * 4  # 20 (parênteses alteram precedência)

# Operador de concatenação de strings
"Hello " <> "World"  # "Hello World"
```

#### **3.3 Shorthands Numéricos**

```elixir
# Binário (prefixo 0b)
0b1010   # 10
0b1111   # 15

# Octal (prefixo 0o)
0o777    # 511
0o644    # 420

# Hexadecimal (prefixo 0x)
0x1F     # 31
0xFF     # 255
0xDEAD   # 57005
```

***

### 🎯 **4. BOOLEANOS E NIL**

#### **4.1 Booleanos**

```elixir
# Valores booleanos
true
false

# Operadores booleanos (estritos - exigem booleanos)
true and true   # true
true and false  # false
false or true   # true
not true        # false

# Estes operadores são short-circuit (curto-circuito)
false and raise("Nunca executado")  # false
true or raise("Nunca executado")    # true

# ⚠️ Cuidado: operadores estritos exigem booleanos!
true and 1
# ** (BadBooleanError) expected a boolean on left-side of "and", got: 1
```

#### **4.2 Operadores Truthy**

```elixir
# Operadores que aceitam valores "truthy" e "falsy"
# Falsy: false e nil
# Truthy: todos os outros valores (incluindo 0, "", [], etc.)

# OR (||) - retorna o primeiro valor truthy
1 || true        # 1
false || 11      # 11
nil || "padrão"  # "padrão"

# AND (&&) - retorna o segundo valor se o primeiro for truthy
true && 17       # 17
1 && 2           # 2
false && 10      # false
nil && "x"       # nil

# NOT (!) - inverte truthy/falsy
!true            # false
!1               # false (1 é truthy)
!false           # true
!nil             # true
```

#### **4.3 nil (Ausência de Valor)**

```elixir
# nil representa a ausência de valor
nil
is_nil(nil)      # true
is_nil("")       # false (string vazia NÃO é nil)

# nil é considerando falsy
if nil do
  "não executado"
else
  "executado"
end
# "executado"

# nil em pattern matching
case Enum.fetch([1, 2, 3], 5) do
  {:ok, valor} -> "Encontrado: #{valor}"
  :error -> "Elemento não existe"
end
# "Elemento não existe"
```

#### **4.4 Tabela de Truthy/Falsy**

\| Valor | Boolean Operator (and/or/not) | Truthy Operator (&&/||/!) | |:------|:------------------------------|:--------------------------| | `true` | ✅ Válido | ✅ Truthy | | `false` | ✅ Válido | ❌ Falsy | | `nil` | ❌ Inválido (erro) | ❌ Falsy | | `0` | ❌ Inválido (erro) | ✅ Truthy | | `""` | ❌ Inválido (erro) | ✅ Truthy | | `[]` | ❌ Inválido (erro) | ✅ Truthy | | `%{}` | ❌ Inválido (erro) | ✅ Truthy |

```elixir
# Regra prática:
# - Use `and`, `or`, `not` quando esperar booleanos EXPLÍCITOS
# - Use `&&`, `||`, `!` quando puder ter outros valores

# Exemplo prático: valor padrão
config = nil
valor_final = config || "valor_padrao"  # "valor_padrao"
```

***

### 🔷 **5. ÁTOMOS (SYMBOLS)**

#### **5.1 O que são Átomos?**

```elixir
# Átomos são constantes cujo valor é o próprio nome
:apple
:orange
:watermelon

# Comparação de átomos
:apple == :apple    # true
:apple == :orange   # false

# Booleanos são átomos especiais
true == :true       # true
false == :false     # true
is_atom(true)       # true
is_boolean(:true)   # true (!!)
```

#### **5.2 Uso Comum de Átomos**

```elixir
# Representando estado de operações
case resultado_da_api do
  {:ok, data} -> "Sucesso: #{data}"
  {:error, reason} -> "Erro: #{reason}"
end

# Valores de configuração
status = :active
role = :admin
priority = :high

# Em mapas como chaves (otimizado)
user = %{
  name: "João",
  age: 30,
  status: :active
}

# Acessando com átomo
user.name    # "João"
user[:name]  # "João"
```

#### **5.3 Átomos Especiais**

```elixir
# true e false são átomos
true == :true
false == :false

# nil também é átomo
nil == :nil

# Elixir permite omitir o : para esses átomos
is_boolean(:true)   # true
is_boolean(true)    # true (mesma coisa)

# Criação dinâmica de átomos (use com cuidado!)
:"um átomo qualquer"
:"usuario_#{123}"
String.to_atom("criado_dinamicamente")

# ⚠️ Átomos não são garbage collected!
# Criar átomos dinamicamente em excesso pode causar memory leak
```

***

### 📝 **6. STRINGS**

#### **6.1 Strings Básicas**

```elixir
# Strings são delimitadas por aspas duplas
"Elixir"
"Olá, mundo!"

# Suporte a UTF-8
"Hello"        # Inglês
"Olá"          # Português
"こんにちは"    # Japonês

# Strings são binaries (sequências de bytes)
is_binary("Hello")   # true

# Tamanho em bytes vs caracteres
byte_size("Olá")     # 4 (O = 1, l = 1, á = 2)
String.length("Olá") # 3 (O, l, á)
```

#### **6.2 Interpolação**

```elixir
# Interpolação de variáveis
nome = "Maria"
idade = 25
"Meu nome é #{nome} e tenho #{idade} anos"
# "Meu nome é Maria e tenho 25 anos"

# Interpolação com expressões
"5 + 5 = #{5 + 5}"     # "5 + 5 = 10"
"#{String.upcase(nome)}"  # "MARIA"

# Qualquer expressão pode ser interpolada
"Data: #{Date.utc_today()}"   # "Data: 2024-01-15"
```

#### **6.3 Concatenação**

```elixir
# Operador <>
"Hello " <> "World"    # "Hello World"

# Concatenação com strings literais
prefixo = "pre-"
prefixo <> "fixo"      # "pre-fixo"

# ⚠️ Ambos os lados devem ser strings!
"Hello " <> 123
# ** (ArgumentError) expected binary argument in <> operator but got 123
```

#### **6.4 Escape Sequences**

```elixir
# Caracteres especiais
"Linha 1\nLinha 2"     # newline
"Coluna1\tColuna2"     # tab
"Texto entre \"aspas\"" # aspas duplas
"Barra invertida \\"   # backslash

# Unicode
"\u00F6"               # "ö"
"\u{1F600}"            # 😀 (emoji)

# Impressão com quebras de linha
IO.puts("Hello\nWorld")
# Hello
# World
# :ok
```

#### **6.5 Funções Comuns do Módulo String**

```elixir
# Case conversion
String.upcase("hello")    # "HELLO"
String.downcase("WORLD")  # "world"
String.capitalize("elixir") # "Elixir"

# Manipulação
String.length("hello")    # 5
String.trim("  hello  ")  # "hello"
String.reverse("hello")   # "olleh"

# Busca
String.contains?("hello", "ell")   # true
String.starts_with?("hello", "he") # true
String.ends_with?("hello", "lo")   # true

# Split e Join
String.split("a,b,c", ",")     # ["a", "b", "c"]
String.join(["a", "b", "c"], "-") # "a-b-c"

# Extração
String.slice("hello", 0..2)    # "hel"
String.first("hello")          # "h"
String.last("hello")           # "o"
```

***

### ⚖️ **7. COMPARAÇÃO ESTRUTURAL**

#### **7.1 Operadores de Comparação**

```elixir
# Igualdade padrão (==)
1 == 1        # true
1 == 2        # false
1 == 1.0      # true (diferentes tipos, mesmo valor numérico)

# Igualdade estrita (===) - distingue tipos
1 === 1        # true
1 === 1.0      # false! (int vs float)

# Desigualdade (!= e !==)
1 != 2         # true
1 !== 1.0      # true (diferentes tipos)

# Comparação de ordem
1 < 2          # true
2 > 1          # true
2 <= 2         # true
3 >= 2         # true
```

#### **7.2 Comparação Entre Tipos Diferentes**

```elixir
# Elixir permite comparar tipos diferentes!
# A ordem de "grandeza" dos tipos é definida:

# number < atom < reference < function < port < pid < tuple < map < list < bitstring

1 < :atom           # true (number < atom)
:atom < "string"    # true (atom < string)
"string" < [1,2,3]  # true (string < list)
[1] < [1,2]         # true (lista menor)
```

#### **7.3 Comparação vs Pattern Matching**

```elixir
# Comparação usa operadores (==, !=, <, >)
if x == 10 do
  IO.puts("x é 10")
end

# Pattern Matching usa operador =
case x do
  10 -> IO.puts("x é 10")
  _ -> IO.puts("x não é 10")
end
```

***

### 🎭 **8. PATTERN MATCHING**

#### **8.1 O Operador de Match (=)**

```elixir
# O = não é atribuição, é MATCH!
# Ele tenta fazer o lado direito "casar" com o lado esquerdo

x = 1        # x agora vale 1
1 = x        # 1 = 1 -> OK
2 = x        # 2 = 1 -> ** (MatchError)

# Variável no lado esquerdo sempre casa e recebe o valor
# Valor no lado esquerdo só casa se for igual
```

#### **8.2 Destructuring Tuplas**

```elixir
# Destructuring básico
{a, b, c} = {:hello, "world", 42}
a   # :hello
b   # "world"
c   # 42

# Matching com valores específicos
{:ok, resultado} = {:ok, 13}
resultado   # 13

{:ok, resultado} = {:error, :oops}
# ** (MatchError) no match of right hand side value: {:error, :oops}

# Ignorando valores com _
{_, resultado} = {:ok, "sucesso"}
resultado   # "sucesso"

# Matching com elementos repetidos
{x, x, y} = {1, 1, 2}   # OK
{x, x, y} = {1, 2, 3}   # ** (MatchError) 1 != 2
```

#### **8.3 Destructuring Listas**

```elixir
# Lista com tamanho fixo
[primeiro, segundo, terceiro] = [1, 2, 3]
primeiro   # 1
segundo    # 2
terceiro   # 3

# Head | Tail (cabeça | resto)
[head | tail] = [1, 2, 3, 4, 5]
head   # 1
tail   # [2, 3, 4, 5]

# Multiplos heads
[first, second | rest] = [1, 2, 3, 4]
first   # 1
second  # 2
rest    # [3, 4]

# Ao contrário: construir lista com head | tail
nova_lista = [0 | [1, 2, 3]]   # [0, 1, 2, 3]
```

#### **8.4 Destructuring Maps**

```elixir
# Desestruturando maps
%{nome: nome, idade: idade} = %{nome: "João", idade: 30, cidade: "SP"}
nome    # "João"
idade   # 30

# Matching com valores específicos
%{status: :ok, data: data} = %{status: :ok, data: "resultado"}
data    # "resultado"

# Usando pin operator para matching em valores existentes
usuario = %{nome: "Maria", idade: 25}
%{idade: idade} = usuario
idade   # 25
```

***

### 📌 **9. O OPERADOR PIN (^)**

#### **9.1 Por que Precisamos do Pin?**

```elixir
# Sem pin, variáveis são sempre rebindadas
x = 1
x = 2      # OK - x agora é 2

# Às vezes queremos MATCH contra o valor atual, não rebind
x = 1
^x = 2     # ** (MatchError) no match of right hand side value: 2
```

#### **9.2 Uso Básico do Pin**

```elixir
# Pin no valor existente
x = 5
^x = 5      # OK
^x = 10     # ** (MatchError)

# Pin em estruturas
x = 1
[^x, y, z] = [1, 2, 3]   # OK, y = 2, z = 3
[^x, y, z] = [2, 2, 3]   # ** (MatchError)

# Pin em maps
config = %{port: 8080, host: "localhost"}
%{port: ^port} = config
port   # 8080 (pego do binding anterior)
```

#### **9.3 Exemplos Práticos**

```elixir
# Validando valores em case
expected = :ok
case resultado do
  ^expected -> IO.puts("Operação bem-sucedida!")
  _ -> IO.puts("Falhou!")
end

# Matching em função com pin
x = 10
case [1, 2, 3] do
  [^x, _, _] -> "Primeiro é 10"
  _ -> "Primeiro não é 10"
end
# "Primeiro não é 10"

# Pin em compreensão de listas
chave = "a"
lista = [{"a", 1}, {"b", 2}, {"a", 3}]
for {^chave, valor} <- lista, do: valor
# [1, 3]
```

***

### 📋 **10. RESUMO RÁPIDO**

#### **10.1 Tabela de Tipos e Operadores**

| Tipo        | Exemplo           | Predicado      | Operações                            |
| ----------- | ----------------- | -------------- | ------------------------------------ |
| **Integer** | `42`, `0x1F`      | `is_integer/1` | `+`, `-`, `*`, `div/2`, `rem/2`      |
| **Float**   | `3.14`, `1.0e-10` | `is_float/1`   | `+`, `-`, `*`, `/` (sempre float)    |
| **Boolean** | `true`, `false`   | `is_boolean/1` | `and`, `or`, `not` (estritos)        |
| **Atom**    | `:ok`, `:error`   | `is_atom/1`    | Comparação (`==`)                    |
| **String**  | `"hello"`         | `is_binary/1`  | `<>` (concatenação), `String` módulo |
| **List**    | `[1, 2, 3]`       | `is_list/1`    | `++`, `--`, \`\[head                 |
| **Tuple**   | `{:ok, 42}`       | `is_tuple/1`   | `elem/2`, `put_elem/3`               |

#### **10.2 Dicas e Boas Práticas**

```elixir
# ✅ Prefira pattern matching a comparações
# Ao invés de:
if x == :ok do
  processar()
end

# Use:
case x do
  :ok -> processar()
  _ -> :ignore
end

# ✅ Use pin operator para evitar rebinds acidentais
valor_esperado = 10
^x = resultado

# ✅ Use _ para valores que você não precisa
[_, segundo, _] = lista

# ✅ Use módulo String para manipulação, não operadores
String.trim("  texto  ")  # ao invés de "texto"

# ⚠️ Cuidado com átomos dinâmicos
# String.to_atom(valor_usuario)  # risco de memory leak!

# ⚠️ Lembre-se: / sempre retorna float!
div(10, 2)  # para inteiro, use div/2

# ✅ Use `||` para valores padrão
config = variavel || "valor_padrao"
```

#### **10.3 Exemplo Completo**

```elixir
defmodule Exemplo do
  def processar_usuario(usuario) do
    # Pattern matching na função
    %{nome: nome, idade: idade} = usuario
    
    # Validação com case
    case idade do
      idade when idade >= 18 -> 
        "#{nome} é maior de idade"
      _ -> 
        "#{nome} é menor de idade"
    end
  end
  
  def executar do
    # Criando usuário
    usuario = %{
      nome: "João Silva",
      idade: 25,
      email: "joao@exemplo.com"
    }
    
    # Extraindo valor com pin
    email_esperado = "joao@exemplo.com"
    ^email_esperado = usuario.email
    
    # Processando
    processar_usuario(usuario)
    # "João Silva é maior de idade"
  end
end
```

***

### 📚 **REFERÊNCIAS**

```yaml
DOCUMENTAÇÃO OFICIAL:
  - Getting Started: https://elixir-lang.org/getting-started/
  - Basic Types: https://hexdocs.pm/elixir/basic-types.html
  - Pattern Matching: https://hexdocs.pm/elixir/pattern-matching.html

LEITURA RECOMENDADA:
  - "Programming Elixir" (Dave Thomas)
  - "Elixir in Action" (Sasa Juric)

PRÁTICA:
  - Exercism.io (track de Elixir)
  - CodeSignal (desafios de programação)
  - Advent of Code (resolver em Elixir)
```

***

**🔐 Lembre-se: Em Elixir, a imutabilidade não é uma limitação — é uma característica que elimina toda uma classe de bugs relacionados a estado compartilhado. Abrace o pattern matching, ele é uma das ferramentas mais poderosas da linguagem!**


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/conceitos/programacao-e-linguagens/elixir/1.-variaveis.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
