Apple’s programming language Swift includes several features commonly used in functional programming but unheard of in more mainstream languages. This blog post explores the lesser-known feature known as curried functions. I first encountered currying when studying the functional language Haskell, which is fundamentally based on function currying. Swift makes function currying available but a developer is never required to make use of it. It’s just another tool in a Swift developer’s toolbox.
The basic idea behind currying is that a function can be partially applied, meaning that some of its parameter values can be specified (bound) before the function is called. Partial function application yields a new function. That new function’s signature is based on the original function’s signature, but the bound parameters are not in the parameter list.
For example, suppose the original function’s parameter list is a String and an Int. If you bind the String parameter, you get back a new function whose parameter list only includes an Int. When you call that partially applied function and pass it an Int value, the function still has the bound String parameter value available to it.
Another way to think about currying is to contrast it to using a function with a default parameter value. In Swift a function’s parameters can have default values specified in the function declaration. If you call a function and don’t provide an argument for a parameter, that parameter’s default value will be passed to the function (assuming the parameter was given a default value by the function’s author). A default parameter value is a compile-time binding between a parameter and a constant value. A new default value cannot be assigned to a parameter at run-time. In contrast, currying effectively allows you to specify a parameter’s default value at run-time. The difference is that partially applying a function results in a new function being born. Only that new function knows the value of the bound parameter. Unlike using a default parameter, code which calls that new function cannot specify a different value for the bound parameter. Once it has been bound via partial function application, that parameter value is set in stone.
Here is a simple example showing the similarities and differences between using default parameter values and curried functions. The following code sample shows how to append a separator to the end of a string. The first function in the code listing uses a default value of “\n” for the separator parameter. Later in the code a different separator, whitespace, is used instead of a newline.
Using a Default Parameter Value
The output created by running this code is shown below:
The first one's free kid. I second that motion! Measure thrice, cut once. The first one's free kid. I second that motion! Measure thrice, cut once.
The next code listing shows how to accomplish the same thing using function currying. Note that when the appendSeparator method is called it returns a new function, not a String. This new function has the separator parameter bound to whatever String was passed to the appendSeparator function. The new function takes a String and returns a String which ends with the separator passed to appendSeparator.
Using a Curried Function
This example is trivial but it shows the essential concept of function currying in action. Binding some of a function’s parameters to create a simpler function makes it is possible to restrict knowledge of what parameter values should be used to only the places in an application that should have that knowledge. This can enable classes to be selectively ignorant about certain aspects of how a function should be used, and reduce coupling between collaborating objects.
I love curry! Saw a q on stackoverflow that I thought currying would be perfect for just wasn’t sure if swift supported it or not and was too lazy to look it up. Seems like apple did a good job with the language. And you as always have done a good job at explaining it
Thanks Mike!
Pingback: Dew Drop – June 10, 2014 (#1794) | Morning Dew
I think you forgot the function in your second example and have the same code as earlier that returns a String.
No, that is the curried method syntax. The example code is correct.
uh, sorry. I missed to see that the function was ()()->() It looked like () -> ()
Hi Josh,
Great blog post (and your other recent Swift posts also). I must admit, I find currying quite confusing and doubt I would ever use it as a result.
Do you see it as something purely academic? Or could you see yourself using it in iOS code?
After reading your article, and being somewhat baffled by the function signature ()() -> () I discovered that what I thought of as currying is actually partial application – which is something I see as being a whole lot more useful!
Regards, Colin E.
I agree that curried functions are pretty odd at first. They definitely are an acquired taste! I’m not sure if I will find them useful in Swift, time will tell.
Hi Josh, your code samples are hard to copy 😉
In my experience, the most pragmatically beneficial trait from functional programing is abstracting over the imperative iteration with general functions like filter, map and reduce. The pattern you use in you example, `var text = “”; for s in sequence { text += appendSeparatorToString }` can be IMHO more cleanly written as `let lines = sentences.reduce(“”) {$0 + appendSeparatorToString($1)}`.
I’d like to suggest to all imperative programmers migrating to more functional environment to learn these idioms as soon as possible, because they allow them to express the intent more cleanly without being bothered with the minutiae of iteration and temporary variables.
Thanks Pavol. I like your sample code! You make a good point.
Nice suggestion!
“This can enable classes to be selectively ignorant about certain aspects of how a function should be used, and reduce coupling between collaborating objects.”
I really like this conclusion. For me it moves the realm of curry-ing from something interesting to something very applicable. Thanks!
Thanks Pete. I’m glad that sentence helped make the concept gel for you.
Thanks Josh! Great post. I was trying to understand this concept in Apple’s new Swift book. I found your writeup via Google. This really makes it crystal clear. Thanks again!
That’s great! Thanks for letting me know, Will.
Pingback: How to Write Curried Functions in Swift [iOS developer:tips];
Agree with earlier Pavol – would be nice to have the source in text form (maybe a link to it?) I wanted to play with it as well as try Pavol’s refinement.
Pingback: Week 2 | Swift Links
Pingback: A First Look at Swift: The Good, the Bad and the Ugly » leib.be