Cookies policy

We use cookies to provide the best site experience

We're planting a tree for every job application! Click here to learn more
GolangWorks

Partial Application VS Currying

Alex Bakic

29 Mar 2018

29 March 2018

6 min read

Partial Application VS Currying
  • PA
  • Currying
  • Clojure

##Partial Application VS Currying

In this article we’re going to get to grips with the difference between partial application and currying. I think this concept is especially important in Clojure as there is no direct support for currying so I want to highlight the techniques we could use to grant similar functionality.

Before we dive into partial application , what is ‘full’ application?

To put it succinctly , full application fixes all arguments to their own , single , function definition.

Moreover it means that the function is applied to each of it’s arguments , so how functions are normally used.

Leading from this we can say partial application is where not all arguments are fixed to one function definition , the function is applied to some arguments but not all.

Alright , so what happens to the rest of the arguments?

Well , a number of arguments are first bound to one function , and another function is produced which handles the remaining arguments (this function is then of reduced arity).

We do this to make our functions more flexible , let’s look at a simple example from Wikipedia

    (defn div
    [x y]
        (/ x y))

What if we were to bind the value of x to 1 ?

Then that would give us a function that takes a y and returns it’s reciprocal (1 / y).

In Clojure this binding is done by the partial function like this

    (def reciprocal (partial div 1))
    ;; so partial binds 1 to x and returns a function which only needs the remaining 
    arguments        
    (we just need a y value in this case). 

    ;; If we were to write a standalone reciprocal function , ignoring partial application for a   
    second we would see ourselves rewriting part of the div behaviour.
 
   (reciprocal 3)
    ;; returns 1/3

This is an important step , we can use the behaviour defined in one function and break it apart and spread to more than just one use case.

By making div a bit more flexible we can apply it to different contexts.

This got me thinking , how could I benefit from this technique ? I then looked at one of my github projects , here is a little snippet :

####Note : The project is in Java , but let’s see what I could of done had I used Clojure

    public boolean isExistingAdmin(){
    try{
            PreparedStatement statement = connection.getConnection().prepareStatement("select  
    * from APP.ADMINDETAILS");
            return statement.executeQuery().next();
            }
            catch(SQLException e){                
            }
        return true;
    }

The problem with this function is that we are referring to the global connection object. Say changes where made to the state by other functions of even if the details of connection were changed over time , then this could cause the function to fail. With all the functions that reference the database , they all start up their own statement objects . Moreover writing all this functions becomes very repetitive. We need to fix this !

    ;; this is the function that abstracts querying the db 
    ;; /jdbc refers to the functions part of the clojure.jdbc  library 
    (defn select-query-wrapper
      ;; in the case of a function supplied , apply it to the resultset
      ([spec f query]
        (with-open [conn (jdbc/connection spec)]
          (let rs [(jdbc/execute conn [query])])
            (apply f rs)))

      ;; in the case of no function , just return the result set.
      ([spec query]
        (with-open [conn (jdbc/connection spec)]
          (let rs [(jdbc/execute conn [query])]))
            rs))

With this function we abstract setting up the connection , as we now pass the spec as an argument , we accommodate for future changes.

Rewriting the function that checks that an admin account exists →

   (def admin-exists? (partial select-query-wrapper db-spec))
   ;; I can partially apply here , passing query-wrapper the specification
   ;;when we actually call the function it doesn't need to know about 
   ;;the spec , all we want to do is get something back from our query. 
   ;;check if the result set is empty (no admin)

   (admin-exists? empty?  "SELECT * FROM APP.ADMINDETAILS;")

The great thing about this is that because we just pass the spec , the resulting function now accepts a query with or without a function.

Now let’s move onto currying .

Currying is the process of breaking down a function accepting n many arguments into a chain of unary functions.

increment = add(1);
incrementBy2 = add(2);

increment(3);
// would print 4

incrementBy2(3);
//would print 5
  
OK question time !  
  
Would you say the following is partial application or currying ?  
  
 ```javascript   
    increment = add(1);
    increment(3);

The answer is currying.

Because the add function only takes 1 argument and that is what we supplied , we didn’t bind anything. Each unary function was fully applied , if add took two arguments and we only supplied one , then we would say an argument is bound.

Because partial application and currying both use closures , identifying which is which in these kind of examples can become confusing. I find it easiest to look for whether each function is being fully applied or not.

I hope this article has been helpful , please any post questions you have on the clojure subreddit. I will try and get back to you when I can.

As for further reading , I would recommend these :

Currying and Partial Application in JavaScript
Partial Application for Humans

References :

Wikipedia → Partial Application
Wikipedia → Currying
[Stack Overflow Question on Currying in Clojure](https://stackoverflow.com/questions/49493398/clojure-currying-technicalities/49495414?noredirect=1# comment86011552_49495414)

Did you like this article?

Alex Bakic

FP Enthusiast

See other articles by Alex

Related jobs

Title

$undefined - undefined

The company

title

Remote

Title

$undefined - undefined

The company

title

Remote

Title

$undefined - undefined

The company

title

Remote

Title

$undefined - undefined

The company

title

Remote

Related articles

title

title

title

title

CareersCompaniesSitemapFunctional WorksBlockchain WorksJavaScript WorksAI WorksGolang WorksJava WorksPython WorksRemote Works
email iconhello@works-hub.comUK flag

Ground Floor, Verse Building, 18 Brunswick Place, London, N1 6DZ

US flag

108 E 16th Street, New York, NY 10003

Subscribe to our newsletter

Join over 111,000 others and get access to exclusive content, job opportunities and more!

© 2021 WorksHub

Privacy PolicyDeveloped by WorksHub