SlideShare ist ein Scribd-Unternehmen logo
1 von 77
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
Why this talk?
Syntax
Pattern matching
and pin operator
Basic recursion, map,
reduce, tail recursion
Concurrency,
distributed systems
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
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?
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

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (19)

How fast ist it really? Benchmarking in practice
How fast ist it really? Benchmarking in practiceHow fast ist it really? Benchmarking in practice
How fast ist it really? Benchmarking in practice
 
R programming
R programmingR programming
R programming
 
c programming
c programmingc programming
c programming
 
Property-Based Testing
Property-Based TestingProperty-Based Testing
Property-Based Testing
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
 
The underestimated power of KeyPaths
The underestimated power of KeyPathsThe underestimated power of KeyPaths
The underestimated power of KeyPaths
 
Javascript
JavascriptJavascript
Javascript
 
PythonOOP
PythonOOPPythonOOP
PythonOOP
 
Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015
 
Protocols
ProtocolsProtocols
Protocols
 
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
 
Introduction to python programming
Introduction to python programmingIntroduction to python programming
Introduction to python programming
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
 
Fog City Ruby - Triple Equals Black Magic
Fog City Ruby - Triple Equals Black MagicFog City Ruby - Triple Equals Black Magic
Fog City Ruby - Triple Equals Black Magic
 
Intro to OTP in Elixir
Intro to OTP in ElixirIntro to OTP in Elixir
Intro to OTP in Elixir
 
The Magic Of Elixir
The Magic Of ElixirThe Magic Of Elixir
The Magic Of Elixir
 
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
 
Database performance 101
Database performance 101Database performance 101
Database performance 101
 
Tame cloud complexity with F#-powered DSLs
Tame cloud complexity with F#-powered DSLsTame cloud complexity with F#-powered DSLs
Tame cloud complexity with F#-powered DSLs
 

Andere mochten auch

Andere mochten auch (12)

Tez: Accelerating Data Pipelines - fifthel
Tez: Accelerating Data Pipelines - fifthelTez: Accelerating Data Pipelines - fifthel
Tez: Accelerating Data Pipelines - fifthel
 
Elm: frontend code without runtime exceptions
Elm: frontend code without runtime exceptionsElm: frontend code without runtime exceptions
Elm: frontend code without runtime exceptions
 
Claudia Doppioslash - Time Travel for game development with Elm
Claudia Doppioslash - Time Travel for game development with ElmClaudia Doppioslash - Time Travel for game development with Elm
Claudia Doppioslash - Time Travel for game development with Elm
 
Elm a possible future for web frontend
Elm   a possible future for web frontendElm   a possible future for web frontend
Elm a possible future for web frontend
 
Elixir and elm - the perfect couple
Elixir and elm - the perfect coupleElixir and elm - the perfect couple
Elixir and elm - the perfect couple
 
Elm: delightful web development
Elm: delightful web developmentElm: delightful web development
Elm: delightful web development
 
Functional Web Development using Elm
Functional Web Development using ElmFunctional Web Development using Elm
Functional Web Development using Elm
 
Rethink Frontend Development With Elm
Rethink Frontend Development With ElmRethink Frontend Development With Elm
Rethink Frontend Development With Elm
 
A recommendation engine for your applications - M.Orselli - Codemotion Rome 17
A recommendation engine for your applications - M.Orselli - Codemotion Rome 17A recommendation engine for your applications - M.Orselli - Codemotion Rome 17
A recommendation engine for your applications - M.Orselli - Codemotion Rome 17
 
Self-testing Code
Self-testing CodeSelf-testing Code
Self-testing Code
 
Introduction to Elm
Introduction to ElmIntroduction to Elm
Introduction to Elm
 
Elm intro
Elm introElm intro
Elm intro
 

Ähnlich wie Very basic functional design patterns

Phoenix for laravel developers
Phoenix for laravel developersPhoenix for laravel developers
Phoenix for laravel developers
Luiz Messias
 
Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
Kerry Buckley
 

Ähnlich wie Very basic functional design patterns (20)

Testing in the World of Functional Programming
Testing in the World of Functional ProgrammingTesting in the World of Functional Programming
Testing in the World of Functional Programming
 
Phoenix for laravel developers
Phoenix for laravel developersPhoenix for laravel developers
Phoenix for laravel developers
 
Introducing Elixir and OTP at the Erlang BASH
Introducing Elixir and OTP at the Erlang BASHIntroducing Elixir and OTP at the Erlang BASH
Introducing Elixir and OTP at the Erlang BASH
 
Functional programming in ruby
Functional programming in rubyFunctional programming in ruby
Functional programming in ruby
 
Elixir & Phoenix - fast, concurrent and explicit
Elixir & Phoenix - fast, concurrent and explicitElixir & Phoenix - fast, concurrent and explicit
Elixir & Phoenix - fast, concurrent and explicit
 
FPBrno 2018-05-22: Benchmarking in elixir
FPBrno 2018-05-22: Benchmarking in elixirFPBrno 2018-05-22: Benchmarking in elixir
FPBrno 2018-05-22: Benchmarking in elixir
 
Clojure functions midje
Clojure functions midjeClojure functions midje
Clojure functions midje
 
Begin with Python
Begin with PythonBegin with Python
Begin with Python
 
PyCon 2010 SQLAlchemy tutorial
PyCon 2010 SQLAlchemy tutorialPyCon 2010 SQLAlchemy tutorial
PyCon 2010 SQLAlchemy tutorial
 
Principles of the Play framework
Principles of the Play frameworkPrinciples of the Play framework
Principles of the Play framework
 
Hacking ansible
Hacking ansibleHacking ansible
Hacking ansible
 
Re-Design with Elixir/OTP
Re-Design with Elixir/OTPRe-Design with Elixir/OTP
Re-Design with Elixir/OTP
 
Ruby on rails
Ruby on rails Ruby on rails
Ruby on rails
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
 
Functional Programming in Swift
Functional Programming in SwiftFunctional Programming in Swift
Functional Programming in Swift
 
How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012
 
Deixa para depois, Procrastinando com Celery em Python
Deixa para depois, Procrastinando com Celery em PythonDeixa para depois, Procrastinando com Celery em Python
Deixa para depois, Procrastinando com Celery em Python
 
Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
 
The Steel industry, Elixir, PostgreSQL & file_fdw
The Steel industry, Elixir, PostgreSQL & file_fdwThe Steel industry, Elixir, PostgreSQL & file_fdw
The Steel industry, Elixir, PostgreSQL & file_fdw
 
Chapter 2
Chapter 2Chapter 2
Chapter 2
 

Kürzlich hochgeladen

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 

Kürzlich hochgeladen (20)

AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 

Very basic functional design patterns