Thursday, December 28, 2017

Back2Basics: Do you know Scala Eta-Expansion and HOF Chemistry?

I am working on Scala from last 2 years, and pretty confident about Scala concept like HOF, Currying and more. But Recently again looking into the HOF (Higher Order Functions) in Scala. I am pretty confident, HOF is "Passed a function as an argument", "Assign functions to variables" and "Return functions from function" and the conclusion is Functions are First Class Citizen.

For me, these below statements are equal:-


First is, anonymous function or lambda expression and second is a function with the name. But we can pass these two function to any function which accepts the function as an argument with this signature Int => Int.

While I am trying to execute these two statements in scala REPL, but this time I noticed, the output of these two statements are different, which insist me to investigate why this behavior?


The first line of code initializes some lambda expression but the second one defines as a function signature.

NOTE: In Scala 2.12.x Function[x] traits act as a Java 8 lambda expression rather than anonymous inner classes.  

After that, while I am looking into the Scala collection API `def map[B] (f: (A) ⇒ B)List[B]` method argument which looks like `val func = .. ` type but different from `def funcd ... ` type.

So, next question is, while I am trying to execute code using func and funcd with Listmap`  method, the code execution is successful???


But If we try to assign def funcd.. to the variable, We are getting this error.


After investigation the whole stuff, We are found the answer in one or two words called "Eta-Expansion". This term itself is a broad term. But in the layman term compiler use Eta-Expansion for convert  `def func ...` type to `lambda expression` or before Scala 2.12.x it converts into traits Function[x].

So, while we are trying to assign def func ... into the variable, we need to trigger Eta-Expansion manually which in Scala called Partially Applied Functions.


For Eta-Expansion, you can further read:
If you want to see the compiler translation, copy the whole bunch of code into scala file and compile using `$ scalac -Xprint:all Test.scala` command.


These are thousands of lines are going to print, which I have no idea, what happens under the hood, but for us, the important part is Eta-Expansion which happens below:


I am using translation as compiler steps, but not sure what we called. But according to above output, we can estimate somethings automatically happen in the case of the list as same as while we trigger Eta-Expansion manually.