As Vinculações de armazenamento e tempo de vida
Por: Dayvson Sales • 2/7/2018 • Trabalho acadêmico • 2.929 Palavras (12 Páginas) • 322 Visualizações
Universidade Federal de Alagoas Instituto de Computação Dayvson Cassiano Sales
Elixir
Maceió 2017
Universidade Federal de Alagoas Instituto da Computação Dayvson Cassiano Sales
Elixir
Relatório referente ao Elixir, como critério de avaliação para a disciplina de CLP, ministrada pelo professor Alcino.
Maceió 2017
Introdução
Elixir é uma linguagem de programação de propósito geral, puramente funcional, dinamicamente tipada e com conceitos modernos, criada em cima da máquina virtual do Erlang por José Valim em 2012.
Aproveita-se das características do Erlang para fornecer aplicações distribuídas, em tempo real suave, tolerante a falhas, non-stop, mas também a estende para suportar metaprogramação com macros e polimorfismo via protocolos. É possível em código Elixir utilizar funções definidas em Erlang, mas é preciso deixar claro que Elixir e Erlang são duas linguagens diferentes.
Neste trabalho iremos discutir as características do Elixir na sua versão 1.5.1, com o Erlang/OTP 20.
SUMÁRIO
1. Nomes 6
2. Variáveis 6
3. Vinculações e Inferência de Tipo 6
3.1. Vinculações de atributos a variáveis 7
3.2. Vinculações de armazenamento e tempo de vida 7
4. Escopo 8
4.1.1. Tempo de Vida 8
4.1.2. Ambiente de Referenciamento 9
4.1.3. Constantes nomeadas 9
5. Tipos de Dados 10
5.1.1. Inteiro e Float 10
5.1.2. Booleanos 10
5.1.3. Strings 11
5.1.4. Listas 11
5.1.5. Tuplas 11
5.1.6. Atoms 12
5.2. Cadeia de caracteres 12
5.3. Tipos ordinais definidos pelo usuário 13
5.4. Matrizes 13
5.4.1. Vinculação de índices e categorias de matrizes 14
5.4.2. Inicialização de matrizes 14
5.4.3. Operação de Matrizes 14
5.4.4. Matrizes regulares e irregulares 14
5.4.5. Fatias 15
5.5. Matrizes Associativas 15
5.6. Registros 16
5.6.1. Operando com registros 16
5.7. Uniões 17
5.8. Ponteiros e referências 17
5.8.1. Coleta de referências 17
5.9. Verificação de tipos 17
6.0. Tipagem forte 18
6.1. Equivalência de tipos 19
1. Nomes
Em Elixir os nomes são sensíveis à capitalização.
Elixir possui poucas palavras reservadas, estas são:
● true, false, nil - usados como átomos
● when, and, or, not, in - usados como operadores
● fn - usado para definições de funções anônimas
● do, end, catch, rescue, after, else - usados em blocos do/end
● defmodule, defstruct, import - usadas em definições
Elixir utiliza as palavras especiais como palavras reservadas, ou seja, não podem ser utilizadas como nome em contexto nenhum.
2. Variáveis
É importante entender que em Elixir as variáveis não funcionam como nas linguagens imperativas. Nela variáveis não ocupam partes da memória, não existe alocação dinâmica de variável; deve-se pensar em variável como um label, ou seja, quando é feito algo como a = 2, não estamos colocando 2 em a, estamos apenas colocando um nome/label para o valor. Ou seja, valores ocupam espaço, variáveis não. Em Erlang por exemplo, não é possível mudar este valor de label, em Elixir é possível.
3. Vinculações e Inferência de Tipo
As vinculações de tipos são dinâmicas em Elixir, sempre inferidas em tempo de execução.
Uma função pode ser definida da forma:
def sum(x, y) do
x + y end
Perceba que não precisamos definir o tipo de x nem y, e nem o tipo de retorno. Também não precisamos definir o que será retornado, tudo em Elixir é uma expressão e será retornado o valor resultante dessa expressão (no caso x+y).
Mesmo assim, Elixir dá a flexibilidade de definir funções esperando tipos, utilizando o @spec. Como no exemplo abaixo:
@spec sum(x,y) :: integer def sum(x, y) do
x + y end
As seguintes expressões são claramente permitidas.
va = 1.0 //float va = 1 //integer va = %{nome: "Dayvson"} //um map va = [1,2,3] // uma lista
Como já dito, Elixir é imutável, mesmo permitindo realizar as operações acima, internamente o valor de va não é mexido, pois utiliza-se a ideia de labels.
3.1. Vinculações de atributos a variáveis
A vinculação é dinâmica.
3.2. Vinculações de armazenamento e tempo de vida
Do ponto de vista do programador, toda a parte de memória é controlada pela BEAM (implementação vinda do Erlang VM, lembrar que Elixir utiliza a VM do Erlang). Ela utiliza alocação dinâmica internamente.
Como cada código de Elixir/Erlang é tratado como vários processos, cada processo possui um pedaço de memória. Esse pedaço é alocado pela BEAM na memória quando um processo é criado (geralmente o tamanho é de 4KB). Um lado é considerado stack (pilha) e o outro lado é considerado heap (monte). Os dados de um processo são copiados apenas quando um processo se comunica com outro.
A memória começa com 4KB e é dobrada quando se torna cheia. A ideia de utilizar vários processos como pequena parte de memória alocada é útil para o garbage collector, que funciona por processo e como os dados não são compartilhados pelos processos (a não ser que isso seja explicitado, mas nesse
caso, os dados seriam copiados, não referenciados), quando o garbage collector está ativo (e isso acontece quando a heap está cheia) não há problemas para os outros processos rodando em paralelo. Quando não mais necessário, a memória é liberada pelo BEAM.
4. Escopo
Em Elixir, existem dois tipos de escopo: escopo de topo (top level scope) e escopo de cláusula de função (function clause scope). Há uma série de instruções que podem criar um novo escopo (como comprehensions, módulos, try blocks). Basicamente, um escopo de um programa Elixir fica organizado da seguinte maneira:
...