Scala Foundation Course - Basics of Scala Functions


Scala is a functional programming language. Right? So, functions are the basic building blocks in Scala. In any other programming language, learning about function is as simple as learning one basic syntax. I mean, you just need to know the syntax to define a function. That's it. But that approach doesn't work with Scala. I often see a lot of confusion that makes it difficult for a beginner. And I blame two things for causing this trouble.

  1. Optional components and flexible syntax.
  2. Jargons and functional programming concepts.

There are several optional components and flexible syntax. They often create a lot of confusion. Then, there are a bunch of functional programming jargons. I have tried to separate out some of them in part two of this tutorial. And you are already familiar with them such as Pure Functions, Higher Order Functions, Anonymous functions, Recursion, Tail Recursion, and Closures. But there are few more, and I will cover them here. This video takes a systematic and step by step approach to eliminate all the confusions around Scala functions.
So, let’s start.

Scala Function syntax

Here is the typical syntax to define a function.

                                
    def functionName ([<parameterName> :<type> [, ....]]) : [return type] = {
        <function body>
        return [expr]
    }                                                   
                         

The def, starts a function definition. Then you give a name or an identifier. The next one is the parameter list. You can provide a list of parameters in a parenthesis. Then the return type of the function. And finally, the body.
One important thing to remember is that the function must return something. If you think that it doesn't need to return a meaningful value, it should return a unit value. But it must return a value. That's a quite simple syntax.

Optional Syntax elements

The first source of confusion is the optional part of the above syntax. Let's create an example function.

                                
    def myMax(x:Int, y:Int) : Int = {
        if (x > y) 
            return x;
        else 
            return y;
    }                                               
                         

We will use this example to understand the optional components of a Scala Function. So, first thing first.

The semicolon

The semicolon is optional. You might want to ask following question.
Then How do we terminate the expression?
The answer to that questions is another question.
Why do you want to give a semicolon when you already press an enter key after every line?
Scala language is full of shortcuts and allows programmers to type only that is necessary. So, do this. Type one expression per line. You anyway do this to keep your code well formatted and readable. But if you want to be sloppy and write more than one expressions on a single line, use a semicolon.
What about long expressions? Do you want to fit below expression into a single line?

                                
    ['^(([^<>()[\]\\.,;:\\s@\"]+(\\.[^<>(),[\]\\.,;:\\s@\"]+)*)',
                                    '|(\\".+\\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.',
                                    '[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\\.)+',
                                    '[a-zA-Z]{2,}))$'].join('')
                                                       
                         

No, Scala allows you to extend long expressions to multiple lines. The compiler is smart, and it will try to combine them and interpret it as a single expression. But it is not always possible to correctly interpret a multi-line expression. So, I recommend that you enclose it within a pair of parenthesis.

The return keyword

The next one is the return keyword. The return keyword is optional.
That seems like a big problem. How do I know that a function is returning something?
The answer to that question is also simple. You learned a fundamental rule. Scala function always returns a value. So, you always know that the function is returning something. A function always returns the value of the last executed expression.
Let’s look at our example. If you eliminate semicolon and return. The function looks like this. If the condition is true, this x is the last expression. If the condition is false, y is the last expression.

                                
    def myMax(x:Int, y:Int) : Int = {
        if (x > y) 
            x
        else 
            y
    }
    //I can squeeze it further like this.
    def myMax(x:Int, y:Int) : Int = {
        if (x >y)  x  else  y
    }                                       
                         

When you have a single line in the function body, you can also leave the curly braces. So, the code looks like this.

                                
    def myMax(x:Int, y:Int) : Int = if (x > y)  x  else  y                                       
                         

We already learned that the Scala compiler could infer the return type of a function. So, the return type is also optional. Now the code looks like this.

                                
    def myMax(x:Int, y:Int) = if (x > y)  x  else  y                                       
                         

These type of single line functions and methods are common in Scala. You will often see them. You will also see multi-line functions in Scala. But they will have a pair of curly braces around the body.
Like this.

                                
    def myMax(x:Int, y:Int) = { if (x > y)  x  else  y }                                          
                         

The = symbol

When you have a pair of curly braces around the function body, the = symbol is optional.
But don't do that. I mean, never remove the = symbol.
Why? Is there a problem?
Yes, you remove the = symbol, and the compiler assumes that the function is returning a unit. Your compiler may or may not give you a warning. But it will infer the return type as a unit even if you are returning something else. So, don't remove the = symbol.

The () for empty parameter list

Let’s look at the function definition as shown below.

                                
    def hWorld() = println("Hello World!")                                           
                         

It doesn't have any parameters. Can I remove the parenthesis?
Let me ask you another question before I answer the first question.
Do you know, how many ways you can call a parameter less function?
You can call it with parenthesis

                                
    hWorld()                                          
                         

You can also call it without the parenthesis.

                                
    hWorld                                          
                         

The answer to the first question is a Yes. You can remove the empty parenthesis at the time of defining a function. But if you do that, you won't be able to call the function with a parenthesis, I mean, hWorld() is not allowed, because you removed the parenthesis from the definition.
Let me repeat it.
Keep the parenthesis in the definition and you should be able to call it with or without parenthesis. Remove the parenthesis from the definition and you cannot call it with a parenthesis. Next related question. Which one should I use?
Use parenthesis when the function has a side effect. When the function doesn't have a side effect, you should define it and call it without parenthesis.
That's a convention. A parameter less function with a parenthesis indicates a side effect. It will help you and others to read your code.
Great, we talked about the basics of a Scala function.
Here is the list of the key takeaways from this session.


  1. You learned the syntax to define a function.
  2. Semicolon is optional in Scala.
  3. Scala compiler expects one expression per line.
    1. If you want to have multiple expressions on a single line, separate them using a semicolon.
    2. It is recommended to enclose the multiline expression in a pair of parenthesis.
  4. The return statement is optional. The recommendation is to avoid using it.
  5. You can also skip the curly braces for a single line function body.
  6. The return type of a function is optional if Scala compiler can infer the return type.
  7. Never forget the = symbol before a function body.
  8. The empty parenthesis is optional for a parameter less function
    1. Use empty parenthesis for a function that has a side effect.
    2. Do not use empty parenthesis for a pure function.

We will continue the discussion on Scala function in the next video.
Thank you for watching Learning Journal. Keep Learning and Keep growing.


You will also like:


Functional Programming

What is Functional Programming and why it is important?

Learning Journal

Scala Variable length arguments

How do you create a variable length argument in Scala? Why would you need it?

Learning Journal

Scala named arguments

Learn about named arguments and default values in Scala functions with examples.

Learning Journal

Anonymous Functions

Learn Scala Anonymous Functions with suitable examples.

Learning Journal