# 3. Funcoes & Objetos & Arrays

### **📋 ÍNDICE**

1. Funções em Elixir
2. Módulos e Visibilidade
3. Listas (Linked Lists)
4. Tuplas (Tuples)
5. Mapas (Maps)
6. Enum - O Coração da Manipulação de Coleções
7. Comparativo: Lista vs Tupla vs Mapa
8. Resumo Rápido

***

### 🔧 **1. FUNÇÕES EM ELIXIR**

#### **1.1 Definição de Funções (def e defp)**

```elixir
# Função pública (pode ser chamada de fora do módulo)
defmodule Calculadora do
  def soma(a, b) do
    a + b
  end
  
  # Função privada (apenas dentro do módulo)
  defp subtrai(a, b) do
    a - b
  end
  
  # Função com guard clause
  def maior_que_zero?(x) when x > 0, do: true
  def maior_que_zero?(_), do: false
  
  # Múltiplas cláusulas
  def fatorial(0), do: 1
  def fatorial(n) when n > 0 do
    n * fatorial(n - 1)
  end
end

Calculadora.soma(5, 3)      # 8
Calculadora.maior_que_zero?(10)  # true
Calculadora.fatorial(5)     # 120
```

#### **1.2 Funções Anônimas (Lambdas)**

```elixir
# Sintaxe básica
soma = fn a, b -> a + b end
soma.(3, 4)  # 7 (note o ponto!)

# Múltiplas cláusulas
saudacao = fn
  :ola, nome -> "Olá, #{nome}!"
  :tchau, nome -> "Até logo, #{nome}!"
  _, _ -> "Comando não reconhecido"
end

saudacao.(:ola, "Maria")    # "Olá, Maria!"
saudacao.(:tchau, "João")   # "Até logo, João!"

# Closures (acesso a variáveis externas)
mensagem = "Olá"
saudacao_personalizada = fn nome -> "#{mensagem}, #{nome}!" end
saudacao_personalizada.("Ana")  # "Olá, Ana!"
```

#### **1.3 Operador de Captura (&)**

```elixir
# Capturando operadores
soma = &(&1 + &2)
soma.(5, 3)  # 8

# Capturando funções existentes
dobro = &(&1 * 2)
dobro.(10)   # 20

# Capturando funções de módulos
mapear = &Enum.map(&1, &2)
mapear.([1, 2, 3], fn x -> x * 2 end)  # [2, 4, 6]

# Forma alternativa (menos comum)
soma_alternativa = &(+/2)
soma_alternativa.(4, 5)  # 9
```

#### **1.4 Parâmetros Padrão**

```elixir
defmodule Saudacao do
  def ola(nome, saudacao \\ "Olá") do
    "#{saudacao}, #{nome}!"
  end
  
  # Função cabeça (head) para múltiplas cláusulas com default
  def mensagem(nome, saudacao \\ "Olá", pontuacao \\ "!")
  def mensagem(nome, saudacao, pontuacao) do
    "#{saudacao}, #{nome}#{pontuacao}"
  end
end

Saudacao.ola("João")              # "Olá, João!"
Saudacao.ola("Maria", "Oi")       # "Oi, Maria!"
Saudacao.mensagem("Ana", "Oi", "?")  # "Oi, Ana?"
```

***

### 📦 **2. LISTAS (LINKED LISTS)**

#### **2.1 Características e Manipulação Básica**

```elixir
# Criação
lista_vazia = []
numeros = [1, 2, 3, 4, 5]
misturada = [1, "dois", :tres, {4, 5}]

# Tamanho (operação O(n))
length(numeros)  # 5

# Acesso ao primeiro elemento (head)
hd(numeros)      # 1

# Acesso ao restante (tail)
tl(numeros)      # [2, 3, 4, 5]

# Adicionar no início (mais eficiente - O(1))
nova_lista = [0 | numeros]   # [0, 1, 2, 3, 4, 5]

# Concatenar (operador ++)
[1, 2] ++ [3, 4]   # [1, 2, 3, 4]

# Remover elementos (operador --)
[1, 2, 3] -- [2]   # [1, 3] (remove PRIMEIRA ocorrência)
```

#### **2.2 Pattern Matching com Listas**

```elixir
# Desestruturação básica
[primeiro, segundo, terceiro] = [1, 2, 3]
primeiro   # 1
segundo    # 2

# Cabeça e cauda (head/tail)
[head | tail] = [1, 2, 3, 4]
head   # 1
tail   # [2, 3, 4]

# Vários elementos no início
[primeiro, segundo | resto] = [1, 2, 3, 4, 5]
primeiro   # 1
segundo    # 2
resto      # [3, 4, 5]

# Ignorar elementos
[_, segundo, _] = [1, 2, 3]
segundo  # 2

# Casamento exato
[1, 2, x] = [1, 2, 3]
# Se a lista não tiver 3 elementos, MatchError
```

#### **2.3 Listas vs Características de Desempenho**

```elixir
# Listas são otimizadas para operações no INÍCIO

# ✅ RÁPIDO - Adicionar no início: O(1)
# Lista original [2, 3, 4]
[1 | [2, 3, 4]]   # [1, 2, 3, 4]

# ❌ LENTO - Adicionar no final: O(n)
list = [1, 2, 3]
list ++ [4]   # Precisa percorrer toda a lista

# ❌ LENTO - Acesso por índice: O(n)
Enum.at([1, 2, 3, 4, 5], 3)  # 4 (precisa percorrer até o índice)

# ✅ RÁPIDO - Obter primeiro elemento: O(1)
hd(list)

# ❌ LENTO - Calcular tamanho: O(n)
length(list)  # Precisa percorrer toda a lista

# Comparação com tuplas (que veremos mais adiante)
tuple = {1, 2, 3, 4, 5}
elem(tuple, 3)  # O(1) - acesso direto!
tuple_size(tuple)  # O(1) - tamanho pré-calculado!
```

#### **2.4 Charlists (Listas de Caracteres)**

```elixir
# Charlists são listas de códigos Unicode
charlist = ~c"hello"
is_list(charlist)  # true
is_binary(charlist)  # false

# Convertendo para string
to_string(~c"hello")   # "hello"

# Convertendo string para charlist
to_charlist("hello")   # ~c"hello"

# Quando usar? Raramente - para compatibilidade com Erlang
# Em 99% dos casos, use strings normais (aspas duplas)
```

***

### 🎯 **3. TUPLAS (TUPLES)**

#### **3.1 Características Básicas**

```elixir
# Criação
tupla_vazia = {}
pessoa = {"João", 30, :masculino}
coordenadas = {10, 20}

# Tamanho (operação O(1) - pré-calculado)
tuple_size(pessoa)  # 3

# Acesso por índice (O(1) - acesso direto)
elem(pessoa, 0)  # "João"
elem(pessoa, 1)  # 30

# Atualização (retorna nova tupla)
nova_pessoa = put_elem(pessoa, 1, 31)
# {"João", 31, :masculino}
pessoa  # Original não muda ({"João", 30, :masculino})
```

#### **3.2 Pattern Matching com Tuplas**

```elixir
# Desestruturação básica
{nome, idade, genero} = {"Maria", 25, :feminino}
nome   # "Maria"
idade  # 25

# Ignorando elementos
{_, idade, _} = {"João", 30, :masculino}
idade  # 30

# Tuplas aninhadas
{cidade, {lat, lon}} = {"São Paulo", {-23.55, -46.63}}
cidade  # "São Paulo"
lat     # -23.55
lon     # -46.63

# Padrão comum: resultado de operação
{:ok, resultado} = {:ok, "sucesso"}
resultado  # "sucesso"

{:error, motivo} = {:error, "arquivo não encontrado"}
motivo     # "arquivo não encontrado"
```

#### **3.3 Tagged Tuples (Tuplas Etiquetadas)**

```elixir
# Padrão comum em Elixir/Erlang
{:ok, valor}    # Sucesso
{:error, razão} # Erro

# Exemplo prático
case File.read("config.txt") do
  {:ok, conteudo} -> "Arquivo lido: #{conteudo}"
  {:error, reason} -> "Erro: #{reason}"
end

# Outros exemplos de tagging
{:http, 200, "OK"}
{:person, "João", 30}
{:point, 10, 20}
{:result, [1, 2, 3], %{status: "completo"}}
```

***

### 🗺️ **4. MAPAS (MAPS)**

#### **4.1 Criação e Acesso**

```elixir
# Criando mapas
vazio = %{}
pessoa = %{"nome" => "João", "idade" => 30}
config = %{:host => "localhost", :port => 8080}

# Atalho para chaves do tipo átomo (sintaxe mais limpa)
config = %{host: "localhost", port: 8080}
# Equivalente a %{:host => "localhost", :port => 8080}

# Acesso
pessoa["nome"]     # "João"
config.host        # "localhost" (apenas para chaves átomo)
config[:port]      # 8080

# Acesso com valor padrão
Map.get(pessoa, "email", "não informado")  # "não informado"

# Pattern matching
%{nome: nome, idade: idade} = %{nome: "Maria", idade: 25, cidade: "SP"}
nome   # "Maria"
idade  # 25
```

#### **4.2 Manipulação de Mapas**

```elixir
# Adicionar/atualizar valores
pessoa = %{nome: "João", idade: 30}
# Atualização com operador |
nova_pessoa = %{pessoa | idade: 31}
# %{nome: "João", idade: 31, cidade: "SP"}    # ✅ ADICIONA cidade
# ⚠️ ERRO! Não pode adicionar novas chaves com este operador!

# Forma correta de adicionar:
Map.put(pessoa, :cidade, "SP")  # %{nome: "João", idade: 30, cidade: "SP"}

# Remover chave
Map.delete(pessoa, :idade)  # %{nome: "João"}

# Atualizar com função
Map.update(pessoa, :idade, 0, fn idade -> idade + 1 end)  # %{nome: "João", idade: 31}
Map.update(pessoa, :altura, 1.80, fn altura -> altura end)  # Adiciona com valor padrão

# Verificar presença de chave
Map.has_key?(pessoa, :nome)   # true
Map.has_key?(pessoa, :altura) # false
```

#### **4.3 Mapas vs Palavras-Chave (Keyword Lists)**

```elixir
# Keyword List (lista de tuplas)
opcoes = [timeout: 5000, retries: 3, debug: true]
# Forma completa: [{:timeout, 5000}, {:retries, 3}, {:debug, true}]

# Mapa
opcoes_map = %{timeout: 5000, retries: 3, debug: true}

# Diferenças:
# Keyword List:
#   - Permite chaves duplicadas
#   - Preserva ordem
#   - Acesso é O(n)
#   - Mais lento
#
# Mapa:
#   - Chaves únicas
#   - Ordem não preservada
#   - Acesso é O(1)
#   - Mais rápido

# Quando usar Keyword List:
# - Opções de funções (parâmetros opcionais)
# - Sintaxe mais antiga (compatibilidade com Erlang)
# - Quando você precisa de ordem ou chaves duplicadas

# Quando usar Map:
# - Armazenamento de dados estruturados
# - Quando performance é importante
# - Quando as chaves são conhecidas
```

***

### 🔄 **5. MÓDULOS E VISIBILIDADE**

#### **5.1 Estrutura de Módulos**

```elixir
defmodule Matematica do
  # Funções públicas
  def soma(a, b), do: a + b
  def multiplica(a, b), do: a * b
  
  # Funções privadas (apenas dentro do módulo)
  defp helper(valor), do: valor * 2
  
  # Funções exportadas via @spec (documentação)
  @spec divide(integer, integer) :: {:ok, float} | {:error, atom}
  def divide(_a, 0), do: {:error, :division_by_zero}
  def divide(a, b), do: {:ok, a / b}
  
  # Módulos aninhados
  defmodule Geometria do
    def area_quadrado(lado), do: lado * lado
  end
end

# Acessando módulos aninhados
Matematica.Geometria.area_quadrado(5)  # 25

# Alias (apelido) para módulos
defmodule Calculadora do
  alias Matematica, as: Calc
  alias Matematica.Geometria
  
  def test do
    Calc.soma(5, 3)           # 8
    Geometria.area_quadrado(4) # 16
  end
end
```

#### **5.2 Aliases, Imports e Uses**

```elixir
# Alias - atalho para módulo
alias Matematica.Geometria, as: Geo

# Import - traz funções para o escopo
import Matematica, only: [soma: 2, multiplica: 2]
import Matematica, except: [soma: 2]  # tudo menos soma

defmodule Exemplo do
  import IO, only: [puts: 1]
  import Enum, only: [map: 2]
  
  def executar do
    puts("Olá")
    map([1, 2, 3], &(&1 * 2))
  end
end

# Use - chama o macro __using__ do módulo (extensão comum)
defmodule MeuModulo do
  use GenServer  # Expande para:
  # require GenServer
  # GenServer.__using__([])
end
```

#### **5.3 Função vs Macro**

```elixir
# Função normal (executada em runtime)
defmodule ExemploFuncao do
  def log(msg) do
    IO.puts("LOG: #{msg}")
  end
end

# Macro (executada em compile-time)
defmodule ExemploMacro do
  defmacro log(msg) do
    IO.puts("LOG em compile-time: #{msg}")
    quote do
      IO.puts("LOG em runtime: #{unquote(msg)}")
    end
  end
end

# Isso imprime em compile-time e runtime
defmodule Teste do
  require ExemploMacro
  ExemploMacro.log("teste")
end
```

***

### 🔢 **6. ENUM - O CORAÇÃO DA MANIPULAÇÃO DE COLEÇÕES**

#### **6.1 Enum.map - Transformação**

```elixir
# Dobrar todos os valores
resultado = Enum.map([1, 2, 3, 4], fn x -> x * 2 end)
# [2, 4, 6, 8]

# Usando operador de captura
Enum.map([1, 2, 3, 4], &(&1 * 2))  # [2, 4, 6, 8]

# Extrair campos de mapas
usuarios = [%{nome: "João", idade: 30}, %{nome: "Maria", idade: 25}]
nomes = Enum.map(usuarios, & &1.nome)  # ["João", "Maria"]

# Transformar mapas em listas
mapa = %{a: 1, b: 2, c: 3}
Enum.map(mapa, fn {_chave, valor} -> valor * 2 end)  # [2, 4, 6]
Enum.map(mapa, fn {chave, valor} -> {chave, valor * 2} end)  # [a: 2, b: 4, c: 6]
```

#### **6.2 Enum.filter - Filtragem**

```elixir
# Números pares
pares = Enum.filter([1, 2, 3, 4, 5, 6], fn x -> rem(x, 2) == 0 end)
# [2, 4, 6]

# Usando operador de captura
Enum.filter([1, 2, 3, 4], &(&1 > 2))  # [3, 4]

# Filtrar mapas em lista de mapas
usuarios = [
  %{nome: "João", ativo: true},
  %{nome: "Maria", ativo: false},
  %{nome: "Pedro", ativo: true}
]
ativos = Enum.filter(usuarios, & &1.ativo)  # [%{nome: "João", ativo: true}, %{nome: "Pedro", ativo: true}]
```

#### **6.3 Enum.reduce - Agregação**

```elixir
# Soma de todos os elementos
soma = Enum.reduce([1, 2, 3, 4], 0, fn x, acc -> x + acc end)
# 10

# Produto de todos os elementos
produto = Enum.reduce([1, 2, 3, 4], 1, fn x, acc -> x * acc end)
# 24

# String concatenada
palavras = ["Elixir", "é", "incrível"]
frase = Enum.reduce(palavras, "", fn palavra, acc -> acc <> " " <> palavra end)
# " Elixir é incrível"

# Encontrar o maior valor
maior = Enum.reduce([10, 25, 5, 30, 15], fn x, acc -> if x > acc, do: x, else: acc end)
# 30
```

#### **6.4 Enum.sort e Enum.uniq**

```elixir
# Ordenação
numeros = [3, 1, 4, 1, 5, 9, 2]
Enum.sort(numeros)                     # [1, 1, 2, 3, 4, 5, 9]
Enum.sort(numeros, &(&1 > &2))        # [9, 5, 4, 3, 2, 1, 1] (decrescente)

# Ordenação de mapas
usuarios = [%{nome: "João", idade: 30}, %{nome: "Ana", idade: 25}, %{nome: "Zeca", idade: 35}]
por_idade = Enum.sort_by(usuarios, &(&1.idade))  # [%{idade: 25, nome: "Ana"}, ...]

# Remover duplicados
Enum.uniq([1, 2, 2, 3, 3, 3])  # [1, 2, 3]
Enum.uniq_by([-1, 1, -2, 2], &abs/1)  # [-1, -2] (primeiro encontrado para cada valor absoluto)

# Combinar operações
[1, 2, 3, 4, 5]
|> Enum.filter(&(&1 > 2))
|> Enum.map(&(&1 * 2))
|> Enum.sum()
# (3,4,5) -> (6,8,10) -> 24
```

#### **6.5 Stream - Versão Lazy do Enum**

```elixir
# Enum processa tudo de uma vez (eager)
# Stream processa sob demanda (lazy)

# Sem Stream (já calcula tudo)
resultado = 1..100_000
|> Enum.filter(&(&1 > 50_000))
|> Enum.map(&(&1 * 2))
|> Enum.take(5)  # Só quer 5 elementos, mas calculou todos!

# Com Stream (calcula só o necessário)
resultado = 1..100_000
|> Stream.filter(&(&1 > 50_000))
|> Stream.map(&(&1 * 2))
|> Enum.take(5)  # Calcula até ter 5 elementos

# Benefícios:
# 1. Performance melhor para grandes coleções
# 2. Pipeline infinito (trata listas infinitas)
# 3. Composição lazy

# Exemplo com lista infinita
numeros = Stream.iterate(0, &(&1 + 1))  # sequência infinita
primeiros_10_pares = numeros
|> Stream.filter(&(rem(&1, 2) == 0))
|> Enum.take(10)  # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
```

#### **6.6 Tabela de Funções Enum (Referência Rápida)**

| Função         | Descrição                    | Exemplo                                            |
| -------------- | ---------------------------- | -------------------------------------------------- |
| `map/2`        | Transforma cada elemento     | `Enum.map([1,2,3], &(&1*2))` → `[2,4,6]`           |
| `filter/2`     | Seleciona elementos          | `Enum.filter([1,2,3], &(&1>1))` → `[2,3]`          |
| `reduce/3`     | Acumula resultados           | `Enum.reduce([1,2,3], 0, &+/2)` → `6`              |
| `sort/1`       | Ordena elementos             | `Enum.sort([3,1,2])` → `[1,2,3]`                   |
| `uniq/1`       | Remove duplicados            | `Enum.uniq([1,2,2,3])` → `[1,2,3]`                 |
| `any?/2`       | Algum elemento atende?       | `Enum.any?([1,2,3], &(&1>2))` → `true`             |
| `all?/2`       | Todos elementos atendem?     | `Enum.all?([1,2,3], &(&1>0))` → `true`             |
| `count/2`      | Conta elementos que atendem  | `Enum.count([1,2,3], &(&1>1))` → `2`               |
| `find/2`       | Encontra primeiro que atende | `Enum.find([1,2,3], &(&1>1))` → `2`                |
| `take/2`       | Pega primeiros N             | `Enum.take([1,2,3,4], 2)` → `[1,2]`                |
| `drop/2`       | Descarta primeiros N         | `Enum.drop([1,2,3,4], 2)` → `[3,4]`                |
| `zip/2`        | Combina duas listas          | `Enum.zip([1,2], [:a,:b])` → `[{1,:a},{2,:b}]`     |
| `with_index/1` | Adiciona índice              | `Enum.with_index(["a","b"])` → `[{"a",0},{"b",1}]` |
| `join/2`       | Junta com separador          | `Enum.join(["a","b","c"], "-")` → `"a-b-c"`        |

***

### 📊 **7. COMPARATIVO: LISTA vs TUPLA vs MAPA**

#### **7.1 Tabela de Características**

| Característica            | Lista              | Tupla           | Mapa               |
| ------------------------- | ------------------ | --------------- | ------------------ |
| **Estrutura**             | Linked list        | Contígua        | Hash map           |
| **Tamanho**               | Dinâmico           | Fixo            | Dinâmico           |
| **Acesso por índice**     | O(n) lento         | O(1) rápido     | O(1) rápido        |
| **Adicionar início**      | O(1) rápido        | Criar nova      | O(1) rápido        |
| **Adicionar final**       | O(n) lento         | Criar nova      | O(1) rápido        |
| **Busca por chave**       | O(n)               | O(n)            | O(1)               |
| **Tamanho (length/size)** | O(n)               | O(1)            | O(1)               |
| **Ordenação**             | Sim                | Não             | Não mantém ordem   |
| **Chaves duplicadas**     | Sim                | N/A             | Não                |
| **Uso típico**            | Coleções dinâmicas | Fixas, pequenas | Dados estruturados |

#### **7.2 Quando Usar Cada Tipo**

```elixir
# ✅ LISTA: Tamanho variável, processamento sequencial
usuarios_online = []  # Começa vazio
usuarios_online = ["João" | usuarios_online]  # Adiciona no início

# ✅ LISTA: Quando você vai modificar frequentemente
cache = []  # Lista de resultados recentes

# ✅ TUPLA: Conjunto de valores fixos de diferentes tipos
pessoa = {"João", 30, "joao@email.com"}

# ✅ TUPLA: Retorno de funções (tagged tuple)
File.read("arquivo.txt")  # {:ok, conteudo} ou {:error, reason}

# ✅ MAPA: Dados estruturados com chave/valor
usuario = %{nome: "Maria", idade: 25, email: "maria@email.com"}

# ✅ MAPA: Configurações, opções, JSON
config = %{host: "localhost", port: 8080, debug: true}
```

#### **7.3 Exemplo Prático Integrado**

```elixir
defmodule Sistema do
  # Estrutura de dados do sistema
  defstruct usuarios: [], config: %{}, stats: {0, 0, 0}
  
  def inicializar do
    %Sistema{
      usuarios: [],
      config: %{timeout: 5000, max_usuarios: 100},
      stats: {0, 0, 0}  # {ativos, inativos, total}
    }
  end
  
  def adicionar_usuario(sistema, nome, idade) do
    # Atualiza lista (O(1))
    novos_usuarios = [%{nome: nome, idade: idade} | sistema.usuarios]
    
    # Atualiza tupla de estatísticas
    {ativos, inativos, total} = sistema.stats
    novas_stats = {ativos + 1, inativos, total + 1}
    
    %{sistema | usuarios: novos_usuarios, stats: novas_stats}
  end
  
  def listar_ativos(sistema) do
    sistema.usuarios
    |> Enum.filter(&(&1.idade >= 18))  # Filtro
    |> Enum.map(& &1.nome)              # Transformação
    |> Enum.join(", ")                  # Agregação
  end
end
```

***

### 🎯 **8. RESUMO RÁPIDO**

#### **8.1 Dicas de Performance**

```elixir
# ✅ Use tuplas para dados fixos
pessoa = {"João", 30}

# ✅ Use listas para coleções que crescem pelo início
[novo | lista_antiga]

# ✅ Use mapas para dados estruturados
config = %{host: "localhost", port: 8080}

# ❌ Evite repetir concatenação no final
resultado = []
Enum.each(1..1000, fn x ->
  resultado = resultado ++ [x]  # MUITO LENTO!
end)

# ✅ Prefira Enum.map, reduce, etc.
Enum.map(1..1000, fn x -> x end)  # RÁPIDO

# ❌ Evite acessar listas por índice repetidamente
Enum.each(0..length(lista)-1, fn i ->
  elem = Enum.at(lista, i)  # O(n) cada acesso!
end)

# ✅ Use Enum.reduce ou pattern matching
Enum.reduce(lista, fn elem, acc -> ... end)
```

#### **8.2 Exemplos de Pipeline (Chaining)**

```elixir
# Exemplo de ETL processamento com pipes
dados
|> Enum.filter(&valid?/1)
|> Enum.map(&transformar/1)
|> Enum.sort()
|> Enum.take(10)
|> Enum.join(", ")

# Extrair emails de usuários ativos
usuarios
|> Enum.filter(& &1.ativo)
|> Enum.map(& &1.email)
|> Enum.uniq()
|> Enum.join("; ")
```

#### **8.3 Palavras Finais**

```yaml
RESUMO:
  - LISTA: Use para coleções dinâmicas que crescem e diminuem
  - TUPLA: Use para dados fixos com poucos elementos
  - MAPA: Use para dados estruturados com chaves nomeadas
  - ENUM: A principal API para manipular coleções
  - STREAM: Use para processamento lazy de grandes volumes

DICA DE OURO:
  Elixir favorece transformação de dados via pipelines
  com Enum e Stream - evite loops manuais!
```

***

**🔐 Lembre-se: Em Elixir, a imutabilidade é uma aliada: transforme seus dados, não os modifique!**


---

# 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/3.-funcoes-and-objetos-and-arrays.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.
