Scala Foundation Course - Function Literals


In the earlier video, we talked about functions. In this video, let's talk about anonymous functions or a function literal or a lambda expression. People use three different names, but essentially all of them are the same thing. I prefer calling them a Function Literal
Why do I prefer Function Literal over other names? There is a reason. Let me explain.

What is function literal in Scala

One of the basic ideas of functional programming is that the functions are the first-class citizens. They are like values. So, whatever you can do with values, you should be able to do it with the functions. Right?

  1. We can assign functions to a value.
  2. We can pass them as a parameter.
  3. We can return them from a higher order function.

You already learned that. However, here is a new thing.
We can also create values using a literal.
For example, I can create values as shown below.

                                    
    //String value
    val s = "Hello World!"
    // Integer value
    val l = 5                                           
                             

I created a value s using a string literal.Then, I created a value l using an Integer literal 5. By default, l an Integer, but I can specify the data type like below.

                                        
    val l:Long = 5
    //Another alternative for enforcing the data type is this.
    val l = 5:Long                                          
                                 

Now, let me ask a question.
Can you create a function value using a literal?
If we can create a string value using a string literal, we must be able to create a function value using a function literal. Right?
Here is the syntax for creating a function literal.

                                            
    ([<parameterName> :<type> [, ....]])  =>  {   
        <function body> 
        return [expr] 
    } : [return type]
                                                      
    //Compare it with standard def syntax for a Scala function
    def functionName ([<parameterName> :<type> [, ....]]) : [return type] = {
        <function body> 
        return [expr]
    }                                       
                                     

You can compare it with the def syntax. You will notice three differences.

  1. We don't have a Function Identifier.
  2. A right arrow symbol replaces the equal to sign.
  3. The return type moved to the end.

Let me apply this syntax and create a function.

                                                
    val f = (x:Int) => { x + 5 }                                      
                                         

It is exactly same as we created a value earlier. Instead of using a string literal, we use a function literal. That's it. I skipped the return type for this function value because Scala automatically infers the return type. However, you can enforce it by putting it in the end.

                                                    
    val f = (x:Int) => { x + 5 }:Int                                      
                                             

Let me ask you a question. We created a long value (val: Long = 5). We were able to specify the type annotation before the = symbol. Right? Can we do the same with the function literal?
The answer is Yes, you can do that. But you must remember the difference between those two places. In the end, I mean, at the end, we define a return type of the function. However, before the = symbol, we specify the type of the function that includes the input type and the return type both. Let me show you an example.

                                                        
    val f:Int => Int = (x:Int) => { x + 5 }                                      
                                                 

The input type is a single Integer, and the output is also an Integer. That's it. But you should avoid (Int => Int) because Scala should be able to infer that automatically. Let me give you a quick question for practice.
Q. Create a function value that takes two parameters.

  1. An Integer
  2. A String

The function should return another string by concatenating the string around the integer. Here is an example of input and output for your better understanding.

                                                            
    myFun(5,"-") 
    //should return -5-                                         
                                                     

Use the complete function literal syntax.
Here is the solution.

                                                                
    val myFun:(Int, String) => String = (x:Int, s:String) => { s + x + s }:String                                        
                                                         

The myFun is the value. Secondpart after the : and before the => symbol is the function type. Everything between the parenthesis is the function literal. The equal to separates the value definition and the function literal.But I recommend removing the optional parts.So, remove the function type and the return type.

                                                                    
    val myFun = (x:Int, s:String) => { s + x + s }                                       
                                                             

This is how you should be creating a function literal.

Why do we need Scala function literal?

Most of the time, you will use function literal with higher order functions. I mean, either you will be passing it to a higher order function or returning it. Let me giveyouan example. Let's take a list of customers.

                                                                        
    val customers = List( "donald", "angela","larry","narendra", "vladimir")                                      
                                                                 

You want to convert these names in proper case.You can do it by applying the following function on each element.

                                                                            
    (x:String) => x.capitalize                                      
                                                                     

So, you pass this literal to the map method.

                                                                                
    customers.map((x:String) => x.capitalize)                                      
                                                                         

Another example. You have a list of some numeric observations.

                                                                                    
    val data = List(-250, 75, 145 ,222 ,-80 ,-140 , 170 , 85 , 122, 250)                                      
                                                                             

Normalizing your data is a common activity in statistics.You want to normalize this data between 0 and 1. You can work out your normalization function and passed it to the map method.

                                                                            
    data.map( (x:Int) => 1d*(x-data.min)/(data.max-data.min)*1d)                                      
                                                                     

Passing a function literal to a higher-order function is a popular thing in Scala. You will see it all over. Great. We have seen a syntax for creating a function literal. In fact, the function literal is syntactic sugar for the def syntax. We can represent every function literal using a def syntax.
Thank you for watching Learning Journal. Keep learning and keep growing.


You will also like:


Pattern Matching

Scala takes the credit to bring pattern matching to the center.

Learning Journal

Anonymous Functions

Learn Scala Anonymous Functions with suitable examples.

Learning Journal

Referential Transparency

Referential Transparency is an easy method to verify the purity of a function.

Learning Journal

Statements and Expressions

Statements and Expressions in Scala. How are they different?

Learning Journal

Lazy Evaluations

Evaluate the expression now vs evaluate it for the first use. Strict vs Lazy?

Learning Journal