Skip to content

marcelgsantos/curso-elm

Folders and files

NameName
Last commit message
Last commit date
Aug 13, 2018
Nov 13, 2016
Nov 13, 2016
Nov 13, 2016
Nov 13, 2016
Aug 13, 2018
Aug 13, 2018
Aug 13, 2018
Aug 13, 2018
Aug 13, 2018

Repository files navigation

  • Elm é um linguagem de programação projetada para construir aplicações front-end.
  • Elm é uma linguagem de programação funcional e excelente alternativa ao JavaScript.
  • Em JavaScript é difícil de escrever bom código, livre de bugs e manutenível.
  • É necessario conhecimento extensivo, muita experiência e disciplina para isso.
  • Muitas linguagens foram criadas para tentar melhorar o JavaScript como CoffeeScript, Dart e TypeScript.
  • O JavaScript evoluiu bastante adicionando novas funcionalidades, porém não removeu as partes ruins.
  • Algumas das principais características e benefícios da linguagem Elm:
    • ótima linguagem para escrever aplicações web front-end
    • cuidadosamente pensada e criada por Evan Czaplicki
    • poderosa e simples de se utilizar
    • equilíbrio entre idealismo e pragmatismo
    • chance nula de erros em tempo de execução
      • é uma linguagem compilada
    • fácil depuração
      • os efeitos colaterais, comum em navegadores, são controlados
      • no JavaScript os erros podem estar em qualquer lugar no código
    • fácil de refatorar
      • pode ser feita com facilidade e confiança
      • no JavaScript, existe muito medo e incertezas
      • o compilador ajuda no processo de refatoração
      • se compila, funciona
      • código com melhor manutenibilidade
    • tipagem estática
      • o sistema de tipos estáticos não é igual ao Java
      • permite corrigir bugs em tempo de desenvolvimento
      • é melhor encontrar erros em tempo de desenvolvimento ao invés de produção
    • melhor produtividade
      • os conceitos da linguagem são simples
      • utiliza-se dados imutáveis e funções
      • não se utiliza objetos complexos com estados e inúmeros padrões de projetos
      • permite atingir o "fluxo"
    • melhor testabilidade
      • utiliza-se funções puras
      • TDD não se faz necessário pois um código Elm já é testável
    • força versionamento semântico
      • utiliza o Elm Package Manager
      • o gerenciador de pacote realiza a verificação
  • Elm expõe uma quantidade grande de péssimos hábitos em outras linguagens.
  • Elm permite conhecer os benefícios de uma linguagem de programação funcional e usá-las em outras linguagens.
  • A melhor forma de aprender programação funcional é através de uma linguagem puramente funcional.
  • O Elm disponibiliza um instalador para Windows e Mac.
  • O Elm pode ser instalado também através do NPM, que é a opção mais recomendada.
  • O Elm pode ser instalado utilizando o comando npm install -g elm.
  • O Elm possui um excelente suporte para diversos editores como o Atom e o Sublime Text.
  • No Sublime Text, recomenda-se instalar o Elm Language Package através do instalador de pacotes.
  • No Atom, recomenda-se instalar o pacote language-elm para ter autocomplete e syntax highlight.
  • A instalação de pacotes no Atom pode ser feita através da linha de comando utilizando o apm.
  • O pacote language-elm pode ser instalado utilizando o comando apm install language-elm.
  • No Atom, recomenda-se instalar também o pacote elm-oracle que adicionar diversas outras funcionalidades em relação ao Elm.
  • O pacote elm-oracle pode ser instalado utilizando o comando npm install -g elm-oracle.
  • Após sua instalação, deve-se adicionar o caminho do elm-oracle nas configurações do Atom. Para isso, obtém-se o caminho utilizando o comando which elm-oracle.
  • Recomenda-se instalar também o pacote elm-format para formatação de acordo com os padrões da comunidade.
  • O elm-format pode ser instalado baixando o executável em https://github.com/avh4/elm-format e movendo para o diretório de executáveis utilizando o comando sudo mv elm-format /usr/local/bin/elm-format.
  • No Atom, recomenda-se instalar o pacote elm-format para formatação de código.
  • O pacote elm-format pode ser instalado utilizando o comando apm install elm-format.
  • É uma boa prática selecionar a opção format on save no Atom para realizar a formatação ao salvar o arquivo.
  • No Atom, recomenda-se instalar um linter utilizando o comando apm install linter.
  • Pode-se instalar um linter para Elm utilizando o comando apm install linter-elm-make.
  • Após sua instalação, deve-se adicionar o caminho do elm-make nas configurações do Atom. Para isso, obtém-se o caminho utilizando o comando which elm-make.
  • Para mais informações sobre as ferramentas, basta acessar https://atom.io/packages/language-elm e https://github.com/ElmCast/elm-oracle.
  • A programação funcional é um estilo de programação que utiliza funções puras.
  • Uma função pura é uma função que retorna um valor baseado na entrada e sem efeitos colaterais.
  • Uma função pura possui as seguintes características:
    • deve ter uma entrada de valor
    • deve retornar um valor
    • não deve utilizar estados
    • não deve causar efeito colateral
  • Uma função pura possui as seguintes vantagens:
    • reusável
    • componível
    • testável
    • cacheável
    • paralelizável
  • A utilização de funções puras permite que tenhamos mais foco.
  • A programação funcional não diz que não se deve ter estado, muito pelo contrário.
  • Uma aplicação é composta por estado e pela alteração do estado.
  • A programação funcional é sobre eliminar o estado quando possível e controlar o estado quando necessário.
  • Um código com estado não controlado deixa o código feio e difícil de manter.
  • É possível utilizar o estilo de programação funcional em linguagens não funcionais.
  • Essa é uma ótima abordagem e altamente recomendada.
  • É possível utilizar programação funcional no JavaScript, mas requer muita disciplina.
  • Porém, como a linguagem e o interpretador não se importam com o código, não temos todas as garantias e benefícios da programação funcional.
  • Utilizar uma linguagem de programação funcional força a programação funcional.
  • Ou seja, somos forçados a utilizar funções puras e dados imutáveis, por exemplo.
  • No Elm, para imprimir um texto na tela, deve-se utilizar a função text do pacote Html.
  • O Elm possui um excelente gerenciador de pacotes.
  • Os diversos pacotes podem ser consultados em http://package.elm-lang.org.
  • Para instalar o pacote Html utiliza-se o comando elm-package install elm-lang/html.
  • Para utilizar o pacote Html utiliza-se o comando import Html.
  • Ao instalar o pacote Html, outros pacotes também serão instalados como dependências.
  • Para imprimir um texto na tela, utiliza-se a função HTML.text, sem a necessidade de parênteses e separando o argumento com um espaço. Por exemplo, Html.text "Hello World".
  • Pode-se utilizar a ferramenta Elm Reactor para executar a aplicação.
  • O Elm Reactor cria um um servidor web, compila e executa automaticamente a aplicação no navegador.
  • Para iniciar o Elm Reactor utiliza-se o comando elm reactor.
  • Para executar a aplicação basta acessar o endereço http://localhost:8000 no navegador e clicar no nome do arquivo Elm da aplicação desejada.
  • Uma função no Elm é definida pelo seu nome, seguido dos argumentos separados por espaço, um sinal de igual e o corpo da função. Por exemplo, add a b = a + b.
  • Não é necessário utilizar return pois o corpo da função é uma expressão.
  • Para chamar a função basta informar o nome da função seguido dos parâmetros separados por espaços. Por exemplo, add 1 2.
  • Como o corpo de uma função é uma expressão, uma cláusula if deverá sempre conter else.
  • O Elm é fortemente tipado e não faz conversão implícita de tipos.
  • A função toString é utilizada para converter um valor de qualquer tipo para uma String.
  • Ela é importada por padrão em todas as aplicações Elm.
  • É recomendável utilizar parênteses para sinalizar a ordem da aplicação das funções.
  • Por exemplo, em toString add 1 2 estamos passando três argumentos para a função toString. Para realizar a adição e depois a conversão para string deveremos utilizar os parênteses como em toString (add 1 2).
  • O operador |> (forward pipe operator) é utilizado para utilizar o resultado da expressão à esquerda como argumento da expressão à direita.
  • A aplicação parcial de uma função consiste em chamar uma função fornecendo parte de seus argumentos.
  • Uma função anônima é definida por uma barra invertida (\), seguidos dos argumentos separados por espaço, um sinal -> e o corpo da função anônima. Por exemplo, \a -> a % 2 == 0 é uma função anônima que verifica se um número é par ou ímpar.
  • Em Elm não é permitido a utilização de funções impuras.
  • É possível utilizar variáveis locais através da cláusula let .. in. Neste caso, só podemos atribuir um valor e nunca alterá-lo por causa da imutabilidade.
  • Em Elm, quase tudo é uma função ou "funciona" como uma função.
  • Em Elm, o operador + é uma função infixa.
  • É mais comum se utilizar funções prefixas em programação imperativa.
  • Uma função infixa, como o operador +, é posicionada entre os parâmetros e permite uma melhor legibilidade.
  • Ao criar uma função que não contenha caracteres alfanuméricos, ela será uma função infixa. Por exemplo, (~+) a b = a + b + 0.1 é uma função infixa e é utilizada como em result = 1 ~+ 2.
  • Pode-se chamar uma função prefixa como uma função infixa utilizando backticks (`). Por exemplo, result = 1 `add` 2.
  • Pode-se chamar uma função infixa como uma função prefixa utilizando parênteses. Por exemplo, result = (~+) 1 2.
  • Uma das vantagens de se utilizar funções puras é a composição de funções.
  • A composição de função permite criar uma nova função a partir da combinação de uma ou mais funções.
  • O operador >> permite realizar a composição de funções em Elm.
  • O Elm possui tipos primitivos como String, Int e Bool e também tipos avançados como Records e Union Types.
  • No Elm, o sistema de tipos estático é razoavelmente diferente do que estamos acostumados.
  • Sistemas de tipos estáticos normalmente possuem alguns problemas como:
    • declarações longas e verbosas
    • compilação lenta
    • mensagens de erros de difícil compreensão
    • erros em tempo de execução
  • O sistema de tipos estático do Elm possui as seguintes características:
    • inferência de tipos
      • não é necessário declarar explicitamente os tipos
      • assemelha-se linguagens dinâmicas
    • compilação rápida
    • mensagens de erros amigáveis e úteis
      • sugestões de correção
    • sem erros em tempo de execução
  • Um compilador é responsável por transformar o código fonte em linguagem de máquina ou linguagem intermediária.
  • No Elm, o processo de compilação permite transformar o código fonte Elm em JavaScript e encontrar e consertar erros em tempo de desenvolvimento.
  • O Elm possui tipos primitivos como String, Char, Bool, Float e number.
  • O tipo number é um tipo genérico que pode ser Integer ou Float.
  • O tipo List representa uma lista de valores todos do mesmo tipo. Por exemplo, ["Anna", "Bob", "Carol"] é uma lista de strings.
  • O tipo tupla representa uma lista ordenada de valores não necessariamente do mesmo tipo. Por exemplo, ("pi", 3.14) é uma tupla com uma string e um float.
  • O tipo Record representa uma estrutura de dados semelhante a um objeto no JavaScript. Por exemplo, person = { name = "James", age = 42 }.
  • Não é possível acessar um campo inexistente em um Record.
  • Um campo de um Record não pode ser undefined ou null e não pode ser auto-referenciado.
  • Um Record é um grupo de campos relacionados.
  • Para acessar um campo de um Record utiliza-se a notação de ponto como em person.name, por exemplo.
  • Ao tentar acessar um campo inexistente em um Record um erro de compilação será disparado.
  • Pode-se acessar como uma função o campo de um Record através da notação de ponto como em .name person, por exemplo.
  • Um campo de um Record pode ser alterado utilizando a sintaxe newPerson = { person | age = 31 }.
  • No Elm, as estruturas de dados são imutáveis. Logo, ao alterar o valor de Record um novo Record é gerado.
  • No Elm, tipos mais complexos podem ser representados através de union types.
  • As union types assemelham-se a enumerações de tipos diferentes.
  • Pode-se criar union types para tipos diferentes de eventos ou ações em uma aplicação. Por exemplo, type Action = AddPlayer | Score ou type Action = AddPlayer String | Score Int Int.
  • Os tipos que levam parâmetros adicionais podem ser tratados com funções (sua anotação de tipos é representada como funções).
  • Em uma aplicação Elm, costuma-se utilizar uma union type chamada Msg por convenção.
  • A mensagem flui através da aplicação e determinadas ações tratam as mensagens corretamente.
  • Pode-se utilizar pattern matching para decodificar as mensagens e responder a cada uma delas.
type Msg = Msg1 Int | Msg2 String
msg = Msg2 "James"
case msg of
    Msg1 num -> "The number is " ++ (toString num)
    Msg2 name -> "Hello " ++ name
  • O pattern matching deve cobrir o maior número de situações possíveis.
  • A maioria das linguagens sejam estáticas ou dinâmicas permitem que variáveis armazenem um valor ou nulo.
  • O null é um dos maiores problemas de projetos de linguagens de programação.
  • O problema é conhecido como "billion-dollar mistake".
  • Muito tempo é desperdiçado com exceções ocasionados por valores nulos.
  • O Elm não suporta valores nulos.
  • Em Elm, utiliza-se o tipo Maybe para representar uma variável que pode ou não conter um valor.
  • Maybe é um union type que pode conter um valor (ou Just) ou nenhum valor (ou Nothing).
  • Pode-se obter Nothing ao tentar retornar o primeiro elemento de uma lista vazia. Por exemplo, List.head [] retorna Nothing.
  • Utilizar Maybe é como checar por nulos em outras linguagens.
  • Utilizar Maybe permite que o compilador garanta a sua utilização correta.
  • O tipo Result é utilizado em uma computação que pode falhar.
  • Ele deve ser utilizado para o gerenciamento de erros no Elm.
  • Result é um union type com duas possibilidades como Maybe. Uma possibilidade é Ok, que contem o valor calculado e a outra possibilidade é Err, que contem informações de erro.
  • Pode-se utilizar a função Maybe.withDefault para mostrar uma mensagem padrão caso Maybe não contenha nenhuma informação.
  • As funções são valores e podem ser passadas como argumentos e retornadas como valor.
  • Uma função de alta ordem é uma função que recebe outra função como argumento ou retorna como valor.
  • A função Maybe.map é um exemplo de uma função de alta ordem.
  • As anotações de tipos estão presentes nos linters, na documentação e no REPL do Elm.
  • As anotações de tipos são utilizadas para informar o tipo de entrada e saída de uma função ou de uma constante.
  • A utilização de anotação de tipos é opcional no Elm.
  • O compilador pode inferir os tipos.
  • É encorajado utilizar anotações de tipos em Elm.
  • Algumas vantanges de utilizar anotações de tipos são:
    • expressividade - permite conhecer com mais detalhes as entradas e saídas das funções
    • restritividade - permite ser mais específico ao definir uma anotação de tipo
    • escrever melhores funções - permite escrever funções mais gerais e usáveis
  • É difícil pensar em tipos e pensar de maneira abstrata e isso vem com experiência.
  • Para definir uma anotação de tipo para uma função utilize o nome da função, seguido de dois-pontos, seguido dos tipos dos argumentos e do tipo de retorno separados por ->. Por exemplo, add : Int -> Int -> Int.
  • O tipo comparable representa qualquer tipo que pode ser comparado como strings, caracteres e números.
  • Pode-se definir uma anotação de tipos para uma lista de registros como em cart : List { name : String, ... }.
  • Pode-se definir um type alias como em type alias Item = { name : String, ... }.
  • A utilização de type aliases permite torna o código mais compreensível.
  • A anotação de tipos da função main é main : Html.Html msg.
  • Uma aplicação Elm possui três partes: model, update e view.
  • A model é como um contêiner que armazena os dados que a aplicação necessita.
  • A model pode ser um tipo primitivo como um Int ou String ou um tipo complexo como um Record. Por exemplo, type alias Model = Int.
  • A seção update é responsável por atualizar a model ou estado da aplicação.
  • Na seção update definimos (1) o que pode acontecer na aplicação e (2) como a model é atualizada.
  • Definimos o que pode acontecer na aplicação utilizando union types como em type Msg = AddCalorie | Clear.
  • Definimos como a model é atualizada utilizando um função update que recebe uma mensagem e a model como argumentos e retorna uma nova model. Por exemplo, update : Msg -> Model -> Model.
  • A view é responsável por criar o HTML levando em consideração a model atual ou o estado da aplicação.
  • A view é criada de maneira declarativa.
  • A view normalmente é uma função view que recebe a model como argumento e retorna o HTML. Por exemplo, view : Model -> Html Msg.
  • No módulo Html do Elm, existem diversas funções responsáveis pela criação das tags HTML.
  • As funções responsáveis pela criação das tags HTML possuem assinaturas consistentes.
  • O nome da função é o nome da tag HTML, o primeiro argumento é uma lista de atributos e o segundo argumento é uma lista de elementos filhos. Por exemplo, div [] [] retornará <div></div> ou p [class "story"] [text "once"] retornará <p class="story">once</p>.
  • É possível utilizar uma função de um módulo sem a necessidade de informá-lo explicitamente como em Html.text "Hello World".
  • Isso pode ser feito importando o módulo em questão e expondo as funções desejadas. Por exemplo, import Html exposing (div, p, button, text).
  • Pode-se importar todas as funções utilizando a notação ... Por exemplo, import Html exposing (..).
  • Para se utilizar atributos HTML deve-se importar os módulos Html.Attributes e Html.Events. Por exemplo, import Html.Attributes exposing (..).
  • Ao utilizar o atributo type, deve-se adicionar uma aspa simples após seu nome para diferenciá-lo da palavra-chave reservada type de Elm. Por exemplo, button [type' "button"].
  • Em view : Model -> Html Msg diz que a função view recebe uma Model como argumento e retorna um Html como resultado que pode gerar uma Msg.
  • A função beginnerProgram do módulo Html é responsável por juntar as três partes (model, view e update) de uma aplicação Elm, ou seja, manter o estado da aplicação, gerenciar as mensagens e chamar as funções view e update de acordo com a necessidade.
  • O funcionamento do fluxo da aplicação em Elm é a seguinte:
    1. a model inicial define o estado atual da aplicação
    2. a função view é chamada com o estado atual da aplicação ou model
    3. a função view gera uma representação visual do estado atual da aplicação
    4. uma mensagem é gerada e a função update é chamada com a mensagem e o estado atual da aplicação como argumentos
    5. a função update cria uma nova model baseada na mensagem informada e na model anterior
    6. a nova model é retornada e armazenada como o novo estado atual da aplicação
    7. a função view é chamada novamente com o estado da aplicação atualizado
    8. e a função view gera uma nova representação visual do novo estado atual da aplicação
  • O estado da aplicação é gerenciado pelo módulo Html e trabalha exclusivamente com funções puras.
  • O tipo Maybe String diz que um valor pode ou não ser uma string.
  • O type alias pode ser utilizado como uma função para construir novos valores.
  • Ao tentar converter um valor de string para inteiro utilizando a função String.toInt, pode-se obter Ok ou Err.
  • Recomenda-se planejar uma aplicação Elm pensando em model, update e view.
  • Recomenda-se quebrar a aplicação em componentes ou funções.
  • Utiliza-se o comando elm make para compilar código Elm.
  • Em elm make ./Main.elm --output ./bundle.js, a aplicação Elm é compilada para um arquivo chamado bundle.js.
  • O arquivo gerado a partir da compilação pode ser incluído normalmente em um arquivo HTML.
  • Deve-se lembrar de associar a aplicação Elm a um elemento do HTML. Por exemplo, var app = Elm.Main.embed(document.getElementById("app")).
  • Pode-se utilizar uma ferramenta como o Gulp para automatizar a compilação de uma aplicação Elm.
  • A utilização de pattern matching deve ser exaustiva e cobrir todos os casos possíveis.
  • Pode-se utilizar o _ como coringa em pattern matching postergar a implementação de todos os casos possíveis.
  • O Elm utiliza uma implementação de virtual DOM poderosíssima.
  • Pode-se utilizar a função Debug.log para imprimir informações no log do navegador.
  • Para adicionar um valor em uma lista utiliza-se o operador ++. Por exemplo, newPlayers = players ++ [player].
  • O operador ++ opera somente sobre listas. Por isso, devemos colocar o valor dentro de uma lista antes de concatenar.
  • Pode-se utilizar o operador :: (cons) para adicionar um valor no começo de uma lista.
  • Utilizar o operador :: é mais performático pois, para adicionar o valor no início da lista, não é preciso percorrer a lista inteira.
  • Pode-se utilizar a função List.map para aplicar uma função em cada elemento de uma lista.
  • Recomenda-se utilizar a função List.sortBy para ordenar uma lista de acordo com um campo. Por exemplo, List.sortBy .name users.
  • Recomenda-se utilizar a função List.filter para filtrar uma lista de acordo com uma condição. Por exemplo, List.filter (\u -> u.age >= 18) users.
  • A utilização do caractere coringa _ não se faz necessária quando se cobre todos os casos em pattern matching.
  • Recomenda-se conhecer como se trabalha com HTTP, web sockets, componentes, single page apps, comunicação com o JavaScript, testes entre outras coisas em Elm.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published