SlideShare a Scribd company logo
Functional Design Patterns
Tomasz Kowal
Why this talk?
Why this talk?
Syntax
Pattern matching
and pin operator
Basic recursion, map,
reduce, tail recursion
Concurrency,
distributed systems
Very basic functional design patterns
Very basic functional design patterns
Very basic functional design patterns
Very basic functional design patterns
Why this talk?
Syntax
Pattern matching
and pin operator
Basic recursion, map,
reduce, tail recursion
Concurrency,
distributed systems
Very basic functional design patterns
Very basic functional design patterns
Why this talk?
Syntax
Pattern matching
and pin operator
Basic recursion, map,
reduce, tail recursion
How do I build stuff?
Questions
Please ask during the talk!
1 + 1
Very basic functional design patterns
Patterns
1. Use single data structure that is your single
source of truth and many small functions
operating on it.
2. Separate pure and impure parts.
Pipe operator
two = double(1)
two =
1
|> double()
Pipe operator
five = add(2, 3)
five =
2
|> add(3)
Pipe operator
one = 1
two = double(one)
four = double(two)
1
|> double()
|> double()
Pipe operator
list = [1, 10, 3, 12, 42]
Pipe operator
list = [1, 10, 3, 12, 42]
filtered = Enum.filter(
list,
&Integer.is_even/1
)
Pipe operator
list = [1, 10, 3, 12, 42]
filtered = Enum.filter(
list,
&Integer.is_even/1
)
sorted = Enum.sort(filtered)
Pipe operator
sorted =
list
|> Enum.filter(&Integer.is_even/1)
|> Enum.sort()
Pipe operator
sorted =
list
|> Enum.filter(&Integer.is_even/1)
|> Enum.sort()
sorted = Enum.sort(Enum.filter(list,
&Integer.is_even/1))
Pipe operator
def sorted_evens(list) do
list
|> Enum.filter(&Integer.is_even/1)
|> Enum.sort()
end
Pipe operator
def two_smallest_evens(list) do
list
|> sorted_evens()
|> Enum.take(2)
end
list list list
transform
list list list
transform
„Debugging” with IO.inspect
def two_smallest_evens(list) do
list
|> sorted_evens()
|> IO.inspect()
|> Enum.take(2)
end
Data validation problem
● Current value:
%User{name: „Tom”, age: 29}
● Things that we want to change:
%{age: 30}
● Is the data valid? If not – why?
Ecto.Changeset fields
● valid?
● data
● params
● changes
● errors
● ...
Validating with Ecto.Changeset
user
|> cast(params, [:name, :email, :age])
user changeset
cast
Validating with Ecto.Changeset
user
|> cast(params, [:name, :email, :age])
|> validate_required([:name, :email])
user changeset changeset
cast validate1
Validating with Ecto.Changeset
user
|> cast(params, [:name, :email, :age])
|> validate_required([:name, :email])
|> validate_format(:email, ~r/@/)
user changeset changeset changeset
cast validate1 validate2
Custom validator
● Lets say we have an event with start
date and end date.
● We want to make sure that start date is
not after end date.
Custom validator
def validate_interval(changeset, start, end)
do
end
Custom validator
def validate_interval(changeset, start, end) do
start_date = get_field(changeset, start)
end_date = get_field(changeset, end)
end
get_field
● Looks for value in params
● Looks for value in original data
Custom validator
def validate_interval(changeset, start, end) do
start_date = get_field(changeset, start)
end_date = get_field(changeset, end)
case Date.compare(start_date, end_date) do
:gt ->
_otherwise ->
end
end
Custom validator
def validate_interval(changeset, start, end) do
start_date = get_field(changeset, start)
end_date = get_field(changeset, end)
case Date.compare(start_date, end_date) do
:gt ->
_otherwise -> changeset
end
end
Custom validator
def validate_interval(changeset, start, end) do
start_date = get_field(changeset, start)
end_date = get_field(changeset, end)
case Date.compare(start_date, end_date) do
:gt -> add_error(changeset, start, "…")
_otherwise -> changeset
end
end
add_error
● appends new error to list of errors
● changes valid? to false
● takes changeset and returns changeset
Custom validator
def validate_interval(changeset, start, end) do
start_date = get_field(changeset, start)
end_date = get_field(changeset, end)
case Date.compare(start_date, end_date) do
:gt -> add_error(changeset, start, "…")
_otherwise -> changeset
end
end
Composing validators
def validate_address(cs, street, zip) do
cs
|> validate_street(street)
|> validate_zipcode(zip)
end
changeset changeset changeset
validate1
cs cs cs
v1
validate2
v2
Inserting to database
case Repo.insert(changeset) do
{:error, changeset} →...
{:ok, model} →...
end
Benefits
● Easy to compose: just |> another validator
● Easy to extend with custom validators
● Easy to test: all functions are pure
● Bonus: it works for any data.
Immutability digression
● Creating new structure every time is optimized
when language provides immutability
● list = [1, 2, 3]
1 2 3
Immutability digression
● Creating new structure every time is optimized
when language provides immutability
● list = [1, 2, 3]
● list2 = [0 | list]
0
1 2 3
Immutability digression
● Creating new structure every time is optimized
when language provides immutability
● list = [1, 2, 3]
● list2 = [0 | list]
● list3 = [4 | list]
0
4
1 2 3
Using Ecto.Multi
Multi.new
|> Multi.update(:account, a_changeset))
|> Multi.insert(:log, log_changeset))
|> Multi.delete_all(:sessions,
assoc(account, :sessions))
multi |> Repo.transaction
Composition
def extend_multi(multi, changeset) do
multi
|> Multi.insert(:some_tag, changeset)
end
multi multi multi
custom
multi multi multi
ins
insert
upd
How would you test this?
Repo.update(...)
Repo.insert(...)
Repo.delete_all(...)
Unit testing Ecto.Multi
assert [
{:account, {:update, achangeset, []}},
{:log, {:insert, log_changeset, []}},
{:sessions, {:delete_all, query, []}}
] = Ecto.Multi.to_list(multi)
Benefits
● Easy to compose: just |> another operation
● Easy to extend with Multi.run
● Easy to test with Multi.to_list
Garbage Collection digression
● Erlang GC is run separately for all processes
● When process dies, all its memory is freed
● This means that, if
– you use a process per request in your web
application and
– it has short lifecycle
The garbage collection may never happen!
Plug (or what makes Phoenix cool)
1. A specification for composable modules
between web applications
2. Connection adapters for different web
servers in the Erlang VM
Plug.Conn
● host
● method
● path_info
● req_headers
● params
● assigns
● resp_body
● status
A plug
def do_nothing(conn) do
conn
end
Pipeline
● Pipeline is a set of plugs
pipeline :pipeline_name do
plug :plug1
plug :plug2
end
● Pipeline is a plug
conn conn conn
pipeline
conn conn conn
v1
plug
v2
Almost the same...
def pipeline_name(conn) do
conn
|> if_not_halted(plug1)
|> if_not_halted(plug2)
end
The glue
def if_not_halted(conn, plug) do
if conn.halted? do
conn
else
plug(conn)
end
Phoenix is a pipeline
pipeline :phoenix do
plug :endpoint
plug :user_pipelines
plug :router
plug :controller
end
And lets you add custom plugs
def current_user(conn) do
account_id = get_session(conn, :account_id)
cond do
account = conn.assigns[:current_account] ->
conn
account = account_id && Repo.get(MyApp.Account, account_id) ->
assign(conn, :current_account, account)
true ->
assign(conn, :current_account, nil)
end
end
And lets you add custom plugs
def current_user(conn, repo  Repo) do
account_id = get_session(conn, :account_id)
cond do
account = conn.assigns[:current_account] ->
conn
account = account_id && repo.get(MyApp.Account, account_id) ->
assign(conn, :current_account, account)
true ->
assign(conn, :current_account, nil)
end
end
current_user test
defmodule Fakerepo do
def get(1) do
%Account{name: „Tomasz”, …}
end
end
current_user(conn, Fakerepo)
Benefits
● Easy to compose: set of plugs is a plug
● Easy to extend: your own plugs can be put
anywhere in the request cycle
● Easy to test: but you need to ensure explicit
contracts
Naming digression
● burritos
Naming digression
● burritos
● >>=
Naming digression
● burritos
● >>=
● Maybe, IO
Naming digression
● burritos
● >>=
● Maybe, IO
● A monad is just a monoid in the category of
endofunctors
GenServer
● GenServer abstracts an actor that takes
requests from the outside world and keeps
state.
c
c
server
c call
cast
cast
GenServer
def handle_call(msg, from, state) do
...
{:reply, actual_reply, new_state}
end
Benefits
● Easy to compose: not covered
● Easy to extend: just add another handle_call
● Easy to test: it is not even necessary to start it!
Elm Architecture
update
view
new_modelcommands
virtual dom
Browser with Elm
msgs model
Benefits
● Easy to compose: recursively
● Easy to extend: just add another message
● Easy to test: only pure functions!
Carrots
Did you know carrots are good for your
eyesight?
Very basic functional design patterns
Single source of truth
● Changeset
● Multi
● Plug.Conn
● GenServer’s State
● Elm Model
Separate pure and impure
● Keep impure parts separate from core logic
● Make impure parts as function inputs (explict
contracts)
Questions
If you like this talk, follow me on Twitter
@snajper47

More Related Content

What's hot (19)

PDF
How fast ist it really? Benchmarking in practice
Tobias Pfeiffer
 
PPTX
R programming
Pramodkumar Jha
 
PDF
c programming
Arun Umrao
 
PDF
Property-Based Testing
Shai Geva
 
PDF
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
ssuserd6b1fd
 
PDF
The underestimated power of KeyPaths
Vincent Pradeilles
 
PDF
Javascript
Vlad Ifrim
 
PDF
PythonOOP
Veera Pendyala
 
PDF
Pooya Khaloo Presentation on IWMC 2015
Iran Entrepreneurship Association
 
PDF
Protocols
SV.CO
 
PDF
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
ssuserd6b1fd
 
PDF
Introduction to python programming
Rakotoarison Louis Frederick
 
PDF
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
ssuserd6b1fd
 
PDF
Fog City Ruby - Triple Equals Black Magic
Brandon Weaver
 
PDF
Intro to OTP in Elixir
Jesse Anderson
 
PDF
The Magic Of Elixir
Gabriele Lana
 
PDF
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
ssuserd6b1fd
 
PPTX
Database performance 101
Leon Fayer
 
PDF
Tame cloud complexity with F#-powered DSLs
Yan Cui
 
How fast ist it really? Benchmarking in practice
Tobias Pfeiffer
 
R programming
Pramodkumar Jha
 
c programming
Arun Umrao
 
Property-Based Testing
Shai Geva
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
ssuserd6b1fd
 
The underestimated power of KeyPaths
Vincent Pradeilles
 
Javascript
Vlad Ifrim
 
PythonOOP
Veera Pendyala
 
Pooya Khaloo Presentation on IWMC 2015
Iran Entrepreneurship Association
 
Protocols
SV.CO
 
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
ssuserd6b1fd
 
Introduction to python programming
Rakotoarison Louis Frederick
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
ssuserd6b1fd
 
Fog City Ruby - Triple Equals Black Magic
Brandon Weaver
 
Intro to OTP in Elixir
Jesse Anderson
 
The Magic Of Elixir
Gabriele Lana
 
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
ssuserd6b1fd
 
Database performance 101
Leon Fayer
 
Tame cloud complexity with F#-powered DSLs
Yan Cui
 

Viewers also liked (12)

PDF
Tez: Accelerating Data Pipelines - fifthel
t3rmin4t0r
 
PDF
Elm: frontend code without runtime exceptions
Pietro Grandi
 
PDF
Claudia Doppioslash - Time Travel for game development with Elm
Codemotion
 
PDF
Elm a possible future for web frontend
Gaetano Contaldi
 
ODP
Elixir and elm - the perfect couple
Tomasz Kowal
 
PDF
Elm: delightful web development
Amir Barylko
 
PDF
Functional Web Development using Elm
💻 Spencer Schneidenbach
 
PDF
Rethink Frontend Development With Elm
Brian Hogan
 
PDF
A recommendation engine for your applications - M.Orselli - Codemotion Rome 17
Codemotion
 
PDF
Self-testing Code
Rogerio Chaves
 
PDF
Introduction to Elm
Rogerio Chaves
 
Tez: Accelerating Data Pipelines - fifthel
t3rmin4t0r
 
Elm: frontend code without runtime exceptions
Pietro Grandi
 
Claudia Doppioslash - Time Travel for game development with Elm
Codemotion
 
Elm a possible future for web frontend
Gaetano Contaldi
 
Elixir and elm - the perfect couple
Tomasz Kowal
 
Elm: delightful web development
Amir Barylko
 
Functional Web Development using Elm
💻 Spencer Schneidenbach
 
Rethink Frontend Development With Elm
Brian Hogan
 
A recommendation engine for your applications - M.Orselli - Codemotion Rome 17
Codemotion
 
Self-testing Code
Rogerio Chaves
 
Introduction to Elm
Rogerio Chaves
 
Ad

Similar to Very basic functional design patterns (20)

PDF
Elixir & Phoenix – fast, concurrent and explicit
Tobias Pfeiffer
 
PDF
Elixir & Phoenix – fast, concurrent and explicit
Tobias Pfeiffer
 
PDF
Functional programming with clojure
Lucy Fang
 
PDF
Beyond PITS, Functional Principles for Software Architecture
Jayaram Sankaranarayanan
 
PDF
Dont Drive on the Railroad Tracks
Eugene Wallingford
 
PDF
Functional Objects in Ruby: new horizons – Valentine Ostakh
Ruby Meditation
 
PDF
Micropatterns
cameronp
 
PDF
Pune Clojure Course Outline
Baishampayan Ghose
 
PDF
Functional programming in ruby
Koen Handekyn
 
PDF
Thinking Functionally - John Stevenson - Codemotion Rome 2017
Codemotion
 
PDF
Thinking Functionally with Clojure
John Stevenson
 
ODP
Clojure: Practical functional approach on JVM
sunng87
 
PDF
Elixir & Phoenix - fast, concurrent and explicit
Tobias Pfeiffer
 
PPT
Clojure 1a
Krishna Chaytaniah
 
PDF
Funtional Ruby - Mikhail Bortnyk
Ruby Meditation
 
PDF
Functional Ruby
Amoniac OÜ
 
PPTX
Esoteric LINQ and Structural Madness
Chris Eargle
 
PDF
Taking Inspiration From The Functional World
Piotr Solnica
 
PPTX
Clojure 7-Languages
Pierre de Lacaze
 
KEY
(map Clojure everyday-tasks)
Jacek Laskowski
 
Elixir & Phoenix – fast, concurrent and explicit
Tobias Pfeiffer
 
Elixir & Phoenix – fast, concurrent and explicit
Tobias Pfeiffer
 
Functional programming with clojure
Lucy Fang
 
Beyond PITS, Functional Principles for Software Architecture
Jayaram Sankaranarayanan
 
Dont Drive on the Railroad Tracks
Eugene Wallingford
 
Functional Objects in Ruby: new horizons – Valentine Ostakh
Ruby Meditation
 
Micropatterns
cameronp
 
Pune Clojure Course Outline
Baishampayan Ghose
 
Functional programming in ruby
Koen Handekyn
 
Thinking Functionally - John Stevenson - Codemotion Rome 2017
Codemotion
 
Thinking Functionally with Clojure
John Stevenson
 
Clojure: Practical functional approach on JVM
sunng87
 
Elixir & Phoenix - fast, concurrent and explicit
Tobias Pfeiffer
 
Funtional Ruby - Mikhail Bortnyk
Ruby Meditation
 
Functional Ruby
Amoniac OÜ
 
Esoteric LINQ and Structural Madness
Chris Eargle
 
Taking Inspiration From The Functional World
Piotr Solnica
 
Clojure 7-Languages
Pierre de Lacaze
 
(map Clojure everyday-tasks)
Jacek Laskowski
 
Ad

Recently uploaded (20)

PDF
TEASMA: A Practical Methodology for Test Adequacy Assessment of Deep Neural N...
Lionel Briand
 
PPTX
CV-Project_2024 version 01222222222.pptx
MohammadSiddiqui70
 
PDF
Cloud computing Lec 02 - virtualization.pdf
asokawennawatte
 
PDF
Difference Between Kubernetes and Docker .pdf
Kindlebit Solutions
 
PDF
What Is an Internal Quality Audit and Why It Matters for Your QMS
BizPortals365
 
PPTX
Wondershare Filmora Crack 14.5.18 + Key Full Download [Latest 2025]
HyperPc soft
 
PDF
LPS25 - Operationalizing MLOps in GEP - Terradue.pdf
terradue
 
PPTX
Seamless-Image-Conversion-From-Raster-to-wrt-rtx-rtx.pptx
Quick Conversion Services
 
PDF
Laboratory Workflows Digitalized and live in 90 days with Scifeon´s SAPPA P...
info969686
 
PPTX
Introduction to web development | MERN Stack
JosephLiyon
 
PPTX
declaration of Variables and constants.pptx
meemee7378
 
PDF
AWS Consulting Services: Empowering Digital Transformation with Nlineaxis
Nlineaxis IT Solutions Pvt Ltd
 
PDF
capitulando la keynote de GrafanaCON 2025 - Madrid
Imma Valls Bernaus
 
PPTX
Quality on Autopilot: Scaling Testing in Uyuni
Oscar Barrios Torrero
 
PDF
WholeClear Split vCard Software for Split large vCard file
markwillsonmw004
 
PPTX
IDM Crack with Internet Download Manager 6.42 [Latest 2025]
HyperPc soft
 
PDF
AI Software Development Process, Strategies and Challenges
Net-Craft.com
 
PDF
Why Edge Computing Matters in Mobile Application Tech.pdf
IMG Global Infotech
 
PDF
Designing Accessible Content Blocks (1).pdf
jaclynmennie1
 
PPTX
Iobit Driver Booster Pro 12 Crack Free Download
chaudhryakashoo065
 
TEASMA: A Practical Methodology for Test Adequacy Assessment of Deep Neural N...
Lionel Briand
 
CV-Project_2024 version 01222222222.pptx
MohammadSiddiqui70
 
Cloud computing Lec 02 - virtualization.pdf
asokawennawatte
 
Difference Between Kubernetes and Docker .pdf
Kindlebit Solutions
 
What Is an Internal Quality Audit and Why It Matters for Your QMS
BizPortals365
 
Wondershare Filmora Crack 14.5.18 + Key Full Download [Latest 2025]
HyperPc soft
 
LPS25 - Operationalizing MLOps in GEP - Terradue.pdf
terradue
 
Seamless-Image-Conversion-From-Raster-to-wrt-rtx-rtx.pptx
Quick Conversion Services
 
Laboratory Workflows Digitalized and live in 90 days with Scifeon´s SAPPA P...
info969686
 
Introduction to web development | MERN Stack
JosephLiyon
 
declaration of Variables and constants.pptx
meemee7378
 
AWS Consulting Services: Empowering Digital Transformation with Nlineaxis
Nlineaxis IT Solutions Pvt Ltd
 
capitulando la keynote de GrafanaCON 2025 - Madrid
Imma Valls Bernaus
 
Quality on Autopilot: Scaling Testing in Uyuni
Oscar Barrios Torrero
 
WholeClear Split vCard Software for Split large vCard file
markwillsonmw004
 
IDM Crack with Internet Download Manager 6.42 [Latest 2025]
HyperPc soft
 
AI Software Development Process, Strategies and Challenges
Net-Craft.com
 
Why Edge Computing Matters in Mobile Application Tech.pdf
IMG Global Infotech
 
Designing Accessible Content Blocks (1).pdf
jaclynmennie1
 
Iobit Driver Booster Pro 12 Crack Free Download
chaudhryakashoo065
 

Very basic functional design patterns