More Related Content Similar to ClojurianからみたElixir (20) More from Kent Ohashi (20) ClojurianからみたElixir3. 6 Lisp6 Lisp (*> ᴗ •*)(*> ᴗ •*)
Clojure : REST API
cf. BOOTH https://booth.pm/ja/items/1317263
8. e.g. 20e.g. 20
ClojureClojure
;; REPL (read-eval-print loop)
user> (->> (iterate (fn [[a b]] [b (+ a b)]) [0 1])
(map first)
(take 20))
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
9. ElixirElixir
# IEx (Interactive Elixir)
iex(1)> Stream.iterate({0, 1}, fn {a, b} -> {b, a+b} end) |>
...(1)> Stream.map(&elem(&1, 0)) |>
...(1)> Enum.take(20)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610,
987, 1597, 2584, 4181]
#
iex(2)> Stream.unfold({0, 1}, fn {a, b} -> {a, {b, a+b}} end) |>
...(2)> Enum.take(20)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610,
987, 1597, 2584, 4181]
12. cf. :cf. : Programming Clojure, Third EditionProgramming Clojure, Third Edition
14. cf. :cf. : Programming Elixir ≥ 1.6Programming Elixir ≥ 1.6
16. Lua, Factor, Elixir, Elm, Julia, MiniKanren, Idris
Seven More Languages in Seven WeeksSeven More Languages in Seven Weeks
17. Chapter 3, 4, 6: Clojure
Chapter 5: Elixir
Seven Concurrency Models in Seven WeeksSeven Concurrency Models in Seven Weeks
27. ClojureClojure
ElixirElixir
cf. (Clojure )
user> '(1 2 3) ; ※
(1 2 3)
user> [1 2 3] ;
[1 2 3]
user> {:a 1 :b 2 :c 3} ;
{:a 1, :b 2, :c 3}
iex(2)> [1, 2, 3] #
[1, 2, 3]
iex(3)> {1, 2, 3} #
{1, 2, 3}
iex(4)> %{a: 1, b: 2, c: 3} #
%{a: 1, b: 2, c: 3}
28. //
ClojureClojure
ElixirElixir
user> (ns example) ; `example`
nil
example> (defn square [x] ; `square`
(* x x))
#'example/square
example> (in-ns 'user) ; `user`
#namespace[user]
user>
iex(5)> defmodule Example do # `Example`
...(5)> def square(x) do # `square`
...(5)> x * x
...(5)> end
...(5)> end
{:module, Example,
<<70, 79, 82, 49, 0, 0, 4, 100, 66, 69, 65, 77, 65, 116, 85, 56,
0, 0, 0, 14, 14, 69, 108, 105, 120, 105, 114, 46, 69, 120, 97,
101, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:square, 1}}
29. ClojureClojure
ElixirElixir
user> (example/square 3) ; `example` `square`
9
user> (map example/square (range 1 (inc 10)))
(1 4 9 16 25 36 49 64 81 100)
iex(6)> Example.square(3) # `Example` `square`
9
iex(7)> Enum.map(1..10, &Example.square/1)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
30. //
ClojureClojure
ElixirElixir
user> (map (fn [x] (* x x)) (range 1 (inc 10)))
(1 4 9 16 25 36 49 64 81 100)
user> (map #(* % %) (range 1 (inc 10)))
(1 4 9 16 25 36 49 64 81 100)
iex(8)> Enum.map(1..10, fn(x) -> x * x end)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
iex(8)> Enum.map(1..10, &(&1 * &1))
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
31. >>>> (threading macro) vs(threading macro) vs |>|> (pipe operator)(pipe operator)
ClojureClojure
ElixirElixir
cf.
user> (->> (range 1 (inc 10))
(map #(* % %))
(filter odd?)
(apply +))
165
iex(9)> require Integer
Integer
iex(10)> 1..10 |>
...(10)> Enum.map(&(&1 * &1)) |>
...(10)> Enum.filter(&Integer.is_odd/1) |>
...(10)> Enum.sum
165
34. //
ClojureClojure
user> (defrecord Triangle [x h] ; `Triangle`
Shape ;
(area [{:keys [x h]}] (/ (* x h) 2)))
user.Triangle
user> (area (map->Triangle {:x 3 :h 2}))
3
user> (defrecord Rectangle [x y] ; `Rectangle`
Shape ;
(area [{:keys [x y]}] (* x y)))
user.Rectangle
user> (area (map->Rectangle {:x 2 :y 3}))
6
35. ElixirElixir
iex(2)> defmodule Triangle do # `Triangle`
...(2)> defstruct [:x, :h]
...(2)> end
{:module, Triangle, ..., %Triangle{h: nil, x: nil}}
iex(3)> defimpl Shape, for: Triangle do #
...(3)> def area(%Triangle{x: x, h: h}), do: x * h / 2
...(3)> end
{:module, Shape.Triangle, ..., {:__impl__, 1}}
iex(4)> Shape.area(%Triangle{x: 3, h: 2})
3.0
iex(5)> defmodule Rectangle do # `Rectangle`
...(5)> defstruct [:x, :y]
...(5)> end
{:module, Rectangle, ..., %Rectangle{x: nil, y: nil}}
iex(6)> defimpl Shape, for: Rectangle do #
...(6)> def area(%Rectangle{x: x, y: y}), do: x * y
...(6)> end
{:module, Shape.Rectangle, ..., {:__impl__, 1}}
iex(7)> Shape.area(%Rectangle{x: 2, y: 3})
6
36. ClojureClojure
ElixirElixir
user> (defrecord Circle [r]) ; `Circle`
user.Circle
user> (area (map->Circle {:r 3}))
Execution error (IllegalArgumentException) at user/eval5412$fn$G
(REPL:47).
No implementation of method: :area of protocol: #'user/Shape fou
nd for class: user.Circle
iex(8)> defmodule Circle do # `Circle`
...(8)> defstruct [:r]
...(8)> end
{:module, Circle, ..., %Circle{r: nil}}
iex(9)> Shape.area(%Circle{r: 3})
** (Protocol.UndefinedError) protocol Shape not implemented for
%Circle{r: 3}
iex:2: Shape.impl_for!/1
iex:3: Shape.area/1
37. ClojureClojure
ElixirElixir
user> (extend-protocol Shape ;
Circle
(area [{:keys [r]}] (* Math/PI r r)))
nil
user> (area (map->Circle {:r 3}))
28.274333882308138
iex(10)> defimpl Shape, for: Circle do #
...(10)> def area(%Circle{r: r}), do: :math.pi() * r * r
...(10)> end
{:module, Shape.Circle, ..., {:__impl__, 1}}
iex(11)> Shape.area(%Circle{r: 3})
28.274333882308138
39. ASTAST
ClojureClojure
user> '(when (= 1 1)
(println "Truthy!"))
(when (= 1 1) (println "Truthy!"))
;;
user> (quote
(when (= 1 1)
(println "Truthy!")))
(when (= 1 1) (println "Truthy!"))
40. ElixirElixir
iex(1)> quote do
...(1)> if 1 == 1 do
...(1)> IO.puts "Truthy!"
...(1)> end
...(1)> end
{:if, [context: Elixir, import: Kernel],
[
{:==, [context: Elixir, import: Kernel], [1, 1]},
[
do: {{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts
]}, [],
["Truthy!"]}
]
]}
42. ElixirElixir
iex(2)> defmodule Example do
...(2)> defmacro my_unless(test, do: body) do
...(2)> quote do
...(2)> if unquote(test), do: nil, else: unquote(body)
...(2)> end
...(2)> end
...(2)> end
{:module, Example, ..., {:my_unless, 2}}
46. ElixirElixir
iex(6)> quote do
...(6)> Example.my_unless 1 == 2 do
...(6)> IO.puts "Falsy!"
...(6)> 42
...(6)> end
...(6)> end |> Macro.expand_once(__ENV__) |> # 1
...(6)> Macro.to_string |> IO.puts # AST
if(1 == 2) do
nil
else
IO.puts("Falsy!")
42
end
:ok
48. vs
cf. (by Rich Hickey)
REPL
cf. REPL (REPL-driven development)
Simple Made Easy