Uma vez eu tive que mudar de emprego. Antes disso, trabalhei apenas com linguagens como Python, C ++, C # e mais algumas. E agora eu tive que começar a trabalhar com uma linguagem funcional. As primeiras impressões foram "que diabos é isso?" No entanto, eu consegui me adaptar rapidamente. A seguir, falarei sobre os principais pontos com os quais tive que me acostumar ou com os quais tive que entender para começar a escrever de maneira rápida e adequada.
1.
Correspondência de padrõesEste é um dos principais recursos do idioma. Mas entendê-lo completamente, até que você realmente comece a escrever no idioma é um pouco difícil. A primeira coisa que li sobre correspondência de padrões é que, graças a isso, você pode simplesmente extrair dados de estruturas e vinculá-los a variáveis. Mas, de fato, tudo é um pouco mais complicado. A correspondência de padrões funciona quase em qualquer lugar em um determinado idioma. Vou dar três exemplos ilustrando as principais aplicações que uso quase constantemente.
Exemplo 1. Por definição:
{tuple_item_1, tuple_item_2} = tuple
- divide uma tupla de 2 elementos em duas variáveis, que podem ser usadas.
[head_item | tail_list] = list
- divide a lista no primeiro elemento da lista e a lista sem o primeiro elemento.
Exemplo 2. Comparação no caso:
case get_elem(struct) do {:ok, elem} -> … {:error, reason} -> … end
A função
get_elem (struct) retorna uma tupla e case permite extrair dados imediatamente e selecionar uma sequência adicional de ações.
Exemplo 3 Mapeamento de Recursos:
def function_1(params, :ok) do end def function_1(params, :error) do end def function_1(params, _) do end
Aqui, de fato, é apresentada a mesma função que requer dois parâmetros. A correspondência de padrões permite escolher qual função executar.
Um pouco sobre a correspondência de padrões. A comparação é sempre "de cima para baixo". Neste exemplo, ao chamar a
função_1 a partir de dois parâmetros, ele primeiro verificará se o segundo parâmetro é
: ok . Se a primeira verificação falhar, será feita uma verificação para
: error . E se não for novamente, em qualquer caso, entraremos na terceira versão do método. O sublinhado significa "qualquer dado", bem como o fato de que os dados recebidos não nos interessam, ou seja, não os usaremos. Se a
função_1 (parâmetros, _) fosse a primeira da lista, o programa sempre a selecionaria e os outros dois métodos nunca funcionariam. Se o padrão desejado não for encontrado, uma exceção será lançada.
2.
PipelineEstas são construções da seguinte forma:
param_1 |> func_1() |> func_2(param_2) …
À primeira vista, algum lixo parece. Mas vale lembrar que o Elixir é uma linguagem funcional. E em uma linguagem funcional, é bastante normal fazer cálculos de funções funcionais, sem variáveis intermediárias. Pipeline é apenas uma entrada conveniente. O próprio idioma pede clareza para iniciar o pipeline com uma variável ou valor.
O exemplo acima pode ser reescrito da seguinte maneira:
func_2(func_1(param_1), param_2)
Em outras palavras, o pipeline redireciona o resultado do cálculo da função anterior para a próxima função com o primeiro argumento.
3.
Falta de ciclosNão há ciclos no Elixir. Esse fato causou o maior choque em mim e é o mais difícil de entender. Em seguida, vem minha opinião e visão, que podem não coincidir com a realidade e a teoria.
As raízes desse fato estão no paradigma de programação funcional, um dos quais afirma que o resultado de um programa é o trabalho de uma função que pode chamar outras funções e o programa não envolve o armazenamento de estados intermediários. Os ciclos, por sua vez, são projetados para alterar repetidamente o estado externo ao ciclo.
Duas coisas servem como um substituto para os ciclos - métodos de recursão e biblioteca para trabalhar com inúmeros elementos da linguagem.
Um pouco mais sobre as pequenas coisas.1. Não há aulas no Elixir, mas há contextos. Em essência, os contextos estão de alguma forma substituindo classes. A descrição mais próxima do contexto através dos olhos de um s-sharper: contextos são um cruzamento entre uma classe e um espaço para nome no sharpe, e o contexto está muito mais próximo do espaço para nome.
2. Átomos. No Elixir, existe um átomo. Um átomo é essencialmente um tipo de "rótulo". A maneira mais fácil de tratá-los é como linhas especiais. Os exemplos neste artigo já tinham dois átomos
:: ok ,: error . Graças aos átomos, a correspondência de padrões e construções lógicas complexas são muito mais fáceis. Em essência, são constantes cujo valor é seu nome. Um átomo sempre tem um ":" na frente de um nome.
3. Como ler os cabeçalhos do método corretamente. No Elixir, é habitual designar métodos da seguinte maneira (isso geralmente é visto na documentação):
& function / 2 . É lido como um método com o nome "função" e arity 2. Arity é o número de argumentos utilizados.
O que me ajudou a integrar o idioma.Em primeiro lugar, este é um diretório no android "Elixir Tutorial". É bom porque cobre brevemente os pontos principais do idioma e sua sintaxe, e pode ser lido no barramento. Menos: está em inglês, portanto não é adequado para todos.
Em segundo lugar, o livro "Introdução ao Elixir", de autoria de Senloren S., Eisenberg D ... Este livro mostra os métodos de trabalho com a linguagem e os explica. É fácil de ler e permite que você melhore significativamente seu trabalho com o idioma. Também pode ser encontrado em russo.
Em terceiro lugar, documentação oficial online. É feito de forma conveniente e permite que você encontre rapidamente as seções / métodos necessários, com uma descrição e exemplos detalhados.
Só isso.
Lista de materiais:
1.
Tutorial do Elixir2. Senloren S., Eisenberg D. Introdução ao Elixir. Introdução à programação funcional. - O'Reilly, 2017.
3.
Documentação oficial.