Start learning free

LESSON 29 OF 414 · FUNCTIONS I

Defining a Function in Scala: Fixing the Buggy Code

Practice Read the full explanation

Inside the code editor we've tried just to define a function (without calling the function) that would print the message Hey, Andy! whenever called.

It seems like we made some mistakes because our code doesn't compile: we get an error.


Assignment:

Your task is to fix our function definition such that no errors will be produced.

STEP 1 OF 1
    Ctrl + Enter to check

    SCALA · FUNCTIONS I

    Buggy Code Defining A Function in Scala, explained

    What the code is supposed to do

    The goal is small: define a function named sayMyName that prints Hey, Andy! each time it is called. The task asks only for the definition. Nothing calls the function, so a correct answer compiles and prints nothing.

    The code you start with looks almost right, but it doesn't compile:

    def sayMyName(): Unit
    println("Hey, Andy!")
    

    Your job is to find out why and fix the definition so the compiler accepts it.

    What goes wrong

    A person reading these two lines guesses that the second one belongs to the first. The compiler doesn't guess. It reads def sayMyName(): Unit as a complete declaration: a method with a name, empty parentheses and a result type, but no body. Then it treats println("Hey, Andy!") as a separate statement that has nothing to do with sayMyName.

    That causes two problems:

    1. The method has no body. A declaration without a body is only allowed where a class leaves a member to be filled in later. Outside that situation, the compiler reports: Declaration of method sayMyName not allowed here: only classes can have declared but undefined members.
    2. The print line belongs to no method. Because nothing connects it to sayMyName, it is a loose statement. It would run on its own, whenever the surrounding code runs, rather than when sayMyName is called. Depending on where the code sits, the compiler may reject it as well.

    Because the code doesn't compile, nothing runs, and you see an error instead of any output.

    How a body is attached: = and braces

    Every Scala method definition has these parts:

    • the keyword def;
    • the name, here sayMyName;
    • parentheses holding the parameters, empty here because the method needs no input;
    • a result type after a colon, here Unit, meaning no useful value;
    • the = sign, which says "this method is defined as the following code";
    • the body: the statements to run, wrapped in { and }.

    The = is what connects the signature to the body. Without it, the line is only a declaration. The braces are what mark the start and end of the body when it holds several statements. Indentation doesn't count: indenting println under the header would make the code look right to a person and change nothing for the compiler.

    Fixing it step by step

    1. Keep the signature. def sayMyName(): Unit already has the keyword, the exact name the task asks for, empty parentheses and the result type.
    2. Add = and open the body. End the first line with = {. The equals sign makes it a definition, and the brace starts the body.
    3. Move the statement inside. The println line goes between the braces, indented so readers can see it belongs to the method.
    4. Close the body. Put } on its own line below the statement.
    5. Don't add a call. The task says to define the method, not to call it.

    The fixed code in Scala

    def sayMyName(): Unit = {
        println("Hey, Andy!")
    }
    

    A few Scala details about these three lines:

    • Unit. It is the result type of a method that returns nothing useful. Its one value is written ().
    • The last expression is the value. A Scala block gives back the value of its last expression. Here that is the result of println, which is (), matching the declared Unit.
    • No semicolons needed. A statement ends at the end of the line.
    • The exact text matters. The comma, the space and the exclamation mark in "Hey, Andy!" are all part of the output. "Hey Andy!" would print something different.
    • A shorter form. When the body is a single expression, the braces are optional: def sayMyName(): Unit = println("Hey, Andy!") works the same way. The braced form is the one to use as soon as a method has more than one statement.

    Defining is not running

    Once the definition compiles, nothing has been printed yet. The body runs only when something calls the method by writing its name followed by parentheses:

    def sayMyName(): Unit = {
        println("Hey, Andy!")
    }
    
    sayMyName()
    sayMyName()
    

    Run as a program, this prints Hey, Andy! twice. Each call runs the body again. For this lesson, submit the definition alone.

    Common mistakes

    • Adding braces but no =. def sayMyName(): Unit { ... } doesn't give the method a body. The = is required.
    • Adding = but leaving the print outside. def sayMyName(): Unit = {} followed by the println line gives the method an empty body and leaves the statement outside it, so the original problem remains.
    • Indenting instead of using braces. The code looks right but is still a bodiless declaration plus a loose statement.
    • Forgetting the closing brace. The compiler reaches the end of the code while still inside the body.
    • Changing the name. Scala names are case-sensitive: saymyname and SayMyName are different from sayMyName.
    • Adding a call. The call would print the message, which the task didn't ask for.

    Checking your fix

    Make the change in the editor above and run it. A correct fix compiles without errors and prints nothing, because the method is defined but never called.

    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free