Documentação da Linguagem Potigol
This project is maintained by potigol
Em Potigol, listas são estruturas de dados fundamentais que permitem armazenar e manipular coleções ordenadas de elementos.
[2, 4, 6, 8, 10]
2 :: [4, 6, 8, 10]
→ [2, 4, 6, 8, 10]
Lista(5, 0)
→ [0, 0, 0, 0, 0]
Lista.vazia[Inteiro]
→ []
Método/Operação | Exemplo | Resultado | Descrição |
---|---|---|---|
.tamanho |
[2,4,6,8,10].tamanho |
5 |
Retorna o número de elementos |
.cabeça |
[2,4,6,8,10].cabeça |
2 |
Primeiro elemento da lista |
.cauda |
[2,4,6,8,10].cauda |
[4,6,8,10] |
Lista sem o primeiro elemento |
.último |
[2,4,6,8,10].último |
10 |
Último elemento da lista |
Acesso por índice | a[3] |
6 (índices começam em 1) |
As listas são imutáveis por padrão, o que significa que qualquer operação de modificação resulta em uma nova lista, mantendo a original inalterada. Isso garante que as estruturas de dados sejam seguras e consistentes.
Seja a = [2, 4, 6, 8, 10]
a.remova(4)
→ [2, 4, 6, 10]
(remove o elemento na posição 4)a.insira(3,5)
→ [2, 4, 5, 6, 8, 10]
(insere 5
na posição 3)a.atualize(3,5)
→ [2, 4, 5, 8, 10]
(alterar o valor da posição 3)a.contém(6)
→ verdadeiro
Abaixo estão exemplos de como manipular elementos em listas:
Quando você deseja modificar um elemento específico de uma lista, a operação não altera a lista original, mas cria uma nova lista com a modificação aplicada.
var a := [1, 2, 3, 4]
b = a
a := a.atualize(3, 5) # Atualiza o elemento na posição 3 para o valor 5
escreva a # [1, 2, 5, 4]
escreva b # [1, 2, 3, 4] (a lista original permanece inalterada)
Neste exemplo:
a.atualize(3, 5)
cria uma nova lista onde o elemento na posição 3 é substituído por 5
.b
permanece inalterada, demonstrando a imutabilidade.[ ] :=
Em Potigol, o conceito de açúcar sintático se refere a uma sintaxe simplificada e mais intuitiva que facilita a escrita e a leitura do código, sem alterar a funcionalidade subjacente. No caso da manipulação de listas, a expressão:
a[3] := 5
é um açúcar sintático para a operação:
a := a.atualize(3, 5)
a[3] := 5
: Essa sintaxe sugere que estamos “atualizando” o valor na posição 3 da lista a
para 5
. No entanto, como as listas são imutáveis, essa operação não modifica a lista original. Em vez disso, ela cria uma nova lista com o valor atualizado e a atribui à variável a
.a := a.atualize(3, 5)
: Essa é a forma explícita da operação. O método .atualize
cria uma nova lista com o valor na posição 3 substituído por 5
, e o resultado é atribuído de volta à variável a
.a[3] := 5
é mais curta e intuitiva, especialmente para quem está acostumado com operações de atualização em listas mutáveis.[ ] :=
var a := [1, 2, 3, 4]
a[3] := 5 # Açúcar sintático para a := a.atualize(3, 5)
escreva a # [1, 2, 5, 4]
Neste exemplo:
a[3] := 5
cria uma nova lista [1, 2, 5, 4]
e a atribui à variável a
.[1, 2, 3, 4]
não é modificada, mas deixa de ser referenciada por a
.Para inserir um elemento em uma posição específica, a operação também gera uma nova lista.
var a := [1, 2, 3, 4]
b = a
a := a.insira(2, 10) # Insere o valor 10 na posição 2
escreva a # [1, 10, 2, 3, 4]
escreva b # [1, 2, 3, 4] (a lista original permanece inalterada)
A remoção de um elemento também resulta em uma nova lista, sem afetar a original.
var a := [1, 2, 3, 4]
b = a
a := a.remova(2) # Remove o elemento na posição 2
escreva a # [1, 3, 4]
escreva b # [1, 2, 3, 4] (a lista original permanece inalterada)
A concatenação de listas também cria uma nova lista, sem modificar as originais.
var a := [1, 2, 3]
var b := [4, 5, 6]
c = a + b # Concatena as listas a e b
escreva c # [1, 2, 3, 4, 5, 6]
escreva a # [1, 2, 3] (a lista original permanece inalterada)
escreva b # [4, 5, 6] (a lista original permanece inalterada)
Essa abordagem funcional torna Potigol uma linguagem robusta para manipulação de dados, especialmente em cenários onde a imutabilidade é essencial.
Método | Exemplo | Resultado | Descrição |
---|---|---|---|
.inverta |
[2,4,6,8,10].inverta |
[10,8,6,4,2] |
Inverte a ordem |
.ordene |
[2,6,8,10,4].ordene |
[2,4,6,8,10] |
Ordenação padrão |
.ordene customizado |
[1,15,2,...].ordene(- _) |
[40,15,10,2,2,1] |
Ordenação decrescente usando lambda - _ |
.junte |
[2,4,6].junte(", ") |
"2, 4, 6" |
Concatena elementos com separador |
[2,4,6] + [8,10]
→ [2,4,6,8,10]
[2,4,6,8,10].descarte(2)
→ [6,8,10]
(remove os primeiros 2 elementos)[2,4,6,8,10].pegue(2)
→ [2,4]
(pega os primeiros 2 elementos)Método | Exemplo | Resultado | Descrição |
---|---|---|---|
.selecione |
[2,4,6,8,10].selecione(n => n mod 4 == 0) |
[4,8] |
Filtra elementos que satisfazem a condição |
.mapeie |
[2,4,6,8,10].mapeie(n => n div 2) |
[1,2,3,4,5] |
Transforma cada elemento |
.injete |
[2,4,6].injete(0)((a,b) => a + b) |
12 |
Acumula valores (equivalente a reduce ) |
a = [[1,2], [3,4]]
a[2][1]
→ 3
Cubo.imutável(2,2,2,"-")
→ Estrutura 2x2x2 preenchida com "-"
a = Lista.mutável(5, 0)
→ [0,0,0,0,0].mutável
a[3] := 5
→ [0,0,5,0,0]
[2,2,3,3,3,6,5,6].divida_quando((a,b) => a <> b)
→ [[2,2],[3,3,3],[6],[5],[6]]
[[1], [10,10], ...].ordene(_.tamanho)
→ Ordena listas pelo tamanhoEm Potigol, listas de objetos são uma forma eficiente de gerenciar coleções de dados complexos, combinando a imutabilidade das listas com a flexibilidade de tipos personalizados. Abaixo está um exemplo prático de como criar, manipular e iterar sobre listas de objetos, utilizando o tipo Pessoa
definido pelo usuário:
Pessoa
Primeiro, definimos a estrutura do objeto Pessoa
com atributos e métodos:
tipo Pessoa
nome: Texto
email: Texto
ano_nascimento: Inteiro
idade() = 2025 - ano_nascimento
adulto() = idade >= 18
fim
nome
, email
, ano_nascimento
.idade()
: Calcula a idade com base no ano atual (2025 no exemplo).adulto()
: Retorna verdadeiro
se a idade for maior ou igual a 18.Usamos um loop para...gere
para ler dados e gerar a lista de objetos Pessoa
:
pessoas = para i de 1 até 5 gere
nome = leia_texto # Lê o nome do terminal
email = leia_texto # Lê o email do terminal
ano_nascimento = leia_inteiro # Lê o ano de nascimento
Pessoa(nome, email, ano_nascimento) # Cria um objeto Pessoa
fim
para...gere
: Gera uma lista com 5 objetos Pessoa
.leia_texto
/leia_inteiro
: Funções para entrada de dados (simuladas ou reais, dependendo do contexto).Podemos iterar sobre a lista e exibir os dados formatados:
para p em pessoas faça
imprima p.nome formato "%20s"
imprima p.email formato "%20s"
escreva p.idade formato "%3d"
fim
para...faça
: Itera sobre cada objeto p
na lista pessoas
.formato
: Formata os valores para alinhamento:
%20s
: Alinha o texto em 20 caracteres.%3d
: Alinha números inteiros em 3 dígitos.Saída esperada (exemplo):
João joao@email.com 25
Maria maria@email.com 30
José jose@email.com 42
Como as listas são imutáveis, qualquer operação retorna uma nova lista. Exemplos:
adultos = pessoas.selecione(p => p.adulto)
escreva "Adultos: {adultos.tamanho}"
emails = pessoas.mapeie(p => p.email)
escreva emails # ["joao@email.com", "maria@email.com", ...]
var pessoas := ...
# Altera a pessoa na posição 1
pessoas[1] := Pessoa("Nome da Pessoa", "oemail@email.com", 2005)
# Atualiza o email da pessoa na posição 2
pessoas[2] := Pessoa(pessoas[2].nome, "novo_email@teste", pessoas[2].ano_nascimento)
[2, 4, 6, 8, 10] # lista literal
2 :: [4, 6, 8, 10] # [2, 4, 6, 8, 10]
[2, 4, 6, 8, 10].tamanho # 5
[2, 4, 6, 8, 10].cabeça # 2
[2, 4, 6, 8, 10].cauda # [4, 6, 8, 10]
[2, 4, 6, 8, 10].último # 10
[2, 4, 6, 8, 10].pegue(2) # [2, 4]
[2, 4, 6, 8, 10].descarte(2) # [6, 8, 10]
[2, 4, 6, 8, 10].inverta # [10, 8, 6, 4, 2]
[2, 6, 8, 10, 4].ordene # [2, 4, 6, 8, 10]
[1, 15, 2, 10, 2, 40].ordene(- _) # [40, 15, 10, 2, 2, 1]
[[1], [10,10], [3,3],[40]].ordene(_.tamanho) # [[1], [40], [10, 10], [3, 3]]
[2, 4, 6] + [8, 10] # [2, 4, 6, 8, 10]
[2, 4, 6].junte # "246"
[2, 4, 6].junte(", ") # "2, 4, 6"
[2, 4, 6].junte("[", ", ", "]") # "[2, 4, 6]"
a = [2, 4, 6, 8, 10]
a[3] # 6
a.posição(6) # 3
a.posição(12) # 0
a.contém(6) # verdadeiro
a.contém(12) # falso
a.remova(4) # [2, 4, 6, 10]
a.insira(3,5) # [2, 4, 5, 6, 8, 10]
Lista.imutável(5, 0) # [0, 0, 0, 0, 0]
Lista.vazia[Inteiro] # [] - Lista vazia de inteiros
# Matrizes e Cubos
a = [[1, 2], [3, 4]] # Matriz 2x2
a[2] # [3, 4]
a[2][1] # 3
b = Matriz.imutável(2, 2, 0) # b == [[0, 0], [0, 0]]
c = Cubo.imutável(2, 2, 2, "-") # c == [[["-", "-"],["-", "-"]],[["-", "-"],["-", "-"]]]
c[1][2][1] # "-"
# Listas mutáveis
a = Lista.mutável(5, 0) # [0, 0, 0, 0, 0].mutável
a[3] := 5 # a == [0, 0, 5, 0, 0].mutável
# Funções de alta-ordem
[2, 4, 6, 8, 10].selecione(n => n mod 4 == 0) # [4, 8]
[2, 4, 6, 8, 10].mapeie(n => n div 2) # [1, 2, 3, 4, 5]
[2, 4, 6].injete(0)((a, b) => a + b) # 0 + 2 + 4 + 6 == 12
[2, 4, 6].injete((a, b: Inteiro) => a + b) # 2 + 4 + 6 == 12
[2, 4, 6, 2, 4].pegue_enquanto(n => n < 6) # [2, 4]
[2, 4, 6, 2, 4].descarte_enquanto(n => n < 6) # [6, 2, 4]
[2,2,3,3,3,6,5,6].divida_quando((a, b) => a <> b) # [[2,2],[3,3,3],[6],[5],[6]]