SlideShare a Scribd company logo
1 of 4
Download to read offline
Healthy Code
March - 2015
10
In 2013, Dhaval Dalal was inspired by Jugalbandi, an Indian classical music
form in which musicians have an improvised musical conversation, each using a
different instrument, while exploring a shared musical theme together akin to Jazz
in some ways. Dhaval thought, “What if we could have a conversation about some
programming concepts in this way? Instead of musical instruments, what if we use
different programming languages?”
Code
Jugalbandi
Article
Ryan and Dhaval
Healthy Code
March - 2015
11
Creator and Listener
We met regularly with over a period of several months,
exploring some key issues related to Functional
Programming(FP).ThisculminatedinaliveCodeJugalbandi
at the Functional Conference in Bengaluru, 2014. During
the FP Code Jugalbandi, we explored nine themes, which
becamemelodies. Similar to the musical Jugalbandi, there
are two roles: creator and listener. We called the creator of
the melody Bramha and the one who listens and responds
with a different instrument, Krishna. In the last Code
Jugalbandi Article, we looked at the melody, the Sequencing
problem. This time we will look at Currying and Partial
Function Application (PFA).
Currying in Groovy
BRAMHA: Imagine, I have an HTTP request for a customer
in our web application and we want to authorize the
request.I’ll use Groovy here to do that.
def req1 = [‘id’: 1]
def customer = authorizer(repo, req1)
println customer.name
BRAMHA: Let’s write down the customer repository
quickly.
class CustomerRepository {
def findBy(Integer id) {
if(id > 0) {
[id: id, name: “Cust Name #$id”]
}
else {
throw new RuntimeException(‘cust not found’)
}
}
}
BRAMHA: and I’ll write authorizer as a closure that
consumes two parameters, repository and request.
def authorizer = { rep, req -> rep.findBy(req.id) }
BRAMHA: Now let’s say that, before I can request the
customer, I need to make sure that the user is authorized to
access it.
def repo = new CustomerRepository()
def req1 = [‘id’: 1]
def req2 = [‘id’: 2]
def cust1 = authorizer(repo, req1)
def cust2 = authorizer(repo, req2)
BRAMHA: If you look at the above. I’m repeatedly
injecting CustomerRepository reference when calling
authorizer. Could I somehow convert this authorizer to just
accept request; the parameter that varies while fixing the
repository? This is where I’ll resort to currying the repository.
def auth = authorizer.curry(repo)
def cust1 = auth(req1)
def cust2 = auth(req2)
BRAMHA: I’ve re-shaped the authorizer to a single argument
function from a two-argument function. Along similar lines
I’ll write an authenticator that takes in an authorizer and http-
request and re-shape it to just accept request.
def authenticator = { rep, req -> rep(req) }
def auth = authenticator.curry(authorizer.
curry(repo))
def cust1 = auth(req1)
BRAMHA: We used currying to re-shape the functions so
that we can chain them and the request can flow through
each of them.
BRAMHA: Let me show you some Scala code that does the
same thing.
Currying in Scala
case class Customer(id: Int, name: String)
class CustomerRepository {
def findBy(id: Int): Option[Customer] =
if (id > 0)
Some(Customer(id, s”Customer Name #
This led to the first Code Jugalbandi between us. Code Jugalbandi inspired and fuelled
our learning by focussing on dialogue and exploration. More languages in the room
meant more perspectives too. Exploring a paradigm through many languages gave us a
better map of the territory than any single language could. Above all, Code Jugalbandi
was a playful way to learn together!
Healthy Code
March - 2015
12
KRISHNA: With partial function application, and currying,
for that matter, the order of arguments matter! e.g. what if
we wanted to fix the second argument instead of the first?
(def new-ada (partial new-person title “Ada”))
(new-ada “Ms” “Lovelace”)
KRISHNA: But this doesn’t make sense, because we
somehow need to have a placeholder for the first param,
which we don’t want to partially apply. So, when we’re
partially applying argument to a function, it works from left
to right. We can’t only apply the third argument and not also
the first and second arguments. We can wire in values for the
arguments, from left to right.
We can’t wire in only the second param, but I can always
achieve this with a lambda:
(def new-ada
(fn [title lname]
(new-person title “Ada” lname)))
(new-ada “Ms” “Lovelace”)
KRISHNA: Fortunately, Clojure has a macro to synthesise
this kind of “ad-hoc” partial function application:
(def new-ada-f
#(new-person %1 “Ada” %2))
(new-ada-f “Ms” “Lovelace”)
KRISHNA: I’m sure Scala has this kind of thing too, right?
Partial Function Application in Scala
BRAMHA: Sure, let me show this in Scala. I do partial
functionapplicationonnew_personbyputtinginplaceholders
for its second and third parameters, and just bind title
def new_person(title: String, fname: String, lname:
String) = s”$title $fname $lname”
val new_ms = new_person(“Ms”, _: String, _: String)
new_ms(“Ada”, “Lovelace”)
BRAMHA This time, I do partial function application
on fname by putting in placeholders for its first and last
parameters.
val new_ada = new_person(_: String, “Ada”, _:
String) new_ada(“Ms”, “Lovelace”
KRISHNA: Scala’s syntax is definitely superior to Clojure’s
in the sense that regular and ad-hoc partial function
application is unified.
BRAMHA: Also, in Scala, if you have a function in curried
form, that is, a function of one argument at a time, it’s trivial
to convert it to the uncurried form, and vice versa.
$id”))
else
None
}
type Request = Map[String, Int]
def authenticator(f: Request => Option[Customer])
(req: Request): Option[Customer] = f(req)
def authorizer(rep: CustomerRepository)(req:
Request): Option[Customer] = req.get(“id”).
flatMap(id => rep.findBy(id))
val authorize = authorizer _
val authenticate = authenticator _
val auth = authenticate(authorize(new Customer
Repository))
val req1 = Map(“id” -> 1)
val cust1 = auth(req1)
BRAMHA: If you observe the above code, unlike Groovy,
I don’t invoke any special method to do currying, by using
multi-parameter functions, Scala gives you currying for free.
All I do here is convert the methods authorizer and
authenticator to function type using partial function
application by using underscore(). This gives me _
authorize, having type CustomerRepository (Request
Option[Customer])functionobject.Italsogivesmeauthenticate,
having type (Request Option[Customer]) (Request
Option[Customer]) function object.
Itheninjecttherepositoryinauthorizeandbecauseofcurrying
it then gets re-shaped into a function that goes from Request
Option[Customer]. This type then directly aligns as input
parameter to the authenticate function.
Partial Function Application in Clojure
KRISHNA: Let’s look at partial function application in
Clojure and start with this function with three arguments.
(defn new-person [title f-name l-name]
{ :title title,
:f-name f-name,
:l-name l-name
})
(new-person “Ms” “Ada” “Lovelace”)
KRISHNA: What if I wanted to partially apply the title to
this function?
(def new-ms (partial new-person “Ms”))
(new-ms “Ada” “Lovelace”)
KRISHNA: I’ve reshaped the function by wiring in the first
argument.
Healthy Code
March - 2015
13
val fUncurried = Function.uncurried(f)
val fCurried = fUncurried.curried
Currying in Haskell
KRISHNA In Haskell, functions are curried by default, you
don’t have any special syntax like Scala.
make_person :: String -> String -> String -> String
make_person s fname lname = s ++ fname ++ lname
main = putStrLn (make_person “Ms” “Ada” “Lovelace”)
-- above is same as
main = putStrLn ((make_person “Ms”) “Ada” “Lovelace”)
-- is same as
main = putStrLn (((make_person “Ms”) “Ada”)
“Lovelace”)
BRAMHA: Groovy also offers right curry - rcurry and curry
a particular parameter at a position - ncurry, but I think they
are more like PFArather than actual currying that we usually
see from left to right.
Reflections
KRISHNA This shows the difference between Currying and
PFA. With PFA, we are just dealing with regular functions
of multiple arguments; essentially fixing a few arguments
and returning a function with fewer arguments. However,
Currying refers to functions that take only one argument
at a time! You can think of a Curried function as a nested
structure, just like Russian dolls: for each argument, there
is another nested function, that takes that argument and
returns a function taking the subsequent arg, and so on, until
all the arguments are exhausted.
BRAMHA: In FP, we can achieve Dependency Injection
(DI) by passing functions around and thereby injecting
behaviour. But currying and PFA also offer a way to achieve
DI: for a function that takes either functions as arguments or
just regular parameters, when we curry such an argument,
we are injecting dependency.Also, depending on the context,
we can change the concrete dependency. For example, when
the context is driving design through tests, we can inject
a MockCustomerRepository, whereas in production we would
inject the real CustomerRepository.
KRISHNA: Yes, that’s why it’s quite commonly used in web
frameworks to inject locale and other contextual information
when creating a request.
BRAMHA: In a language that deals well with PFA, you
won’t really miss currying, because you’ll use PFA where
you would have used currying.
Also, “ad-hoc PFA” is practically more powerful than
currying in some ways. With currying, you have to curry
strictly from left to right, with PFA you can do ad-hoc
application of args.
KRISHNA: Currying and PFA gives us a way to reshape -
and repurpose - our functions for different use cases, without
having to explicitly “wrap” the old function with a different
argument list.
References
Learn more from http://codejugalbandi.org
Ryan is a software developer,
coach and advisor, based in Cape
Town. He has been working with
code for more than 15 years. Ryan
assists individuals and teams
to manage the evolution and
complexity of their software
systems. Ryan is a passionate
learner and enjoys facilitating
learning in others.
Dhavalahands-ondeveloperand
mentor, believes that software
development is first an art and
then a craft. For him writing
software brings his creativity
to the fore. His interests are in
architecting applications ground
up, estabilishing environments,
transitioning and orienting
teams to Agile way of working
by embedding himself within
teams.
You can follow them on Twitter @
CodeJugalbandi

More Related Content

What's hot

Hw1 rubycalisthenics
Hw1 rubycalisthenicsHw1 rubycalisthenics
Hw1 rubycalisthenics
shelton88
 

What's hot (11)

Php Oop
Php OopPhp Oop
Php Oop
 
Java String class
Java String classJava String class
Java String class
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)
 
Hw1 rubycalisthenics
Hw1 rubycalisthenicsHw1 rubycalisthenics
Hw1 rubycalisthenics
 
NLP in 10 lines of code
NLP in 10 lines of codeNLP in 10 lines of code
NLP in 10 lines of code
 
Inheritance
InheritanceInheritance
Inheritance
 
Think Like a Programmer
Think Like a ProgrammerThink Like a Programmer
Think Like a Programmer
 
Domain-Specific Languages
Domain-Specific LanguagesDomain-Specific Languages
Domain-Specific Languages
 
Intro to Programming for Communicators - Hacks/Hackers ATX
Intro to Programming for Communicators - Hacks/Hackers ATXIntro to Programming for Communicators - Hacks/Hackers ATX
Intro to Programming for Communicators - Hacks/Hackers ATX
 
Build a compiler using C#, Irony and RunSharp.
Build a compiler using C#, Irony and RunSharp.Build a compiler using C#, Irony and RunSharp.
Build a compiler using C#, Irony and RunSharp.
 
Intro to Programming for Communicators - Hacks/Hackers ATX
Intro to Programming for Communicators - Hacks/Hackers ATXIntro to Programming for Communicators - Hacks/Hackers ATX
Intro to Programming for Communicators - Hacks/Hackers ATX
 

Viewers also liked

Approaching Rich Internet Applications
Approaching Rich Internet ApplicationsApproaching Rich Internet Applications
Approaching Rich Internet Applications
Dhaval Dalal
 
The tao-of-transformation
The tao-of-transformationThe tao-of-transformation
The tao-of-transformation
Dhaval Dalal
 
Web sockets primer
Web sockets primerWeb sockets primer
Web sockets primer
Dhaval Dalal
 
Domain languageacceptancetests
Domain languageacceptancetestsDomain languageacceptancetests
Domain languageacceptancetests
Dhaval Dalal
 
C# for-java-developers
C# for-java-developersC# for-java-developers
C# for-java-developers
Dhaval Dalal
 
Math works kids-game
Math works kids-gameMath works kids-game
Math works kids-game
Dhaval Dalal
 

Viewers also liked (18)

Transition contours
Transition contoursTransition contours
Transition contours
 
Code jugalbandi
Code jugalbandiCode jugalbandi
Code jugalbandi
 
Approaching Rich Internet Applications
Approaching Rich Internet ApplicationsApproaching Rich Internet Applications
Approaching Rich Internet Applications
 
Language portfolio
Language portfolioLanguage portfolio
Language portfolio
 
The tao-of-transformation-workshop
The tao-of-transformation-workshopThe tao-of-transformation-workshop
The tao-of-transformation-workshop
 
The tao-of-transformation
The tao-of-transformationThe tao-of-transformation
The tao-of-transformation
 
Web sockets primer
Web sockets primerWeb sockets primer
Web sockets primer
 
Domain languageacceptancetests
Domain languageacceptancetestsDomain languageacceptancetests
Domain languageacceptancetests
 
C# for-java-developers
C# for-java-developersC# for-java-developers
C# for-java-developers
 
Calculator stories
Calculator storiesCalculator stories
Calculator stories
 
Jumping-with-java8
Jumping-with-java8Jumping-with-java8
Jumping-with-java8
 
CodeRetreat
CodeRetreatCodeRetreat
CodeRetreat
 
A case-for-graph-db
A case-for-graph-dbA case-for-graph-db
A case-for-graph-db
 
Midas - on-the-fly schema migration tool for MongoDB.
Midas - on-the-fly schema migration tool for MongoDB.Midas - on-the-fly schema migration tool for MongoDB.
Midas - on-the-fly schema migration tool for MongoDB.
 
Tayra
TayraTayra
Tayra
 
Grooming with Groovy
Grooming with GroovyGrooming with Groovy
Grooming with Groovy
 
Math works kids-game
Math works kids-gameMath works kids-game
Math works kids-game
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
 

Similar to 3-CodeJugalbandi-currying-pfa-healthycodemagazine#mar2015

Similar to 3-CodeJugalbandi-currying-pfa-healthycodemagazine#mar2015 (20)

Learning puppet chapter 2
Learning puppet chapter 2Learning puppet chapter 2
Learning puppet chapter 2
 
Graphql
GraphqlGraphql
Graphql
 
Function Applicative for Great Good of Palindrome Checker Function - Polyglot...
Function Applicative for Great Good of Palindrome Checker Function - Polyglot...Function Applicative for Great Good of Palindrome Checker Function - Polyglot...
Function Applicative for Great Good of Palindrome Checker Function - Polyglot...
 
The Bund language
The Bund languageThe Bund language
The Bund language
 
Ruby on Rails
Ruby on RailsRuby on Rails
Ruby on Rails
 
Functions & Closures in Scala
Functions & Closures in ScalaFunctions & Closures in Scala
Functions & Closures in Scala
 
Functions & Closures in Scala
Functions & Closures in ScalaFunctions & Closures in Scala
Functions & Closures in Scala
 
Functions & closures
Functions & closuresFunctions & closures
Functions & closures
 
Regular expressions in Python
Regular expressions in PythonRegular expressions in Python
Regular expressions in Python
 
R hive tutorial - apply functions and map reduce
R hive tutorial - apply functions and map reduceR hive tutorial - apply functions and map reduce
R hive tutorial - apply functions and map reduce
 
The JavaScript You Wished You Knew
The JavaScript You Wished You KnewThe JavaScript You Wished You Knew
The JavaScript You Wished You Knew
 
FUNCTIONS IN R PROGRAMMING.pptx
FUNCTIONS IN R PROGRAMMING.pptxFUNCTIONS IN R PROGRAMMING.pptx
FUNCTIONS IN R PROGRAMMING.pptx
 
Licão 13 functions
Licão 13 functionsLicão 13 functions
Licão 13 functions
 
Arrays & functions in php
Arrays & functions in phpArrays & functions in php
Arrays & functions in php
 
Python Homework Help
Python Homework HelpPython Homework Help
Python Homework Help
 
Icsug conf 14_dev03_xpages-roadtodamascas-lotus-script-and-formula-to-ssjs
Icsug conf 14_dev03_xpages-roadtodamascas-lotus-script-and-formula-to-ssjsIcsug conf 14_dev03_xpages-roadtodamascas-lotus-script-and-formula-to-ssjs
Icsug conf 14_dev03_xpages-roadtodamascas-lotus-script-and-formula-to-ssjs
 
Monad as functor with pair of natural transformations
Monad as functor with pair of natural transformationsMonad as functor with pair of natural transformations
Monad as functor with pair of natural transformations
 
Introduction to CoffeeScript
Introduction to CoffeeScriptIntroduction to CoffeeScript
Introduction to CoffeeScript
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
Plunging Into Perl While Avoiding the Deep End (mostly)
Plunging Into Perl While Avoiding the Deep End (mostly)Plunging Into Perl While Avoiding the Deep End (mostly)
Plunging Into Perl While Avoiding the Deep End (mostly)
 

More from Dhaval Dalal

More from Dhaval Dalal (15)

Test Pyramid in Microservices Context
Test Pyramid in Microservices ContextTest Pyramid in Microservices Context
Test Pyramid in Microservices Context
 
Code Retreat
Code RetreatCode Retreat
Code Retreat
 
Booting into functional programming
Booting into functional programmingBooting into functional programming
Booting into functional programming
 
Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)
 
Creating Lazy stream in CSharp
Creating Lazy stream in CSharpCreating Lazy stream in CSharp
Creating Lazy stream in CSharp
 
Json Viewer Stories
Json Viewer StoriesJson Viewer Stories
Json Viewer Stories
 
Value Objects
Value ObjectsValue Objects
Value Objects
 
Mars rover-extension
Mars rover-extensionMars rover-extension
Mars rover-extension
 
How Is Homeopathy Near To Yoga?
How Is Homeopathy Near To Yoga?How Is Homeopathy Near To Yoga?
How Is Homeopathy Near To Yoga?
 
Approaching ATDD/BDD
Approaching ATDD/BDDApproaching ATDD/BDD
Approaching ATDD/BDD
 
Paradigms Code jugalbandi
Paradigms Code jugalbandiParadigms Code jugalbandi
Paradigms Code jugalbandi
 
Data Reconciliation
Data ReconciliationData Reconciliation
Data Reconciliation
 
CodeJugalbandi-Expression-Problem-HealthyCode-Magazine#Jan-2015-Issue
CodeJugalbandi-Expression-Problem-HealthyCode-Magazine#Jan-2015-IssueCodeJugalbandi-Expression-Problem-HealthyCode-Magazine#Jan-2015-Issue
CodeJugalbandi-Expression-Problem-HealthyCode-Magazine#Jan-2015-Issue
 
Healthy Code Magazine June-2014 Issue Midas-Touch-Article
Healthy Code Magazine June-2014 Issue Midas-Touch-ArticleHealthy Code Magazine June-2014 Issue Midas-Touch-Article
Healthy Code Magazine June-2014 Issue Midas-Touch-Article
 
Neo4j MySql MS-SQL comparison
Neo4j MySql MS-SQL comparisonNeo4j MySql MS-SQL comparison
Neo4j MySql MS-SQL comparison
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 

3-CodeJugalbandi-currying-pfa-healthycodemagazine#mar2015

  • 1. Healthy Code March - 2015 10 In 2013, Dhaval Dalal was inspired by Jugalbandi, an Indian classical music form in which musicians have an improvised musical conversation, each using a different instrument, while exploring a shared musical theme together akin to Jazz in some ways. Dhaval thought, “What if we could have a conversation about some programming concepts in this way? Instead of musical instruments, what if we use different programming languages?” Code Jugalbandi Article Ryan and Dhaval
  • 2. Healthy Code March - 2015 11 Creator and Listener We met regularly with over a period of several months, exploring some key issues related to Functional Programming(FP).ThisculminatedinaliveCodeJugalbandi at the Functional Conference in Bengaluru, 2014. During the FP Code Jugalbandi, we explored nine themes, which becamemelodies. Similar to the musical Jugalbandi, there are two roles: creator and listener. We called the creator of the melody Bramha and the one who listens and responds with a different instrument, Krishna. In the last Code Jugalbandi Article, we looked at the melody, the Sequencing problem. This time we will look at Currying and Partial Function Application (PFA). Currying in Groovy BRAMHA: Imagine, I have an HTTP request for a customer in our web application and we want to authorize the request.I’ll use Groovy here to do that. def req1 = [‘id’: 1] def customer = authorizer(repo, req1) println customer.name BRAMHA: Let’s write down the customer repository quickly. class CustomerRepository { def findBy(Integer id) { if(id > 0) { [id: id, name: “Cust Name #$id”] } else { throw new RuntimeException(‘cust not found’) } } } BRAMHA: and I’ll write authorizer as a closure that consumes two parameters, repository and request. def authorizer = { rep, req -> rep.findBy(req.id) } BRAMHA: Now let’s say that, before I can request the customer, I need to make sure that the user is authorized to access it. def repo = new CustomerRepository() def req1 = [‘id’: 1] def req2 = [‘id’: 2] def cust1 = authorizer(repo, req1) def cust2 = authorizer(repo, req2) BRAMHA: If you look at the above. I’m repeatedly injecting CustomerRepository reference when calling authorizer. Could I somehow convert this authorizer to just accept request; the parameter that varies while fixing the repository? This is where I’ll resort to currying the repository. def auth = authorizer.curry(repo) def cust1 = auth(req1) def cust2 = auth(req2) BRAMHA: I’ve re-shaped the authorizer to a single argument function from a two-argument function. Along similar lines I’ll write an authenticator that takes in an authorizer and http- request and re-shape it to just accept request. def authenticator = { rep, req -> rep(req) } def auth = authenticator.curry(authorizer. curry(repo)) def cust1 = auth(req1) BRAMHA: We used currying to re-shape the functions so that we can chain them and the request can flow through each of them. BRAMHA: Let me show you some Scala code that does the same thing. Currying in Scala case class Customer(id: Int, name: String) class CustomerRepository { def findBy(id: Int): Option[Customer] = if (id > 0) Some(Customer(id, s”Customer Name # This led to the first Code Jugalbandi between us. Code Jugalbandi inspired and fuelled our learning by focussing on dialogue and exploration. More languages in the room meant more perspectives too. Exploring a paradigm through many languages gave us a better map of the territory than any single language could. Above all, Code Jugalbandi was a playful way to learn together!
  • 3. Healthy Code March - 2015 12 KRISHNA: With partial function application, and currying, for that matter, the order of arguments matter! e.g. what if we wanted to fix the second argument instead of the first? (def new-ada (partial new-person title “Ada”)) (new-ada “Ms” “Lovelace”) KRISHNA: But this doesn’t make sense, because we somehow need to have a placeholder for the first param, which we don’t want to partially apply. So, when we’re partially applying argument to a function, it works from left to right. We can’t only apply the third argument and not also the first and second arguments. We can wire in values for the arguments, from left to right. We can’t wire in only the second param, but I can always achieve this with a lambda: (def new-ada (fn [title lname] (new-person title “Ada” lname))) (new-ada “Ms” “Lovelace”) KRISHNA: Fortunately, Clojure has a macro to synthesise this kind of “ad-hoc” partial function application: (def new-ada-f #(new-person %1 “Ada” %2)) (new-ada-f “Ms” “Lovelace”) KRISHNA: I’m sure Scala has this kind of thing too, right? Partial Function Application in Scala BRAMHA: Sure, let me show this in Scala. I do partial functionapplicationonnew_personbyputtinginplaceholders for its second and third parameters, and just bind title def new_person(title: String, fname: String, lname: String) = s”$title $fname $lname” val new_ms = new_person(“Ms”, _: String, _: String) new_ms(“Ada”, “Lovelace”) BRAMHA This time, I do partial function application on fname by putting in placeholders for its first and last parameters. val new_ada = new_person(_: String, “Ada”, _: String) new_ada(“Ms”, “Lovelace” KRISHNA: Scala’s syntax is definitely superior to Clojure’s in the sense that regular and ad-hoc partial function application is unified. BRAMHA: Also, in Scala, if you have a function in curried form, that is, a function of one argument at a time, it’s trivial to convert it to the uncurried form, and vice versa. $id”)) else None } type Request = Map[String, Int] def authenticator(f: Request => Option[Customer]) (req: Request): Option[Customer] = f(req) def authorizer(rep: CustomerRepository)(req: Request): Option[Customer] = req.get(“id”). flatMap(id => rep.findBy(id)) val authorize = authorizer _ val authenticate = authenticator _ val auth = authenticate(authorize(new Customer Repository)) val req1 = Map(“id” -> 1) val cust1 = auth(req1) BRAMHA: If you observe the above code, unlike Groovy, I don’t invoke any special method to do currying, by using multi-parameter functions, Scala gives you currying for free. All I do here is convert the methods authorizer and authenticator to function type using partial function application by using underscore(). This gives me _ authorize, having type CustomerRepository (Request Option[Customer])functionobject.Italsogivesmeauthenticate, having type (Request Option[Customer]) (Request Option[Customer]) function object. Itheninjecttherepositoryinauthorizeandbecauseofcurrying it then gets re-shaped into a function that goes from Request Option[Customer]. This type then directly aligns as input parameter to the authenticate function. Partial Function Application in Clojure KRISHNA: Let’s look at partial function application in Clojure and start with this function with three arguments. (defn new-person [title f-name l-name] { :title title, :f-name f-name, :l-name l-name }) (new-person “Ms” “Ada” “Lovelace”) KRISHNA: What if I wanted to partially apply the title to this function? (def new-ms (partial new-person “Ms”)) (new-ms “Ada” “Lovelace”) KRISHNA: I’ve reshaped the function by wiring in the first argument.
  • 4. Healthy Code March - 2015 13 val fUncurried = Function.uncurried(f) val fCurried = fUncurried.curried Currying in Haskell KRISHNA In Haskell, functions are curried by default, you don’t have any special syntax like Scala. make_person :: String -> String -> String -> String make_person s fname lname = s ++ fname ++ lname main = putStrLn (make_person “Ms” “Ada” “Lovelace”) -- above is same as main = putStrLn ((make_person “Ms”) “Ada” “Lovelace”) -- is same as main = putStrLn (((make_person “Ms”) “Ada”) “Lovelace”) BRAMHA: Groovy also offers right curry - rcurry and curry a particular parameter at a position - ncurry, but I think they are more like PFArather than actual currying that we usually see from left to right. Reflections KRISHNA This shows the difference between Currying and PFA. With PFA, we are just dealing with regular functions of multiple arguments; essentially fixing a few arguments and returning a function with fewer arguments. However, Currying refers to functions that take only one argument at a time! You can think of a Curried function as a nested structure, just like Russian dolls: for each argument, there is another nested function, that takes that argument and returns a function taking the subsequent arg, and so on, until all the arguments are exhausted. BRAMHA: In FP, we can achieve Dependency Injection (DI) by passing functions around and thereby injecting behaviour. But currying and PFA also offer a way to achieve DI: for a function that takes either functions as arguments or just regular parameters, when we curry such an argument, we are injecting dependency.Also, depending on the context, we can change the concrete dependency. For example, when the context is driving design through tests, we can inject a MockCustomerRepository, whereas in production we would inject the real CustomerRepository. KRISHNA: Yes, that’s why it’s quite commonly used in web frameworks to inject locale and other contextual information when creating a request. BRAMHA: In a language that deals well with PFA, you won’t really miss currying, because you’ll use PFA where you would have used currying. Also, “ad-hoc PFA” is practically more powerful than currying in some ways. With currying, you have to curry strictly from left to right, with PFA you can do ad-hoc application of args. KRISHNA: Currying and PFA gives us a way to reshape - and repurpose - our functions for different use cases, without having to explicitly “wrap” the old function with a different argument list. References Learn more from http://codejugalbandi.org Ryan is a software developer, coach and advisor, based in Cape Town. He has been working with code for more than 15 years. Ryan assists individuals and teams to manage the evolution and complexity of their software systems. Ryan is a passionate learner and enjoys facilitating learning in others. Dhavalahands-ondeveloperand mentor, believes that software development is first an art and then a craft. For him writing software brings his creativity to the fore. His interests are in architecting applications ground up, estabilishing environments, transitioning and orienting teams to Agile way of working by embedding himself within teams. You can follow them on Twitter @ CodeJugalbandi