summaryrefslogtreecommitdiffhomepage
path: root/ro-ro
diff options
context:
space:
mode:
Diffstat (limited to 'ro-ro')
-rw-r--r--ro-ro/elixir-ro.html.markdown459
1 files changed, 459 insertions, 0 deletions
diff --git a/ro-ro/elixir-ro.html.markdown b/ro-ro/elixir-ro.html.markdown
new file mode 100644
index 00000000..d8b261af
--- /dev/null
+++ b/ro-ro/elixir-ro.html.markdown
@@ -0,0 +1,459 @@
+---
+language: elixir
+contributors:
+ - ["Joao Marques", "http://github.com/mrshankly"]
+ - ["Dzianis Dashkevich", "https://github.com/dskecse"]
+ - ["Ryan Plant", "https://github.com/ryanplant-au"]
+ - ["Ev Bogdanov", "https://github.com/evbogdanov"]
+translators:
+ - ["Vitalie Lazu", "https://github.com/vitaliel"]
+
+filename: learnelixir-ro.ex
+---
+
+Elixir este un limbaj funcțional modern construit pe baza mașinii virtuale Erlang.
+E total compatibil cu Erlang, dar are o sintaxă mai prietenoasă și propune mai multe
+posibilități.
+
+```elixir
+
+# Comentariile de o linie încep cu simbolul diez.
+
+# Pentru comentarii pe mai multe linii nu există sintaxă separată,
+# de aceea folosiți mai multe linii cu comentarii.
+
+# Pentru a folosi shell-ul elixir utilizați comanda `iex`.
+# Compilați modulele cu comanda `elixirc`.
+
+# Ambele comenzi vor lucra în terminal, dacă ați instalat Elixir corect.
+
+## ---------------------------
+## -- Tipuri de bază
+## ---------------------------
+
+# Numere
+3 # număr întreg
+0x1F # număr întreg
+3.0 # număr cu virgulă mobilă
+
+# Atomii, sunt constante nenumerice. Ei încep cu `:`.
+:salut # atom
+
+# Tuplele sunt păstrate în memorie consecutiv.
+{1,2,3} # tuple
+
+# Putem accesa elementul tuplelui folosind funcția `elem`:
+elem({1, 2, 3}, 0) #=> 1
+
+# Listele sunt implementate ca liste înlănțuite.
+[1,2,3] # listă
+
+# Fiecare listă ne vidă are cap (primul element al listei)
+# și coadă (restul elementelor).
+# Putem accesa capul și coada listei cum urmează:
+[cap | coadă] = [1,2,3]
+cap #=> 1
+coadă #=> [2, 3]
+
+# În Elixir, ca și în Erlang, simbolul `=` denotă potrivirea șabloanelor și
+# nu atribuire.
+#
+# Aceasta înseamnă că expresia din stînga (șablonul) se potrivește cu
+# expresia din dreaptă.
+#
+# În modul acesta exemplul de mai sus lucrează accesînd capul și coada unei liste.
+
+# Potrivirea șablonului va da eroare cînd expresiile din stînga și dreapta nu se
+# potrivesc, în exemplu acesta tuplele au lungime diferită.
+{a, b, c} = {1, 2} #=> ** (MatchError)
+
+# Există și date binare
+<<1,2,3>>
+
+# Sunt două tipuri de șiruri de caractere
+"salut" # șir de caractere Elixir
+'salut' # listă de caractere Erlang
+
+# Șir de caractere pe mai multe linii
+"""
+Sunt un șir de caractere
+pe mai multe linii.
+"""
+#=> "Sunt un șir de caractere\npe mai multe linii..\n"
+
+# Șirurile de caractere sunt codificate în UTF-8:
+"Bună dimineața" #=> "Bună dimineața"
+
+# Șirurile de caractere sunt date binare, listele de caractere doar liste.
+<<?a, ?b, ?c>> #=> "abc"
+[?a, ?b, ?c] #=> 'abc'
+
+# `?a` în Elixir întoarce codul ASCII pentru litera `a`
+?a #=> 97
+
+# Pentru a concatena listele folosiți `++`, pentru date binare - `<>`
+[1,2,3] ++ [4,5] #=> [1,2,3,4,5]
+'Salut ' ++ 'lume' #=> 'Salut lume'
+
+<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
+"Salut " <> "lume" #=> "Salut lume"
+
+# Diapazoanele sunt reprezentate ca `început..sfîrșit` (inclusiv)
+1..10 #=> 1..10
+început..sfîrșit = 1..10 # Putem folosi potrivirea șabloanelor cu diapazoane de asemenea
+[început, sfîrșit] #=> [1, 10]
+
+# Dicţionarele stochează chei şi o valoare pentru fiecare cheie
+genuri = %{"Ion" => "bărbat", "Maria" => "femeie"}
+genuri["Ion"] #=> "bărbat"
+
+# Dicționare cu chei de tip atom au sintaxă specială
+genuri = %{ion: "bărbat", maria: "femeie"}
+genuri.ion #=> "bărbat"
+
+## ---------------------------
+## -- Operatori
+## ---------------------------
+
+# Operații matematice
+1 + 1 #=> 2
+10 - 5 #=> 5
+5 * 2 #=> 10
+10 / 2 #=> 5.0
+
+# În Elixir operatorul `/` întotdeauna întoarce un număr cu virgulă mobilă.
+
+# Folosiți `div` pentru împărțirea numerelor întregi
+div(10, 2) #=> 5
+
+# Pentru a obține restul de la împărțire utilizați `rem`
+rem(10, 3) #=> 1
+
+# Există și operatori booleni: `or`, `and` and `not`.
+# Acești operatori așteaptă ca primul argument o expresie booleană.
+true and true #=> true
+false or true #=> true
+1 and true #=> ** (BadBooleanError)
+
+# Elixir de asemenea oferă `||`, `&&` și `!` care acceptă argumente de orice tip.
+# Toate valorile în afară de `false` și `nil` se vor evalua ca `true`.
+1 || true #=> 1
+false && 1 #=> false
+nil && 20 #=> nil
+!true #=> false
+
+# Operatori de comparație: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` și `>`
+1 == 1 #=> true
+1 != 1 #=> false
+1 < 2 #=> true
+
+# `===` și `!==` au strictețe mai mare cînd comparăm numere întregi și reale:
+1 == 1.0 #=> true
+1 === 1.0 #=> false
+
+# Putem compara de asemenea și date de diferite tipuri:
+1 < :salut #=> true
+
+# La compararea diferitor tipuri folosiți următoare prioritate:
+# număr < atom < referință < funcție < port < proces < tuple < listă < șir de caractere
+
+# Cităm pe Joe Armstrong în acest caz: "Ordinea actuală nu e importantă,
+dar că ordinea totală este bine definită este important."
+
+## ---------------------------
+## -- Ordinea execuției
+## ---------------------------
+
+# expresia `if`
+if false do
+ "Aceasta nu veți vedea niciodată"
+else
+ "Aceasta veți vedea"
+end
+
+# expresia opusă `unless`
+unless true do
+ "Aceasta nu veți vedea niciodată"
+else
+ "Aceasta veți vedea"
+end
+
+# Țineți minte potrivirea șabloanelor? Multe structuri în Elixir se bazează pe ea.
+
+# `case` ne permite să comparăm o valoare cu multe șabloane:
+case {:unu, :doi} do
+ {:patru, :cinci} ->
+ "Aceasta nu se potrivește"
+ {:unu, x} ->
+ "Aceasta se potrivește și atribuie lui `x` `:doi` în acest bloc"
+ _ ->
+ "Aceasta se va potrivi cu orice valoare"
+end
+
+# Simbolul `_` se numește variabila anonimă.
+# Folosiți-l pentru valori ce nu vă interesează.
+# De exemplu, dacă doar capul listei ne intereseaza:
+[cap | _] = [1,2,3]
+cap #=> 1
+
+# Pentru o citire mai bună putem scri:
+[cap | _coadă] = [:a, :b, :c]
+cap #=> :a
+
+# `cond` ne permite să verificăm multe condiții de odată.
+# Folosiți `cond` în schimbul la multe expresii `if`.
+cond do
+ 1 + 1 == 3 ->
+ "Aceasta nu veți vedea niciodată"
+ 2 * 5 == 12 ->
+ "Pe mine la fel"
+ 1 + 2 == 3 ->
+ "Aceasta veți vedea"
+end
+
+# Este obușnuit de setat ultima condiție cu `true`, care se va potrivi întotdeauna.
+cond do
+ 1 + 1 == 3 ->
+ "Aceasta nu veți vedea niciodată"
+ 2 * 5 == 12 ->
+ "Pe mine la fel"
+ true ->
+ "Aceasta veți vedea (este else în esență)"
+end
+
+# Blocul `try/catch` se foloște pentru prelucrarea excepțiilor.
+# Elixir suportă blocul `after` care se execută în orice caz.
+try do
+ throw(:salut)
+catch
+ mesaj -> "Am primit #{mesaj}."
+after
+ IO.puts("Sunt în blocul after.")
+end
+#=> Sunt în blocul after.
+# "Am primit salut"
+
+## ---------------------------
+## -- Module și Funcții
+## ---------------------------
+
+# Funcții anonime (atenție la punct la apelarea funcției)
+square = fn(x) -> x * x end
+square.(5) #=> 25
+
+# Ele de asemenea aceptă multe clauze și expresii de gardă.
+# Expresiile de gardă vă permit să acordați potrivirea șabloanelor,
+# ele sunt indicate după cuvîntul cheie `when`:
+f = fn
+ x, y when x > 0 -> x + y
+ x, y -> x * y
+end
+
+f.(1, 3) #=> 4
+f.(-1, 3) #=> -3
+
+# Elixir de asemenea oferă multe funcții incorporate.
+# Ele sunt accesibile în scopul curent.
+is_number(10) #=> true
+is_list("salut") #=> false
+elem({1,2,3}, 0) #=> 1
+
+# Puteți grupa cîteva funcții într-un modul. În interiorul modulului folosiți `def`
+# pentru a defini funcțiile necesare.
+defmodule Math do
+ def sum(a, b) do
+ a + b
+ end
+
+ def square(x) do
+ x * x
+ end
+end
+
+Math.sum(1, 2) #=> 3
+Math.square(3) #=> 9
+
+# Pentru a compila modulul nostru simplu Math îl salvăm ca `math.ex` și utilizăm `elixirc`.
+# în terminal: elixirc math.ex
+
+# În interiorul modulului putem defini funcții cu `def` și funcții private cu `defp`.
+defmodule PrivateMath do
+ # O funcție definită cu `def` este accesibilă pentru apelare din alte module,
+ def sum(a, b) do
+ do_sum(a, b)
+ end
+
+ # O funcție privată poate fi apelată doar local.
+ defp do_sum(a, b) do
+ a + b
+ end
+end
+
+PrivateMath.sum(1, 2) #=> 3
+PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
+
+# Declarația funcției de asemenea suportă expresii de gardă și multe clauze:
+defmodule Geometry do
+ def area({:rectangle, w, h}) do
+ w * h
+ end
+
+ def area({:circle, r}) when is_number(r) do
+ 3.14 * r * r
+ end
+end
+
+Geometry.area({:rectangle, 2, 3}) #=> 6
+Geometry.area({:circle, 3}) #=> 28.25999999999999801048
+Geometry.area({:circle, "not_a_number"}) #=> ** (FunctionClauseError)
+
+# Din cauza variabilelor imutabile, un rol important îl ocupă funcțiile recursive
+defmodule Recursion do
+ def sum_list([head | tail], acc) do
+ sum_list(tail, acc + head)
+ end
+
+ def sum_list([], acc) do
+ acc
+ end
+end
+
+Recursion.sum_list([1,2,3], 0) #=> 6
+
+# Modulele în Elixir suportă atribute, există atribute incorporate și
+# puteți adăuga altele.
+defmodule MyMod do
+ @moduledoc """
+ Este un atribut incorporat
+ """
+
+ @my_data 100 # Acesta e atributul nostru
+ IO.inspect(@my_data) #=> 100
+end
+
+# Operatorul |> permite transferarea rezultatului unei expresii din stînga
+# ca primul argument al unei funcții din dreapta.
+Range.new(1,10)
+|> Enum.map(fn x -> x * x end)
+|> Enum.filter(fn x -> rem(x, 2) == 0 end)
+#=> [4, 16, 36, 64, 100]
+
+## ---------------------------
+## -- Structuri și Excepții
+## ---------------------------
+
+# Structurile sunt extensii a dicționarelor ce au valori implicite,
+# verificări în timpul compilării și polimorfism
+defmodule Person do
+ defstruct name: nil, age: 0, height: 0
+end
+
+joe_info = %Person{ name: "Joe", age: 30, height: 180 }
+#=> %Person{age: 30, height: 180, name: "Joe"}
+
+# Acesarea cîmpului din structură
+joe_info.name #=> "Joe"
+
+# Actualizarea valorii cîmpului
+older_joe_info = %{ joe_info | age: 31 }
+#=> %Person{age: 31, height: 180, name: "Joe"}
+
+# Blocul `try` cu cuvîntul cheie `rescue` e folosit pentru a prinde excepții
+try do
+ raise "o eroare"
+rescue
+ RuntimeError -> "a fost prinsă o eroare runtime"
+ _error -> "aici vor fi prinse toate erorile"
+end
+#=> "a fost prinsă o eroare runtime"
+
+# Toate excepțiile au un mesaj
+try do
+ raise "o eroare"
+rescue
+ x in [RuntimeError] ->
+ x.message
+end
+#=> "o eroare"
+
+## ---------------------------
+## -- Concurența
+## ---------------------------
+
+# Concurența în Elixir se bazează pe modelul actor. Pentru a scrie programe
+# concurente avem nevoie de trei lucruri:
+# 1. Crearea proceselor
+# 2. Trimiterea mesajelor
+# 3. Primirea mesajelor
+
+# Un nou proces se crează folosind funcția `spawn`, care primește o funcție
+# ca argument.
+f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
+spawn(f) #=> #PID<0.40.0>
+
+# `spawn` întoarce identificatorul procesului pid, îl puteți folosi pentru
+# a trimite mesaje procesului. Mesajele se transmit folosind operatorul `send`.
+# Pentru primirea mesajelor se folosește mecanismul `receive`:
+
+# Blocul `receive do` este folosit pentru așteptarea mesajelor și prelucrarea lor
+# cînd au fost primite. Blocul `receive do` va procesa doar un singur mesaj primit.
+# Pentru a procesa mai multe mesaje, funcția cu blocul `receive do` trebuie
+# recursiv să se auto apeleze.
+
+defmodule Geometry do
+ def area_loop do
+ receive do
+ {:rectangle, w, h} ->
+ IO.puts("Aria = #{w * h}")
+ area_loop()
+ {:circle, r} ->
+ IO.puts("Aria = #{3.14 * r * r}")
+ area_loop()
+ end
+ end
+end
+
+# Compilați modulul și creați un proces
+pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
+# Un alt mod
+pid = spawn(Geometry, :area_loop, [])
+
+# Trimiteți un mesaj către `pid` care se va potrivi cu un șablon din blocul `receive`
+send pid, {:rectangle, 2, 3}
+#=> Aria = 6
+# {:rectangle,2,3}
+
+send pid, {:circle, 2}
+#=> Aria = 12.56000000000000049738
+# {:circle,2}
+
+# Interpretatorul este de asemenea un proces, puteți folosi `self`
+# pentru a primi identificatorul de proces:
+self() #=> #PID<0.27.0>
+
+## ---------------------------
+## -- Agenții
+## ---------------------------
+
+# Un agent este un proces care urmărește careva valori ce se schimbă.
+
+# Creați un agent cu `Agent.start_link`, transmițînd o funcție.
+# Stare inițială a agentului va fi rezultatul funcției.
+{ok, my_agent} = Agent.start_link(fn -> ["roșu", "verde"] end)
+
+# `Agent.get` primește numele agentului și o `fn` care primește starea curentă
+# Orice va întoarce `fn` este ceea ce veți primi înapoi:
+Agent.get(my_agent, fn colors -> colors end) #=> ["roșu", "verde"]
+
+# Actualizați starea agentului în acelaș mod:
+Agent.update(my_agent, fn colors -> ["albastru" | colors] end)
+```
+
+## Link-uri utile
+
+* [Primii pași](http://elixir-lang.org/getting-started/introduction.html) de pe [situl Elixir](http://elixir-lang.org)
+* [Documentația oficială Elixir](http://elixir-lang.org/docs/master/)
+* [Un mic conspect pe Elixir](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf)
+* [Cartea "Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) de Dave Thomas
+* [Cartea "Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) de Fred Hebert
+* [Cartea "Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) de Joe Armstrong