Presentation from DC |> Elixir, March 19, 2019. Covered transitioning from Ruby on Rails to Elixir and Phoenix, and why developers want to make that transition, and why management should be supportive of that transition.
5. Who Am I?
• Software Developer
• Director of Development at SmartLogic
6. Who Am I?
• Software Developer
• Director of Development at SmartLogic
• Rails developer for 12 years
7. Who Am I?
• Software Developer
• Director of Development at SmartLogic
• Rails developer for 12 years
• Elixir convert since Summer 2016
8. Who Am I?
• Software Developer
• Director of Development at SmartLogic
• Rails developer for 12 years
• Elixir convert since Summer 2016
• Organizer of the Baltimore Elixir and Erlang
Meetup
39. Ecto
Changesets
• Ever try and run just some ActiveRecord
validations depending on the current user?
• Ever have a set of validations dependent on
data state?
40. Ecto
Changesets
def edit_self_changeset(user, params %{}) do
user
|> cast(params, [:name, :age])
|> validate_required([:name])
|> validate_inclusion(:age, 18..100)
end
def admin_edit_changeset(user, params %{}) do
user
|> cast(params, [:name, :email, :age])
|> validate_required([:name, :email])
|> validate_format(:email, ~r/@/)
|> validate_inclusion(:age, 18..100)
|> unique_constraint(:email)
end
41. Ecto
Changesets
def edit_self_changeset(user, params %{}) do
user
|> cast(params, [:name, :age])
|> validate_required([:name])
|> validate_inclusion(:age, 18..100)
end
def admin_edit_changeset(user, params %{}) do
user
|> cast(params, [:name, :email, :age])
|> validate_required([:name, :email])
|> validate_format(:email, ~r/@/)
|> validate_inclusion(:age, 18..100)
|> unique_constraint(:email)
end
42. Ecto
Changesets
def edit_self_changeset(user, params %{}) do
user
|> cast(params, [:name, :age])
|> validate_required([:name])
|> validate_inclusion(:age, 18..100)
end
def admin_edit_changeset(user, params %{}) do
user
|> cast(params, [:name, :email, :age])
|> validate_required([:name, :email])
|> validate_format(:email, ~r/@/)
|> validate_inclusion(:age, 18..100)
|> unique_constraint(:email)
end
43. Ecto
Changesets
def edit_self_changeset(user, params %{}) do
user
|> cast(params, [:name, :age])
|> validate_required([:name])
|> validate_inclusion(:age, 18..100)
end
def admin_edit_changeset(user, params %{}) do
user
|> cast(params, [:name, :email, :age])
|> validate_required([:name, :email])
|> validate_format(:email, ~r/@/)
|> validate_inclusion(:age, 18..100)
|> unique_constraint(:email)
end
44. Phoenix
Param Matching
def show(conn, %{"user_params" => user_params} = params) do
end
def show(conn, %{"admin_params" => admin_params} = params) do
end
47. Phoenix
View Code
• Not a pile of global namespace helpers
• Good encapsulation of presentation logic
48. Gen Server
No need for external workers
GenServer.cast(MyWorker, {:process, this_thing})
def handle_cast({:process, this_thing}, state) do
# do work
{:noreply, state}
end
49. Gen Server
No need for external workers
GenServer.cast(MyWorker, {:process, this_thing})
def handle_cast({:process, this_thing}, state) do
# do work
{:noreply, state}
end
50. Gen Server
No need for external workers
GenServer.cast(MyWorker, {:process, this_thing})
def handle_cast({:process, this_thing}, state) do
# do work
{:noreply, state}
end
55. What does Elixir bring?
• Ruby-inspired syntax
• Meta programming
56. What does Elixir bring?
• Ruby-inspired syntax
• Meta programming
• Polymorphism via protocols
57. What does Elixir bring?
• Ruby-inspired syntax
• Meta programming
• Polymorphism via protocols
• Great tooling
58. What does Elixir bring?
• Ruby-inspired syntax
• Meta programming
• Polymorphism via protocols
• Great tooling
• Better code organization facilities than Erlang
59. What does Elixir bring?
• Ruby-inspired syntax
• Meta programming
• Polymorphism via protocols
• Great tooling
• Better code organization facilities than Erlang
• Erlang functions can be called from Elixir
62. What does Elixir bring?
• Lightweight and isolated concurrency
• Shared nothing concurrent programming
63. What does Elixir bring?
• Lightweight and isolated concurrency
• Shared nothing concurrent programming
• Lazy and async collections
64. What does Elixir bring?
• Lightweight and isolated concurrency
• Shared nothing concurrent programming
• Lazy and async collections
• Pattern matching
65. What does Elixir bring?
• Lightweight and isolated concurrency
• Shared nothing concurrent programming
• Lazy and async collections
• Pattern matching
• Unicode support and UTF-8 strings
68. Scaleable and Fault-tolerant
• Isolation means each process is garbage
collected independently
• This means less system wide pauses.
69. Scaleable and Fault-tolerant
• Isolation means each process is garbage
collected independently
• This means less system wide pauses.
• Things go wrong. Especially with network or
disk activity.
70. Scaleable and Fault-tolerant
• Isolation means each process is garbage
collected independently
• This means less system wide pauses.
• Things go wrong. Especially with network or
disk activity.
• Supervisor processes are instructed in how to
maintain your application
73. Stable and Extensible
• Only 1 planned language deprecation for 2.0
• No planned timeline for 2.0
74. Stable and Extensible
• Only 1 planned language deprecation for 2.0
• No planned timeline for 2.0
• The core team believes all the right
fundamentals are in place
78. Speed (Throughput)
• Sure, it isn't C
• For a Rails shop, that isn't the benchmark
• Multi-thread by default, no global lock
79. Speed (Throughput)
• Sure, it isn't C
• For a Rails shop, that isn't the benchmark
• Multi-thread by default, no global lock
• Fast garbage collection
80. Speed (Throughput)
• Sure, it isn't C
• For a Rails shop, that isn't the benchmark
• Multi-thread by default, no global lock
• Fast garbage collection
• All means high throughput web apps
89. Costs
All of the items we've discussed have a real impact on:
• Development pace, build from pure functions
90. Costs
All of the items we've discussed have a real impact on:
• Development pace, build from pure functions
• Developer focus, cognitive load of functions over
objects
91. Costs
All of the items we've discussed have a real impact on:
• Development pace, build from pure functions
• Developer focus, cognitive load of functions over
objects
• Ease of implementing new features
92. Costs
All of the items we've discussed have a real impact on:
• Development pace, build from pure functions
• Developer focus, cognitive load of functions over
objects
• Ease of implementing new features
• Test quality and speed
93. Costs
All of the items we've discussed have a real impact on:
• Development pace, build from pure functions
• Developer focus, cognitive load of functions over
objects
• Ease of implementing new features
• Test quality and speed
• Bug rates
94. Costs
All of the items we've discussed have a real impact on:
• Development pace, build from pure functions
• Developer focus, cognitive load of functions over
objects
• Ease of implementing new features
• Test quality and speed
• Bug rates
• Maintainability
103. Paradigm Shift?
Functional Programming
• Might take some adjustment
• Fits your use case more than you expect, it is
about the data
• Makes writing great tests easy
104. Paradigm Shift?
Functional Programming
• Might take some adjustment
• Fits your use case more than you expect, it is
about the data
• Makes writing great tests easy
• Makes writing fast tests easy
106. Mix and IEx
Mix - A great build tool for dependency
management and other tasks
IEx - An interactive shell
107. Docs, Tests, and DocTests
Documentation - a first class citizen in the
Elixir ecosystem
Tests - Testing libraries built into the language
with ExUnit
DocTests - A hybrid of testing and documentation