{{announcement.body}}
{{announcement.title}}

Eta-Expansion and Partially Applied Functions in Scala

DZone 's Guide to

Eta-Expansion and Partially Applied Functions in Scala

Here we'll discuss the topic of eta-expansion and partially-applied functions, which are often loosely covered and piecemeal.

· Java Zone ·
Free Resource

This article is for Scala programmers who know at least these essential concepts: what a method is and how to define a function value (lambda). Here we'll discuss the topic of eta-expansion and partially-applied functions, which are often loosely covered and piecemeal.

You can read this article over at the Rock the JVM blog in its original form or watch as video on YouTube or in the video below:


Background

Long story short, methods and functions are different things in Scala. When I write

Scala


that's a method, which is a piece of code that can be invoked on an instance of a class. A method is a member of the enclosing class or object and can be invoked like this:

Scala
 


Even if you call the method from the body of the class or object, it's the same as invoking it on the this instance. So you won't be able to call a method on its own, because it's tied to some instance of a class.

Function values (aka lambdas), on the other hand, are pieces of code that can be invoked independently of a class or object. Functions are assignable to values or variables, can be passed as arguments and can be returned as results - it's one of the most important tenets of functional programming in Scala.

Scala


Behind the scenes, these function values are actually instances of the FunctionN family of traits with an apply method which benefits from special treatment, so what you're doing is in fact:

Scala


Methods and functions are thus different in Scala. However, because the user sees and uses them in the same way (just invoke them), they're "morally" equivalent. The eta-expansion mechanism allows the conversion between a method and a function.

Converting a Method to a Function

Because a method and a function are seen differently by the JVM - a method of a class vs a field of type FunctionN - you can't simply say

Scala
 




xxxxxxxxxx
1


 
1
val incrementF = incrementMethod
2
 
          



because the compiler will think you'll try to call your increment method, which requires arguments. The way you'd do the conversion is

Scala


The underscore at the end is a signal for the compiler that you want to turn the method into a function value, and you'll obtain a function of type Int => Int. This conversion is called eta-expansion, and the compiler will generate a piece of code that will look something like

Scala


The compiler can also do this automatically if you give it the function type in advance:

Scala
 


In this case, the compiler can disambiguate the context, because you declared that you want a function so the compiler will automatically eta-expand the method for you.

Partially Applied Functions

Another important scenario where eta-expansion is useful is with methods taking multiple argument lists.

Scala


In this case, you'll get another function which takes the remaining arguments, therefore of type Int => Int. This is called a partially applied function, because you're only supplying a subset of argument lists and the remaining arguments are to be passed later:

Scala


In a similar fashion as before, the compiler can detect whether a value is expected to have a function type, and so it can automatically eta-expand a method for you:

Scala


In this case, the argument of the map method needs to have the type Int => Int, so the compiler will automatically turn the method into an eta-expanded lambda for you.

Interesting Questions

So far, we've discussed only methods that have a single argument in their list. Here's something to think about:

Scala


In this case, the method has two arguments. An eta-expanded function value (lambda) will have two arguments as well, so it will be of type (Int, Int) => Int. A similar expansion will happen on a larger number of arguments as well.

Another interesting scenario is: what happens on more than two argument lists and/or we're left with more than an argument list in the expanded function:

Scala


In this case, we'll get a curried function which will take the remaining argument lists in turn, so the function type will be Int => Int => Int. If you want to invoke it:

Scala


At the same time, if we pass more than one argument list:

Scala


then we'll get a function which takes the remaining argument lists (a single integer), so it will have the type Int => Int.

To put it short, eta-expansion turns a method into a function which will take the remaining argument lists (however large) in turn, however long the chain may be.

Conclusion

We covered eta-expansion and its application in defining function values converted from methods and in partially applied functions.

Check out the Rock the JVM blog for more articles like this and our YouTube channel for their video versions. For fresh updates, follow us on Twitter and LinkedIn!

Topics:
scala

Published at DZone with permission of Daniel Ciocirlan . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}