Published 2014-01-13.
Last modified 2024-08-12.
Time to read: 7 minutes.
This lecture continues from the Functions are First Class and
Closures lectures.
You should be comfortable with that material before working through this lecture.
It shows how Function0
, Function1
and lazily evaluated parameters are related.
Currying and functional composition are also discussed.
This lecture is referred to by many other lectures in the Intermediate Scala course. You need to know this material well if you want to become a good Scala programmer.
The sample code for this lecture can be found in
courseNotes/
.
Call By Name / Lazy Evaluation of a Parameter
So far we have only discussed eagerly evaluated parameters,
which means the arguments are evaluated prior to passing the computed value into a method or FunctionN
.
For example, timidPi1
is a method that eagerly evaluates its value
parameter.
scala> import java.util.Calendar import java.util.Calendar
scala> val isWitchingHour: Boolean = Calendar.getInstance().get(Calendar.HOUR_OF_DAY) == 0 isWitchingHour: Boolean = false
scala> def timidPi1(value: Int): String = if (!isWitchingHour) s"Eager evaluation yields $value" else "I am too scared to compute" timidPi1: (value: Int)String
Let’s invoke timidPi1
with a constant.
scala> timidPi1(3) res2: String = Eager evaluation yields 3
Now let’s invoke timidPi1
with a stateful object that returns an Int
.
scala> object Stateful { | var count = 0 | def increment = { | count = count + 1 | count | } | } defined object Stateful
scala> timidPi1(Stateful.increment) res3: String = Eager evaluation yields 1
scala> timidPi1(Stateful.increment) res4: String = Eager evaluation yields 2
scala> timidPi1(Stateful.increment) res5: String = Eager evaluation yields 3
Each time timidPi1
is invoked with a stateful method call the state changes,
which is why Stateful.increment
computes a monotonically increasing value.
This should not be surprising.
If we reference the value
parameter inside timidPi1a
the same quantity is returned,
which is also what we expect.
scala> def timidPi1a(value: Int): String = if (!isWitchingHour) s"Eager evaluation yields $value, yes $value" else "I am too scared to compute" timidPi1a: (value: Int)String
scala> timidPi1a(3) res10: String = Eager evaluation yields 3, yes 3
You can defer evaluation of a parameter until it is referenced inside a method using call by name syntax, also known as lazy evaluation.
scala> def timidPi2(value: => Int): String = if (!isWitchingHour) s"Lazy evaluation yields $value" else "I am too scared to compute" timidPi2: (value: Int)String
Notice how similar the above is to defining an eagerly evaluated parameter.
The only difference is the addition of a rocket (right arrow) between the colon following the name of the variable and the variable type.
Also notice that the resulting syntax almost looks like a function type without a parameter list.
Let’s try invoking timidPi2
with a constant, and with the Stateful
object.
scala> timidPi2(3) res7: String = Lazy evaluation yields 3
scala> timidPi2(Stateful.increment) res8: String = Lazy evaluation yields 4
scala> timidPi2(Stateful.increment) res9: String = Lazy evaluation yields 5
Again, not surprising.
Now let’s modify timidPi2
so it references value
twice.
scala> def timidPi2a(value: => Int): String = if (!isWitchingHour) s"Lazy evaluation yields $value, yes $value" else "I am too scared to compute" timidPi2a: (value: Int)String %
And we’ll run timidPi2a
.
scala> timidPi2a(3) res11: String = Lazy evaluation yields 3, yes 3
scala> timidPi2a(Stateful.increment) res12: String = Lazy evaluation yields 6, yes 7
scala> timidPi2a(Stateful.increment) res13: String = Lazy evaluation yields 8, yes 9
So we see that value
is evaluated each time it is mentioned – this is the big difference with lazy evaluation.
Yes, evaluation is deferred until the value of value
is required, but the evaluation happens afresh for each reference.
In contrast, here is a similar statement that accepts a no-argument Function
, known as a
Function0
.
scala> def timidPi3(value: () => Int): String = if (!isWitchingHour) s"Evaluating function yields ${value()}" else "I am too scared to compute" timidPi3: (value: () => Int)String
Let’s invoke timidPi3
.
scala> timidPi3(() => 3) res17: String = Evaluating function yields 3
scala> timidPi3(() => Stateful.increment) res18: String = Evaluating function yields 12
scala> timidPi3(() => Stateful.increment) res19: String = Evaluating function yields 13
In this circumstance, Function0
provides a more awkward syntax than lazy evaluation, but identical semantics.
Let’s try it with multiple references to value.
scala> def timidPi3a(value: () => Int): String = if (!isWitchingHour) s"Evaluating function yields ${value()}, yes ${value()}" else "I am too scared to compute" timidPi3a: (value: () => Int)String
The results are again consistent with call by name / lazy evaluation semantics.
scala> timidPi3a(() => 3) res20: String = Evaluating function yields 3, yes 3
scala> timidPi3a(() => Stateful.increment) res21: String = Evaluating function yields 14, yes 15
scala> timidPi3a(() => Stateful.increment) res22: String = Evaluating function yields 16, yes 17
You can run this code by typing.
$ sbt "runMain LazyEvalLevel1"
Output is as shown above.
When writing code that invokes timidPi1
and timidPi3
there is no clue in the calling code if lazy or eager evaluation will
be used.
IntelliJ IDEA can highlight those for you if you enable Settings / Languages and Frameworks / Scala / Highlight arguments to
by-name parameters, and the sub-selections Include block expressions and Include literals.

Here is a complete program that contrasts the syntax for eager evaluation, lazy evaluation and a no-arg function (Function0
).
These timidPi
methods return BigDecimal
instead of Int
because Pi
could be computed with
arbitrarily large precision.
object LazyEval extends App { import java.util.Calendar
/** The Leibniz series algorithm converges slowly to Pi. About 5 billion iterations are required to yield accuracy to 10 decimal places. * Pi is the limit of this series: 4/1 - 4/3 + 4/5 - 4/7 + 4/9 ... * @see https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80 */ def leibnizPi(iterationCount: Long=5000000000L, digits: Int=10): BigDecimal = { val numerator: BigDecimal = 4.0 var denominator: BigDecimal = 1 var plus = true var result: BigDecimal = 0.0 while (denominator < iterationCount) { if (plus) { result = result + numerator / denominator plus = false } else { result = result - numerator / denominator plus = true } denominator = denominator + 2 } result.setScale(digits, BigDecimal.RoundingMode.HALF_UP) }
val isWitchingHour: Boolean = Calendar.getInstance().get(Calendar.HOUR_OF_DAY) == 0 val scaredMsg = "I am too scared to compute"
def timidPi1(value: BigDecimal): String = if (!isWitchingHour) s"Eager evaluation yields $value" else scaredMsg def timidPi2(value: => BigDecimal): String = if (!isWitchingHour) s"Lazy evaluation yields $value" else scaredMsg def timidPi3(value: () => BigDecimal): String = if (!isWitchingHour) s"Evaluating function yields ${value()}" else scaredMsg
println(timidPi1(leibnizPi())) // eager evaluation println(timidPi2(leibnizPi())) // lazy evaluation println(timidPi3(() => leibnizPi())) // no-arg function }
You can run this program by typing.
$ sbt "runMain LazyEval" Eager evaluation yields 3.1415926532 Lazy evaluation yields 3.1415926532 Evaluating function yields 3.1415926532
Multiple Parameter Lists
Scala methods and functions can accept multiple parameter lists, a feature which is heavily used in functional programming, especially when working with libraries and frameworks. Let’s start with the simplest example, using the REPL.
scala> def myFunc(x: Int)(y: Int): Int = x*x-y myFunc: (x: Int)(y: Int)Int
scala> val foo = myFunc(3)(4) foo: Int = 5
Yes, myFunc
has two parameter lists, each of which happens to have a single parameter.
You can have as many parameter lists as you want, but it is rare to have more than two.
There are many reasons for using multiple parameter lists, which we will discuss in this lecture, and in several lectures of the
Intermediate Scala course.

In the example above, myFunc
is referred to as a
curried function because it is actually
implemented as a chain of two Function1
instances (single parameter functions).
We’ll discuss currying in the Partially Applied Functions
lecture of the Intermediate Scala course.
The term has nothing to do with Asian cooking – instead, it is named for
Haskell Curry
the famous American mathematician and logician.
Incidentally, Scala’s functional programming constructs were inspired by the pure functional language
Haskell, also named for Haskell Curry.
Scala lets us replace parenthesis with curly braces around an argument list. These method invocations all produce the same result.
myFunc(3)(4) myFunc(3){4} myFunc(3) { 4 } myFunc(3) { 4 }
Multiple argument lists give us a very nice looking block structure syntax when the parameter accepts a lazily evaluated block of code or a
FunctionN
.
We can use this feature to easily create our own control structures.
The With Pattern described later in this lecture is an excellent example of this.
Here are a couple of simple examples. You will learn more Scala programming techniques in the Intermediate Scala course which will allow you to construct more practical and complete designs with multiple parameter lists, and passing code blocks and functions as arguments.
Handmade unless Construct
def unless(cond: Boolean)(body: => Unit): Unit = if (!cond) body
unless
will only execute body
if the predicate cond
is false
.
The predicate is not lazily evaluated, which means it is evaluated when this method is invoked.
What’s more, body
is only evaluated if cond
is false
.
Here’s an example of how it’s used.
scala> var x = 1 x: Int = 1
scala> unless(x == 0) { println(s"I can divide by x because x is not zero: ${3 / x}") } I can divide by x because x is not zero: 3
scala> x = 0 x: Int = 0
scala> unless(x == 0) { println(s"I can divide by x because x is not zero: ${3 / x}") }
The AntiPatterns: Eager Evaluation and Closing Over External State section of the Partially Applied Functions lecture discusses this concept further.
Handmade until Construct
until
is the inverse of a while loop.
It always executes body
at least once, and it keeps invoking itself as long as the predicate cond
is false
.
This means that both cond
and body
must be lazily evaluated, so their values are computed each time the method recursively
invokes itself.
If these parameters were eagerly evaluated, their values would be fixed on the first invocation and the program might never terminate, and probably
would not produce correct results.
import scala.annotation.tailrec @tailrec def until(body: => Unit)(cond: => Boolean): Unit = { body if (!cond) until(body)(cond) }
Here’s an example of how to use until
.
var i = 0 until { println(s"$i squared = ${i * i}") i += 1 } (i == 10)
You can run these examples by typing:
$ sbt "runmain MultipleParamLists" 0 squared = 0 1 squared = 1 2 squared = 4 3 squared = 9 4 squared = 16 5 squared = 25 6 squared = 36 7 squared = 49 8 squared = 64 9 squared = 81
“With” Pattern
The With Pattern is commonly used in many languages and frameworks. For example, Play Framework uses something similar for request handling in controllers.
case class Blarg(i: Int, s: String)
def withBlarg(blarg: Blarg)(operation: Blarg => Unit): Unit = operation(blarg)
Walking through the code:
- An instance of
Blarg
gets passed into thewithBlarg
method as the only parameter in the first parameter list for that method. - The second parameter list accepts one parameter, which is a function that receives a
Blarg
and returnsUnit
. In other words, the function is only useful for its side effects. BTW, the With Pattern does not require the function to returnUnit
. - The body of
withBlarg
merely causes theoperation
passed in from the second parameter list to be invoked on theBlarg
instance that was passed in from the first parameter list.
Let’s try out this code. Notice that we use squiggly braces to demark the second parameter list, because it is more legible.
scala> withBlarg(Blarg(1, "blarg")) { blarg => | println(blarg) | } Blarg(1,blarg)
We can use shorthand syntax because there is only one reference to the Blarg
in the lambda function.
scala> withBlarg(Blarg(2, "asdf")) { println(_) } Blarg(2,asdf)
We can use an even terser shorthand syntax because println
only receives one parameter.
scala> withBlarg(Blarg(3, "qwer")) { println } Blarg(3,qwer)
The With pattern will be revisited in the ’With’ Pattern Using Implicits section of the Implicit Values lecture of the Intermediate Scala course, further developed in the ’With’ Pattern Revisited section of the Parametric Types lecture of the same course, enhanced yet again in the Parametric ’With’ Pattern Revisited section of the Partial Functions lecture and even further enhanced in the Structural Types With Parametrics section of the Structural Types lecture.
Setup
Lets define a trait and a few functions for use later in this lecture.
Here we see a trait that extends Function1[Int, Int]
, expressed with syntactic sugar (Int => Int
).
The trait defines two methods: apply
, which is a default method and so is implicitly called if no method name is provided, and tilde
(~
), commonly used in Scala as a synonym for "and then".
The use of andThen
is a form of method composition, also known as method chaining.
We will see how that works in a second.
trait Fn extends (Int => Int) { def apply(x: Int): Int
def ~(f: => Fn) = this andThen f }
val addOne: Fn = new Fn { def apply(x: Int) = 1 + x }
val multiplyTwo: Fn = new Fn { def apply(x: Int) = 2 * x }
The trait Fn
is abstract because the apply
method is not implemented.
addOne
and multiplyTwo
are instances of anonymous classes which implement the trait’s abstract apply
method.
The Scala compiler can infer which constructor to invoke according to the declared type to be returned.
This allows addOne
and multiplyTwo
to be defined without writing new Fn
, like this.
val addOne: Fn = (x: Int) => 1 + x
val multiplyTwo: Fn = (x: Int) => 2 * x
This works because Scala silently uses the defined type for functions (Fn
) to call the constructor for that type.
If you do not declare the type then the Scala compiler defines the returned type to be Int => Int
, which is not useful.
val addOneNG = (x: Int) => 1 + x val multiplyTwoNG = (x: Int) => 2 * x // Does not compile because addOneNG and multiplyTwoNG have type Function1[Int, Int], which does not define a method called ~ // addOneNG ~ multiplyTwoNG
Composition

Let’s use these definitions. First, let’s call each method separately.
scala> addOne(2) res14: Int = 3
scala> multiplyTwo(4) res15: Int = 8
Next we can compose the two functions together, thereby defining a new instance of a new anonymous class, also with type Int => Int
.
scala> val compute = multiplyTwo ~ addOne compute: Int => Int = <function1>
Now we can invoke this new function by passing it an Int
.
Because the definition of ~
is for this
(which is multiplyTwo
) to be performed, andThen f
to be
performed (which is addOne
), the argument is first doubled then one is added.
scala> compute(2) res16: Int = 5
We can define another anonymous class, which defines a function that performs the operations in the opposite order, and invoke it all together, like this.
scala> (addOne ~ multiplyTwo)(6) res17: Int = 14
Method Lifting Turns Varargs into a Sequence

Just as a reminder, repeated arguments (also known as varargs, discussed in the
Classes lecture) are denoted by an asterisk,
and the arguments are received as a Seq
.
The following code defines a method foo
that accepts one or more integers:
scala> def foo(ns:Int*) = ns.sum foo: (ns: Int*)Int
scala> foo(1,2,3) res11: Int = 6
Notice what happens when we lift foo
to a Function1
.
scala> val foov = foo _ foov: Seq[Int] => Int = <function1>
The type of foov
is Seq[Int] => Int
.
In other words, it is a Function1
that accepts a Seq[Int]
and returns an Int
.
We can call it by supplying a sequence, which is just a list of Int
.
scala> foov(Seq(1,2,3)) res12: Int = 6
We will discuss sequences and lists (and much more) in the Collections Overview lecture of the Intermediate Scala course.
Dispensing with App and DelayedInit
We first came across the App
trait in the Hello, world! Exercise in
the SBT Project Setup lecture.
By now you know that App
can be used to create a Scala console application.
I did not mention at the time that App incorporates behavior from
DelayedInit
.
This can cause problems when creating new instances of objects.
The following Program
abstract class is a drop-in replacement for App
that does not use DelayedInit
.
package app
abstract class Program[U](body: => U) { def main(args: Array[String]): Unit = { body() } }
object MyThing extends Program({ println("hello world") })
Can you explain what this sample program does?
© Copyright 1994-2024 Michael Slinn. All rights reserved.
If you would like to request to use this copyright-protected work in any manner,
please send an email.
This website was made using Jekyll and Mike Slinn’s Jekyll Plugins.