Introduzione a Elisir Lang
Pubblicato: 2015-02-27Un'introduzione al linguaggio di programmazione Elisir (e perché lo adoro)
Ho scritto un articolo qualche mese fa per presentarti Golang e perché mi è piaciuto così tanto. Anche se lo amo ancora, ultimamente ho giocato con una nuova lingua; Elisir. Ho comprato il libro Elisir di programmazione e l'ho seguito fino in fondo. Ho già imparato ad amare Elixir e spero di mostrarti perché in questo articolo.
Mentre lavoravo per Couchbase un paio di anni fa, mi sono interessato molto a Erlang e ai sistemi distribuiti. Per me, Erlang è fonte di confusione. Quando ho visto Elixir, ho subito capito che stavo pensando a qualcosa di buono. Elixir è descritto come un linguaggio funzionale e simultaneo che viene eseguito su Erlang VM.
Ho sentito molte volte persone dire che Elixir è "Ruby for Erlang" ecc. Questa teoria non è del tutto errata, ma realisticamente, è principalmente solo la sintassi di Elixir che è influenzata da Ruby, poiché non condivide molti degli stessi costrutti di programmazione. È, ovviamente, simile in modi a Erlang, essendo costruito in cima all'Erlang VM e dandoci accesso diretto alle primitive Erlang in modo nativo.
Ad ogni modo, senza ulteriori indugi, tuffiamoci e andiamo avanti con un po' di Elisir.
Installazione
Se stai utilizzando OSX, l'installazione è facile come usare Homebrew:
~ brew update
~ brew install erlang
~ brew install elixir
Una volta fatto questo, dovresti essere in grado di eseguire:
~ elixir -v
> Elixir 1.0.2
Ora Elixir è installato correttamente, possiamo aprire un elisir interattivo e giocare con alcuni tipi comuni di base.
Tipi in Elisir
Avvia una REPL di elisir interattivo inserendo
> iex
Variabili:
iex(1)> name = "rbin"
#=> "rbin"
Atomi:
In Elixir, un Atom è una costante in cui il nome corrisponde al proprio valore.
iex(2)> :this_is_an_atom
#=> :this_is_an_atom
iex(3)> :my_atom == :atom
#=> false
Tuple:
Usiamo la notazione parentesi graffa per definire le tuple. In Elixir, le tuple vengono archiviate immediatamente in memoria, il che significa che ottenere le dimensioni di una tupla o accedere a un elemento tupla è veloce, ma l'aggiornamento o l'aggiunta di elementi è costoso in quanto richiede la copia dell'intera tupla in memoria.
iex(4)> tuple = {:hello, "world"}
#=> {:hello, "world"}
iex(5)> elem(tuple, 1)
#=> "world"
Elenchi:
In Elisir, le liste sono salvate in memoria, come liste collegate. Possiamo aggiornare gli elenchi in modo banale anteponendo gli elementi, ma aggiungere elementi è più costoso, poiché dobbiamo attraversare l'intero elenco per capire la sua dimensione.
iex(8)> list = [1, 2, :atom]
#=> [1, 2, :atom]
iex(9)> ["string"] ++ list
#=> ["string", 1, 2, :atom]
iex(10)> list ++ [31]
#=> [1, 2, :atom, 31]
Ci sono funzioni integrate molto utili da utilizzare con gli elenchi, incluso ottenere l'intestazione e la coda di un elenco.
iex(11)> hd(list)
#=> 1
iex(12)> tl(list)
#=> [2, :atom]
Funzioni anonime:
In Elixir, le funzioni sono cittadini di prima classe, il che significa che possiamo passare funzioni come argomenti ad altre funzioni. Di seguito, definiremo una variabile denominata add che contiene una funzione, che passeremo come argomento a is_function/1 func .
iex(14)> add = fn a, b -> a + b end
#Function<12.90072148/2 in :erl_eval.expr/5>
iex(15)> add.(13, 31)
#=> 44
iex(16)> is_function(add)
#=> true
Organizzare i nostri progetti (Mix)
Elixir viene fornito con uno strumento super utile chiamato Mix. Mix è uno strumento di compilazione che ci consente di generare, organizzare, compilare e testare i nostri progetti molto facilmente. Inoltre, ci semplifica la gestione delle dipendenze. (Sempre un argomento delicato!) Per creare un nuovo progetto con Mix, facciamo semplicemente quanto segue:
~ mix new myapp --module MyApp
Questo creerà una directory chiamata myapp con alcuni file all'interno. Definirà anche un modulo MyApp all'interno di lib/myapp.ex .
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/myapp.ex
* creating test
* creating test/test_helper.exs
* creating test/myapp_test.exs
Your mix project was created successfully.
You can use mix to compile it, test it, and more:
cd myapp
mix test
Come possiamo vedere, otteniamo tutti i file necessari per una struttura di progetto di base. Penso che questa sia una delle funzionalità più belle disponibili fornite con Elixir. Avere strumenti di gestione dei progetti è super utile e fa risparmiare molto tempo.
Il file mix.exs è il file principale utilizzato per configurare il nostro progetto e gestire le dipendenze, ecc. Otteniamo un test/folder , in cui possiamo scrivere test molto simili a ruby per il nostro progetto. Ovviamente otteniamo una lib/folder , che contiene i file sorgente del nostro progetto. Se eseguiamo il mix test sulla nostra app, otteniamo quanto segue:
$ mix test
Compiled lib/myapp.ex
Generated myapp.app
.
Finished in 0.04 seconds (0.04s on load, 0.00s on tests)
1 tests, 0 failures
Randomized with seed 543313
Concorrenza
Proprio come Erlang, Elixir usa il modello "Attore" per la concorrenza. Tutto il nostro codice viene eseguito all'interno di Processes e questi processi sono isolati l'uno dall'altro. Possiamo creare programmi completamente simultanei in Elixir generando processi e inviando e ricevendo messaggi tra di loro.
In Elixir, avviamo i processi usando la funzione spawn , che prende un'altra funzione come argomento.
iex(1)> spawn(fn -> IO.puts 1 + 1 end)
#=> 2
#PID<0.55.0>
Come puoi vedere, abbiamo generato un processo che ha prodotto 1 + 1 e ha anche restituito il suo ID processo. La restituzione di questo ID processo è utile, poiché possiamo assegnarlo a una variabile e utilizzarlo per inviare messaggi al processo. Prima di farlo, dobbiamo creare un meccanismo di ricezione per ottenere i messaggi che inviamo al processo. (Possiamo andare avanti e farlo nella nostra sessione di Elisir interattivo , riga per riga.)
Una volta fatto, possiamo creare un processo che valuti area_loop e assegnarlo a pid .
pid = spawn(fn -> Geometry.area_loop() end)
#=> #PID<0.40.0>
Possiamo quindi inviare messaggi a pid su cui il nostro codice predefinito corrisponderà, a seconda che riceva :rectangle atom o :circle atom.
send pid, {:rectangle, 2, 3}
#=> Area = 6
# {:rectangle,2,3}
send pid, {:circle, 2}
#=> Area = 12.56000000000000049738
# {:circle,2}
Possiamo verificare se i processi sono ancora in esecuzione utilizzando Process.alive? funzione.
Process.alive?(pid)
#=> false
Conclusione
Non abbiamo nemmeno scalfito la superficie in questo blog. Ci sono così tante fantastiche funzionalità in Elixir, spero che continuerai a provarlo di persona. Di seguito ho elencato alcune risorse di apprendimento per aiutarti lungo il percorso, ma prima di partire e tuffarti, ecco alcune delle mie cose preferite su Elixir:
- Era facile da capire, con una sintassi simile a un rubino e primitivi simili a Erlang
- Dietro c'è una community fantastica
- Il suo modello di concorrenza mi è familiare e molto potente
- Mix è una manna dal cielo e fa risparmiare MOLTO tempo
- Elisir ci incoraggia a documentare tutto
- Rende la creazione di app distribuite un campo di battaglia molto meno confuso
- Vedo Elixir fare molta strada.
Risorse
Alcune risorse che ho trovato molto utili nel mio breve periodo di apprendimento di Elisir:
- http://elisir-lang.org/getting-started/introduction.html
- https://pragprog.com/book/elisir/programmazione-elisir
- https://teamgaslight.com/blog/the-best-resources-for-learning-elisir
- http://esercizio.io
* Vai avanti e sorseggia quell'Elisir! – @rbin *