Elm

Resumo

Como vamos ver, Elm é bastante pequena e simples, o que torna fácil criar interfaces gráficas para a Internet. Elm quando compilada tem como alvos JavaScript, HTML e CSS. Elm é uma linguagem ainda muito jovem, foi criada em 2012 e está na versão 0.16 (https://en.wikipedia.org/wiki/Elm_%28programming_language%29).

Introdução

Elm utiliza o paradigma de programação FRP (Functional Reactive Programming), ou seja é uma linguagem funcional que está alerta ao tempo. Por outro lado desenvolvimento em Elm diverge da maioria das alternativas porque não utiliza a arquitetura MVC (Model, View & Controller). O fluxo de informação num programa Elm, que corre dentro do navegador de Internet, segue apenas uma direção tal como se pode ver na imagem abaixo.

Elm: Fluxo de informação num programa

Fluxo de informação num programa Elm (retirado da documentação oficial)

Instalação

Para instalar a linguagem Elm é necessário o Node.Js para proceder à sua compilação. A infra-estrutura Elm também disponibiliza um gestor de pacotes, ferramenta de testes unitários, REPL (Read, Evaluate, Print, Loop), debugger e instaladores para Windows e Mac que podem ser descarregados em http://elm-lang.org. A instalação em Ubuntu é feita com os seguintes comandos, começando por instalar o Node.Js seguida da instalação de Elm:

$ curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -
$ sudo apt-get install -y nodejs
$ npm install -g elm

Agora estamos prontos para criar o nosso primeiro programa em Elm. A forma mais simples é partir de uma infra-estrutura e preencher apenas algumas funções. Esta infra-estrutura será responsável pelo fluxo de informação e pela receção de sinais a que o nosso programa responderá (o tempo, o clicar e mover do rato e o teclado são exemplos de sinais). Os sinais registados no programa levarão a uma mudança no estado do programa e consequentemente a uma atualização da interface gráfica. É mais fácil do que parece, vamos a isto.

Programa que conta cliques do rato

A imagem abaixo mostra-nos o programa Click numa janela do navegador.

Elm: programa Click
Este programa reage a dois eventos:

  • se se clicar no botão esquerdo do rato em cima do número a azul, o mesmo aumenta em uma unidade; e
  • se se carregar no botão a contagem fica a zero.

O valor inicial é 100.

O código

Para começar o programa criar a diretoria Click e de seguida ir para a mesma. Escrever o comando:

$ elm-package install evancz/start-app

E responder y às perguntas para autorizar a instalação. Start-app é a infra-estrutura de que falámos atrás. O conteúdo da diretoria é:

  • elm-package.json
  • elm-stuff/

A diretoria elm-stuff não contém nada com que seja necessário preocuparmo-nos agora. O ficheiro elm-package.json contém informação que deve ser editada manualmente, por exemplo a licença, a versão, e uma explicação sobre a aplicação. Para a nossa aplicação temos que acrescentar a informação sobre a biblioteca elm-http, ficando o ficheiro elm-package.json com a seguinte informação:

{
  "version": "1.0.0",
  "summary": "Programa para contar cliques.",
  "repository": "https://github.com/user/project.git",
  "license": "BSD3",
  "source-directories": ["."],
  "exposed-modules": [],
  "dependencies": {
    "elm-lang/core": "3.0.0 <= v < 4.0.0",
    "evancz/elm-html": "4.0.1 <= v < 5.0.0",
    "evancz/start-app": "2.0.2 <= v < 3.0.0"
  },
  "elm-version": "0.16.0 <= v < 0.17.0"
}

Aqui são declaradas as bibliotecas externas utilizadas pelo programa. Um programa em Elm começa pelo ficheiro Main.elm e, no nosso caso criamos o ficheiro Click.elm.

O ficheiro Click.elm

No ficheiro Click.elm temos as funcionalidades do programa conforme, começando pela declaração do tipo de variável Model que guarda o estado do programa. Uma nova variável deste tipo é criada quando o programa reage a um sinal externo. Também é declarado o tipo de variável Action que corresponde às possíveis mudanças de estado do programa.

module Click where

import Html exposing (..)
import Html.Attributes exposing (style)
import Html.Events exposing (onClick)

type alias Model = Int
type Action = Increment | Reset

No programa Click o nosso modelo corresponde a uma contagem de cliques no botão esquerdo do rato, que é guardado num tipo inteiro. O tipo de ações que iremos utilizar no nosso programa serão incrementar a contagem e colocá-la a zero.

Segue-se a função update que cria variáveis do tipo Model sempre que é invocada.

update : Action -> Model -> Model
update action model = case action of
  Increment ->
    model + 1
  Reset ->
    0

A declaração da função update mostra-nos que entram duas variáveis, a primeira do tipo Action e a segunda do tipo Model. A função update devolve uma variável do tipo Model. Se a ação invocada for Increment, à variável com o valor do modelo atual é somado 1. Se a ação for Reset, é criada uma variável do tipo Model com o valor 0.

A função view que atualiza a interface gráfica.

view : Signal.Address Action -> Model -> Html
view address model = div []
  [ div [ textStyle ]
            [ text "Clique no numero para incrementar: " ]
  , div [ countStyle
        , onClick address Increment ]
            [ text (toString model) ]
  , button [ onClick address Reset ]
            [ text "Colocar a 0" ]
  ]

A função view tem como argumentos de entrada uma variável do tipo Action e outra variável do tipo Model. O resultado da função é um DOM (Html).

Os atributos dos elementos criados são dados em textStyle e countStyle, conforme podemos ver abaixo.

countStyle : Attribute
countStyle = style
   [ ("font-size", "20px")
  , ("color", "blue")
  , ("font-family", "monospace")
  , ("display", "inline-block")
  , ("width", "50px")
  , ("text-align", "center")
  ]
textStyle : Attribute
textStyle = style
  [ ("font-size", "20px")
  , ("font-family", "fantasy")
  , ("display", "inline-block")
  , ("text-align", "center")
  ]

O ficheiro Main.elm

O ficheiro Main.elm declara o estado inicial do programa, note-se que iniciamos o modelo a 100.

import Click exposing (update, view)
import StartApp.Simple exposing (start)
main = start
  { model = 100
  , update = update
  , view = view
  }

Compilação

Um programa Elm é compilado para JavaScript. O comando para o fazer é:

$ elm-make Main.elm

Para correr o programa basta abrir o ficheiro index.html na diretoria em que escreveu o programa a partir do seu navegador favorito.

Conclusões

A linguagem Elm corresponde aos anseios de quem pretende fugir à arquitetura MVC e a quem deseja fazer programação funcional nos navegadores.

A linguagem Elm insere-se na família ML, tem variáveis dinâmicas (a declaração dos tipos das funções, tal como foi apresentada neste artigo, é opcional).

A linguagem Elm é pequena e muito pragmática pelo que é acessível a programadores que não conheçam programação funcional. A documentação, principalmente em Inglês, é clara e a comunidade é muito amigável.

Refira-se ainda que as mensagens de erro são muito claras, tentando guiar o programador diretamente para a origem do problema de uma forma direta e sugerindo soluções.