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

Partial Application VS Currying

Alex Bakic

29 Mar 2018

6 min read

Partial Application VS 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.

**Note :**

Unary Function → Function that accepts **1** argument Binary Function → Function that accepts **2** arguments and so on… We are basically changing the structure of our original function . We transform this larger function of a given arity into the composition of smaller , unary functions like this : Original Signature ``` f (X , Y , Z) : → N ``` Curried Signature ``` i(X) : → g(Y) : → h(Z) : → f(X , Y , Z) : → N ``` Gosh , just looks like more work to me , why bother ? Currying makes your code much more expressive. With 1 function comes 1 function name , but by splitting them into unary functions we can describe the role of each argument concisely. Say we had a function that retrieved the inputs a user entered. We have to validate each bit of input the user entered to make sure it is of a) correct type b) within any specified range . All this validation crammed into one function can make it less unit testable and hence less maintainable. Alright , let’s look at a basic example of implementing currying. First we define our polyadic (multiple argument) function : ``` (defn area-of-triangle "Takes the lengths a b and the angle c" [a b c] (Math/abs (* 0.5 a b (Math/sin c)))) ``` This function needs three arguments , so we need to break this down into 3 functions. But if I try this I get an error : ``` (defn curry [a] (fn [b] (fn [c] ((area-of-triangle a b c))))) ``` running this in the REPL results in : ``` (def a (curry 3)) (def b (a 4)) (def c (b 54.7)) ClassCastException java.lang.Double cannot be cast to clojure.lang.IFn user$curry$fn__1737$fn__1738.invoke (:4) ``` This is because I added too many parentheses , evaluating the last line gave ``` (fn [c] (10) ``` But then I get the same error when I remove the brackets ! Just in a different place : ``` (def c (10)) ``` So what can we do to make this work ? The realisation is that in Clojure we need to utilise a technique for us to generate chains of unary functions properly. What kind of technique ? *Well since we can’t just fully apply each unary function* , we need to utilise our old friend partial application. So by partially applying area-of-triangle with just 1 argument we get back a function that takes the remaining 2 . Then we just keep partially applying 1 argument till our chain is complete. Like this: ``` (def a (partial area-of-triangle 3)) (def b (partial a 4)) (def c (b 54.7)) ;; 5.7698490053091875 ``` Keep in mind , this is not currying . This is the technique we must use to imitate currying behaviour. Partial would actually allow us to give any number of arguments like 0 , 1 or 2. But we stick to the concept of creating a chain of unary functions so that we can reap some of the benefits of currying. The reason currying isn’t supported is just a design choice. The developers chose to support variadic functions (which are functions that take a variable number of arguments) than currying. Likewise Haskell chose to include currying instead of variadic functions. Imagine trying to curry a random argument function . To my knowledge it is impossible as the arguments need to be defined before hand to generate the chain of unary functions for each argument. Moreover this is why partial application is much easier and preferred than to do something like hack the language with macros and enable currying . Alright I think it is time we recapped on the similarities and differences between these two : Partial Application will bind pre-existing values to some of the functions arguments. Leaving other arguments to be applied. Currying is just transforming the argument list of a function into chains of functions accepting just 1 argument . In a language where currying is supported , all the arguments can be fully applied , there is just a decoupling between the arguments . Which leads me onto their main similarity. Both partial application and currying will use new functions to separate arguments but currying will still fully apply the function . Partial application will obviously not fully apply but instead produce only an arbitrary number of functions that didn’t get its argument fixed. Moreover , partial application can bind any number of arguments , it can produce functions of all kinds of arities , not just the fixed unary functions that currying is all about. The main similarity is partial application and currying make use of closures to link all these arguments together. I think this example , albeit in JavaScript (where currying is supported) , is a nice little snippet that should help with all this : [Reference :](https://hackernoon.com/partial-application-of-functions-dbe7d9b80760) ```javascript add = function add (a){ return function (b) { return a + b; } }
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

Did you like this article?

Alex Bakic

FP Enthusiast

See other articles by Alex

Related jobs

See all

Title

The company

  • Remote

Title

The company

  • Remote

Title

The company

  • Remote

Title

The company

  • Remote

Related articles

JavaScript Functional Style Made Simple

JavaScript Functional Style Made Simple

Daniel Boros

12 Sep 2021

JavaScript Functional Style Made Simple

JavaScript Functional Style Made Simple

Daniel Boros

12 Sep 2021

WorksHub

CareersCompaniesSitemapFunctional WorksBlockchain WorksJavaScript WorksAI WorksGolang WorksJava WorksPython WorksRemote Works
hello@works-hub.com

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

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!

© 2024 WorksHub

Privacy PolicyDeveloped by WorksHub