Functions and Methods (Scala 3 Video)
As with other programming languages, a Scala function lets you create a reusable block of code. This is a set of instructions that performs a specific task, and like other languages, a function should do only one thing, like read a file, write to a web service, calculate tax on an order, etc.
A function typically takes one or more input parameters, runs its algorithm, and then has a return value. For example, this is a function that doubles the integer it’s given:
def double(i: Int): Int = i * 2
When you first start working with Scala, it may be easier to read the function when the function body is on a separate line, like this:
def double(i: Int): Int =
i * 2
Return vs yield or evaluate
In Scala we don’t say that a function returns a result as much as it yields a result or evaluates to a result, and I’ll talk about this as we go through these function lessons.
Function vs method
Scala 3 blurs the lines between a function and a method, so I use this terminology:
- If it’s inside a
class
ortrait
, I call it a method - Otherwise, I call it a function
Functions and methods can be defined in these locations:
- In a
class
,trait
, orobject
- In Scala 3, functions don’t have to be in those containers; they can be outside of those containers, and we call these toplevel functions
Other features of functions
- Parameters can have default values
- Advanced: a feature known as “givens”
- Advanced: a function can have multiple input parameter groups
General syntax
A basic function looks like this:
def functionName(param1: Type1, param2: Type2): ReturnType =
// the
// function
// body
Functions can get more complicated when we use:
- Generic parameters
- Default parameter values
- An advanced feature known as “givens”
You’ll see those features in future lessons.
First examples (one-liners)
These are some functions that I define on one line:
// define them
def add(i: Int, j: Int): Int = i + j
def multiply(i: Int, j: Int): Int = i * j
// use them
val a = add(1, 1)
val b = multiply(1, 1)
Here’s an example of a function body that is more than one line long:
// note: last line is the value the function yields
def add(i: Int, j: Int): Int =
// comment
i + j
Notice that you just indent the body of the function.
More of a real-world, multiline example:
// [1] this works, and uses one variable at a time
def multilineStringToList(s: String): Seq[String] =
val linesArray: Array[String] = s.split("\n")
val linesSeq = linesArray.toSeq
val linesTrimmed = linesSeq.map(_.trim)
linesTrimmed.filter(_ != "")
// [2] this is the same algorithm
def multilineStringToList(s: String): Seq[String] =
s.split("\n")
.toSeq
.map(_.trim)
.filter(_ != "")
// [3] this is how you use either of those functions
val ms = """
one
two
three
"""
multilineStringToList(ms)
The function return type
Specifying the function return type is optional, but I almost always declare it. One place you might not declare it is in small scripts.
def add(i: Int, j: Int): Int = i + j // with the return type
def add(i: Int, j: Int) = i + j // without the return type
A function can return whatever you need, such as a tuple:
def strlen(s: String): (String, Int) =
(s, s.length)
or a list of tuples:
def strlens(xs: Seq[String]): Seq[(String, Int)] =
xs.map(s => (s, s.length))
val names = List("joey", "pacey", "dawson")
val namesAndLengths = strlens(names) // Seq[(String, Int)]
namesAndLengths.foreach( t => println(s"${t(0)}, ${t(1)}"))
namesAndLengths.foreach( t => println(s"${t._1}, ${t._2}"))
Or anything else you need!
Update: All of my new videos are now on
LearnScala.dev