Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

of

Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 1 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 2 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 3 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 4 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 5 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 6 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 7 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 8 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 9 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 10 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 11 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 12 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 13 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 14 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 15 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 16 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 17 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 18 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 19 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 20 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 21 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 22 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 23 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 24 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 25 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 26 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 27 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 28 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 29 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 30 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 31 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 32 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 33 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 34 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 35 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 36 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 37 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 38 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 39 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 40 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 41 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 42 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 43 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 44 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 45 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 46 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 47 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 48 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 49 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 50 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 51 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 52 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 53 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 54 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 55 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 56 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 57 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 58 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 59 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 60 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 61 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 62 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 63 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 64 Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir" Slide 65
Upcoming SlideShare
What to Upload to SlideShare
Next
Download to read offline and view in fullscreen.

0 Likes

Share

Download to read offline

Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir"

Download to read offline

Seit Prozessoren nicht mehr schneller sondern nur noch mehr werden, werden uns häufig Konzepte aus der Welt der funktionalen Programmierung als Lösung versprochen. Aber wer hat schon Lust, Quellcode zu schreiben, dessen zweite Hälfte aus schließenden Klammern besteht?
Funktional programmieren aber mit modernem Syntax und solidem Unterbau. Das verspricht die Programmiersprache Elixir.
Dieser Vortrag wird zum einen die Grundlagen der Sprache vorstellen und wo vorhanden Parallelen zum Java-Umfeld aufzeigen.
Zum anderen wird gezeigt, warum Anwendungen auf Basis von Elixir die Bezeichnungen „Serverless“ und „Microservices“ eher verdienen als andere.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir"

  1. 1. "Hallo " <> "Elixir" Mirko Zeibig (mirko.zeibig@t-systems.com)
  2. 2. Agenda ● Basis ● Sprache ● OTP ● Ausblick
  3. 3. BEAM [Bogdan‘s|Björn‘s] Erlang Abstract Machine JVM Java Virtual Machine Elixir • mix • hex • ExUnit Compiler, Tools, Runtime Library Compiler, Tools, Runtime Library • Gradle • Maven • JUnit OTP JDK
  4. 4. Sprache ● Funktionale Sprache ● Dynamisches Typsystem ● Module ● Garbage Collection ● REPL (iex)
  5. 5. arity ● Anzahl der Parameter einer Funktion – alle Parameter auch optionale Parameter mit default ● ähnlich der Methodensignatur in Java – da Parameter keine Typen haben ● [Modulname].[Funktionsname]/[Parameterzahl] – Enum.map/2 – Enum.map_join/2 – Enum.map_join/3 – File.write/2
  6. 6. iex ● interaktive shell ● integrierte Hilfe ● h/0, h/1 ● i/1 ● c/1 ● r/1
  7. 7. :observer.start
  8. 8. Funktionen ● named function def add(a, b 1) do a + b end def square(a) do a * a end add(40, 2) add(41) square(3)
  9. 9. Funktionen ● anonymous function f = fn x -> x * x end f.(3)
  10. 10. Funktionen ● function capturing f = &square(&1) f.(3)
  11. 11. Funktionen ● guard clauses def gt(a, b) when a > b do :gt end def gt(a, b) when a < b do :lt end def gt(a, b) when a == b do :eq end
  12. 12. Module ● alle named functions müssen in Module ● Schachtelung möglich defmodule DevDay.Functions do def add(a, b 1) do a + b end defmodule MoreFunctions do def square(a) do a * a end end end
  13. 13. Datentypen - immutable ● string ● integer ● float ● boolean ● atom ● range ● tuple ● list ● map ● struct ● binary ● pid ● references
  14. 14. integer ● Haben keine fixe Größe ● 2019 ● 0xbabe ● 0x765 ● 0b1011 ● 1_000_000
  15. 15. integer
  16. 16. float ● IEEE 754 double precision ● 1.0 ● 3.14159 ● 0.314159e1 ● 314159.0e-5
  17. 17. :atoms ● Konstanten deren Name der Wert ist ● :devday ● :devday2019 ● :devday@2019 ● :devday! ● :hugbúnaðurVerktaki ● :"Pippilotta Viktualia … Efraimsdotter Långstrump"
  18. 18. range ● Von – bis Werte ● 1..10 ● 10..1 ● 0x13..0o777
  19. 19. tuples ● Geordnete Menge von Werten ● {42, :devday, "Radebeul"} ● File.read("existing.file") {:ok, "inhalt der Datei"} ● File.read("nonexisting.file") {:error, :enoent}
  20. 20. Keyword lists ● Liste von Zwei-Element-Tuples ● Keys sind Atome und nicht eindeutig ● [foo: "bar", hello: "world"] ● [{:foo, "bar"}, {:hello, "world"}] ● x = [foo: "bar", hello: "world"] ● x[:hello] "world"
  21. 21. List ● Verkettete Liste beliebiger Werte ● list = [42, :devday, "Radebeul"] ● ["hello"] ++ list ["hello", 42, :devday, "Radebeul"] ● list ++ ["world"] [42, :devday, "Radebeul", "world"]
  22. 22. List ● list = [42, :devday, "Radebeul"] ● list -- [42] [:devday, "Radebeul"] ● hd(list) 42 ● tl(list) [:devday, "Radebeul"] ● ["hallo" | [:devday, "Radebeul"]] ["hallo", :devday, "Radebeul"]]
  23. 23. Map ● Key-Value-Speicher ● map = %{:answer => 42, "was" => :devday, "wo" => "Radebeul"} ● map[:answer] 42 ● map["was"] :devday ● map["wo"] "Radebeul"
  24. 24. Map ● map = %{answer: 42, was: :devday, wo: "Radebeul"} ● map.answer 42 ● map.was :devday ● map.wo "Radebeul" ● %{map | answer: 3.14}
  25. 25. Enum (Module) ● bietet Funktionen zu Arbeit mit Enumerables – each/2 – filter/2 – map/2 – reduce/2 – join/2 – empty?/1 – any?/2 – all?/2
  26. 26. |> (pipe) speakers = ["Mirko", "Emil", "Ida", "Lina", "Alfred", "Alma", "Anton", "Lukas", "Lotta"] speakers |> Enum.filter(fn s -> String.length(s) > 3 end) |> Enum.map(fn s -> String.upcase(s) end) |> Enum.sort() |> Enum.each(fn s -> IO.puts(s) end) List<String> speakers = Arrays.asList("Mirko", "Emil", "Ida", "Lina", "Alfred", "Alma", "Anton", "Lukas", "Lotta"); speakers.stream() .filter(s -> s.length() > 3) .map(s -> s.toUpperCase()) .sorted() .peek(s -> System.out.println(s));
  27. 27. |> (pipe) speakers = ["Mirko", "Emil", "Ida", "Lina", "Alfred", "Alma", "Anton", "Lukas", "Lotta"] speakers |> Enum.filter(fn s -> String.length(s) > 3 end) |> Enum.map(fn s -> String.upcase(s) end) |> Enum.sort() |> Enum.each(fn s -> IO.puts(s) end) List<String> speakers = Arrays.asList("Mirko", "Emil", "Ida", "Lina", "Alfred", "Alma", "Anton", "Lukas", "Lotta"); speakers.stream() .filter(s -> s.length() > 3) .map(s -> s.toUpperCase()) .sorted() .peek(s -> System.out.println(s)) .collect(Collectors.toList());
  28. 28. |> (pipe) speakers = ["Mirko", "Emil", "Ida", "Lina", "Alfred", "Alma", "Anton", "Lukas", "Lotta"] speakers |> Enum.filter(&String.length(&1) > 3) |> Enum.map(&String.upcase(&1)) |> Enum.sort() |> Enum.each(&IO.puts(&1)) List<String> speakers = Arrays.asList("Mirko", "Emil", "Ida", "Lina", "Alfred", "Alma", "Anton", "Lukas", "Lotta"); speakers.stream() .filter(s -> s.length() > 3) .map(String::toUpperCase) .sorted() .peek(System.out::println) .collect(Collectors.toList());
  29. 29. Struct defmodule DevDay.Speaker do alias __MODULE__ defstruct [:name, :age, :sessions] def new(name) do %Speaker{name: name} end end
  30. 30. Strings ● String ist eigentlich kein eigener Typ ● Zwei Typen von Strings ● "" vs. '' ● UTF-8 ● String interpolation – "Hallo #{dd}!"
  31. 31. Strings – single quoted ● Character Lists ● Liste von Integer Codepoints – 'DevDay' → [68,101,118,68,97,121] – 'Måla' → [77, 229, 108, 97] – 'noël' → [110, 111, 101, 776, 108] ● es funktionieren alle Funktionen auf Listen ● wird für Erlang-Interoperabilität benötigt
  32. 32. Strings – double quoted ● Binaries ● Sequenz von Bits – "DevDay" → <<68,101,118,68,97,121>> – "Måla" → <<77, 229, 108, 97>> – "noël" → <<110, 111, 101, 776, 108>> ● dies sind die Standard-Strings
  33. 33. String - noël ● String.codepoints "noeu0308l" ["n","o","e","¨", "l"] ● String.graphemes "noeu0308l" ["n", "o", "ë", "l"] ● String.reverse "noeu0308l" "lëon" ● String.slice("noeu0308l", 0, 3) "noë" ● String.length "noeu0308l" 4
  34. 34. String – hä? ● "hä?" == "hau0308?" false ● "hä?" == "hä?" true ● String.equivalent?("hä?", "hau0308?") true ● String.equivalent?("hä?", "hä?") true
  35. 35. Pattern Matching ● = ist in Elixir 'match operator' ● wenn linke und rechte Seite matchen → alles ok ● wenn nicht → MatchError ● enthält linke Seite Variablen, werden bei match Werte zugewiesen ● funktioniert in Elixir fast überall
  36. 36. Pattern Matching ● 1 = 1 1 ● x = 1 1 ● 1 = x 1 ● 2 = x ** (MatchError) no match of right hand side value: 1
  37. 37. Pattern Matching ● {a, b, c} = {"Hallo", "DevDay", 2019} {"Hallo", "DevDay", 2019} ● a "Hallo" ● b "DevDay" ● {a, b, 2018} = {"Hallo", "DevDay", 2019} ** (MatchError) no match of right hand side value: {"Hallo", "DevDay", 2019}
  38. 38. Pattern Matching ● [a, b, c] = [3, 14, 42] [3, 14, 42] ● [head | tail] = [3, 14, 42] [3, 14, 42] ● head 3 ● tail [14, 42] ● [head | tail] = [] ** (MatchError) no match of right hand side value: []
  39. 39. Pattern Matching - case def casematch(t) do case t do {1, 2, 3} -> "das paßt nicht" {3, 14, x} -> "Die Antwort ist #{x}." _ -> "der Rest" end end IO.puts casematch({1, 2, 3}) IO.puts casematch({3, 14, 42}) IO.puts casematch("DevDay")
  40. 40. Pattern Matching - case def file_match() do case File.read("/devday/speakers.txt") do {:ok, data} -> tuwas(data) {:error, reason} -> "#{:file.format_error(reason)}" end end iex(1)> DevDay.Match.file_match "no such file or directory"
  41. 41. Pattern Matching - function def sum([]) do 0 end def sum([head|tail]) do head + sum(tail) end iex(3)> DevDay.Match.sum([1,2,3,4,5]) 15
  42. 42. Prozesse ● Wo man in Java ein Objekt erzeugt, startet man in Elixir einen Prozeß. ● keine OS-Prozesse oder -Threads ● sehr leichtgewichtig ● von VM verwaltet ● isoliert – keine gemeinsamen Resourcen ● kein lokales Errorhandling ● kommuniyieren über Messages
  43. 43. Prozesse defmodule DevDay.HelloProc do def simple_hallo() do IO.puts "Hallo" end end iex(6)> DevDay.HelloProc.simple_hallo Hallo :ok iex(7)> spawn(DevDay.HelloProc, :simple_hallo, []) Hallo #PID<0.155.0>
  44. 44. Prozesse - Messages def hallo() do receive do {sender, msg} -> send(sender, {:ok, "Hallo, #{msg}!"}) end end iex> pid = spawn(DevDay.HelloProc, :hallo, []) iex> send(pid, {self(), "DevDay"}) iex> receive do {:ok, message} -> IO.puts message end Hallo, DevDay! :ok
  45. 45. Prozesse - link ● spawn/3 - startet neuen Prozeß – im Fehlerfall wird er beendet ● spawn_link/3 - startet neuen Prozeß und verknüpft ihn mit dem Parent – im Fehlerfall wird der verknüpfte Prozeß mit beendet ● spawn_monitor/3 – startet neuen Prozeß und überwacht ihn – im Fehlerfall wird eine Nachricht verschickt
  46. 46. Prozesse - link
  47. 47. Prozesse - link ? !
  48. 48. Prozesse - state ● Daten sind unveränderlich ● Funktionen sind stateless ● Objekte gibt es nicht ● Wer hält einen state? → Prozesse
  49. 49. defmodule DevDay.Simple do def start_link do spawn_link(__MODULE__, :loop, [%{}]) end def loop(state) do receive do {:add, name} -> new_state = Map.put(state, name, Speaker.new(name)) loop(new_state) {:remove, name} -> new_state = Map.delete(state, name) loop(new_state) {:list, pid} -> send(pid, {:ok, state}) loop(state) end end end
  50. 50. GenServer ● Abstraktion für Server ● Verarbeitet Nachrichten synchron/asynchron ● Kümmert sich um – Loop – State – Start – Stop ● Definiert Callbacks
  51. 51. defmodule DevDay.SpeakerServer do use GenServer def init(:ok) do {:ok, %{}} end def handle_cast({:add, name}, state) do new_state = Map.put(state, name, DevDay.Speaker.new(name)) {:noreply, new_state} end def handle_cast({:remove, name}, state) do new_state = Map.delete(state, name) {:noreply, new_state} end def handle_call(:speakers, _from, state) do {:reply, state, state} end end
  52. 52. GenServer - Client iex(1)> {:ok, pid} = GenServer.start_link(DevDay.SpeakerServer, :ok) {:ok, #PID<0.212.0>} iex(2)> GenServer.call(pid, :speakers) %{} iex(3)> GenServer.cast(pid, {:add, "Mirko"}) :ok iex(4)> GenServer.call(pid, :speakers) %{"Mirko" => %DevDay.Speaker{age: nil, name: "Mirko", sessions: nil}} iex(5)> GenServer.cast(pid, {:remove, "Mirko"}) :ok
  53. 53. defmodule DevDay.SpeakerServer do use GenServer @name __MODULE__ def start_link() do GenServer.start_link(__MODULE__, :ok, name: @name) end def add(name) do GenServer.cast(@name, {:add, name}) end def remove(name) do GenServer.cast(@name, {:remove, name}) end def speakers() do GenServer.call(@name, :speakers) end ... end
  54. 54. GenServer - Client iex(1)> DevDay.SpeakerServer.start_link {:ok, #PID<0.212.0>} iex(2)> DevDay.SpeakerServer.speakers %{} iex(3)> DevDay.SpeakerServer.add("Mirko") :ok iex(4)> DevDay.SpeakerServer.speakers %{"Mirko" => %DevDay.Speaker{age: nil, name: "Mirko", sessions: nil}} iex(5)> DevDay.SpeakerServer.remove("Mirko") :ok
  55. 55. Supervisor ● Spezieller Prozeß ● überwacht andere Prozesse ● startet beendete Prozesse bei Bedarf neu ● Regeln für Neustart können definiert werden – Welche Prozesse? – Wie oft pro Zeit? – Unter welche Bedingungen? ● Kann Kindprozesse auch dynamisch starten.
  56. 56. Supervisor defmodule DevDay.Supervisor do use Supervisor def start_link do Supervisor.start_link(__MODULE__, []) end def init(_) do children = [ worker(DevDay.SpeakerServer, []) ] supervise(children, strategy: :one_for_one) end end
  57. 57. Supervisor S S S S !
  58. 58. Nodes ● eine VM mit Namen ● mehrere pro Rechner ● verteilt auf mehrere Rechner ● können untereinander kommunizieren ● iex --sname node1 -S mix ● Node.self/0 ● Node.list/0 ● Node.connect/1
  59. 59. Nodes - node1 ● iex --sname node1 -S mix ● iex(node1@mzlv110)1> Node.self :node1@mzlv110 ● iex(node1@mzlv110)2> DevDay.HelloProc.simple_hallo Hallo :ok
  60. 60. Nodes - node2 ● iex --sname node2 ● iex(node2@mzlv110)1> Node.spawn(:node1@mzlv110, DevDay.HelloProc, :simple_hallo, []) Hallo #PID<10739.247.0> ● iex(node2@mzlv110)2> Node.list [:node1@mzlv110] ● iex(node2@mzlv110)3> DevDay.HelloProc.simple_hallo ** (UndefinedFunctionError) function DevDay.HelloProc.simple_hallo/0 is undefined (module DevDay.HelloProc is not available) DevDay.HelloProc.simple_hallo()
  61. 61. Ausblick - OTP ● GenServer ● Agent ● Task ● ETS (Erlang Term Storage) ● Mnesia (heavy duty real-time distributed database) ● :gen_tcp ● GenStage ● GenStateMachine / :gen_statem ● otp_app
  62. 62. Ausblick - ecto ● Datenzugriff ● Zugriff über Repositories und Changesets ● Daten sind Structs ● Datendefinitionen als Schemas / Migrations ● Build-in PostgreSQL und MySQL
  63. 63. Ausblick - Phoenix ● Web Framework ● MVC ● Templates ● Routing ● Channels – stateful connections – pro Connection ein Prozeß – Websockets
  64. 64. Links ● https://elixir-lang.org/ ● https://elixir-lang.org/getting-started ● https://elixirschool.com/ ● https://hexdocs.pm/ ● https://exercism.io/tracks/elixir ● https://alchemist.camp/ ● http://www.erlang.org/
  65. 65. Ende Fragen?

Seit Prozessoren nicht mehr schneller sondern nur noch mehr werden, werden uns häufig Konzepte aus der Welt der funktionalen Programmierung als Lösung versprochen. Aber wer hat schon Lust, Quellcode zu schreiben, dessen zweite Hälfte aus schließenden Klammern besteht? Funktional programmieren aber mit modernem Syntax und solidem Unterbau. Das verspricht die Programmiersprache Elixir. Dieser Vortrag wird zum einen die Grundlagen der Sprache vorstellen und wo vorhanden Parallelen zum Java-Umfeld aufzeigen. Zum anderen wird gezeigt, warum Anwendungen auf Basis von Elixir die Bezeichnungen „Serverless“ und „Microservices“ eher verdienen als andere.

Views

Total views

381

On Slideshare

0

From embeds

0

Number of embeds

200

Actions

Downloads

3

Shares

0

Comments

0

Likes

0

×