2

Function Literals in Scala

By Michael Alfaro on February 23, 2013
Share on Facebook0Tweet about this on Twitter3Share on LinkedIn0Google+0

scala_logoIf you come from an imperative language background like many of us do, you may find it hard to avoid mutable data types in Scala.  Scala gives the option to use mutable data, but that really pushes you away from the functional beauty of Scala.

One trick that will help you avoid having to reach for a mutable type is something called a “Function Literal”, which is essentially a function made on the fly without being bound to an identifier.  Function literals also have many other uses beyond what this post will discuss, but you should still have a good feel for function literals after this.

 

1. Introduction to Function Literals

Here’s the standard structure for a function literal:

(arg1 : ArgType, arg2 : ArgType, ... , argN : ArgType) => Function Body

In most cases, you can ignore the argument’s types, due to Scala’s type system.

(arg1, arg2) => Function Body

Here are a few example function literals:

(x : Int, y : Int) => x * y

(x, y) => x + y

x => x*10

It’s important to note the parentheses can be ignored if you have only one param

 

2. Basic Example

Now that we understand the structure of function literals we’ll now go over some basic applications of function literals.

Here’s a function that will evaluate the literal you pass into it at 1, 10 and 100.

def evaluateAndPrint( foo: Int => Int ){
   println("Here's the result of your literal at 1: "+ foo(1))
   println("Here's the result of your literal at 10: "+ foo(10))
   println("Here's the result of your literal at 100: "+ foo(100))
}

Now let’s try running evaluateAndPrint with a few different literals.

evaluateAndPrint(bar => bar*2)

>Here's the result of your literal at 1: 2
>Here's the result of your literal at 10: 20
>Here's the result of your literal at 100: 200

evaluateAndPrint(baz => baz*baz)

>Here's the result of your literal at 1: 1
>Here's the result of your literal at 10: 100
>Here's the result of your literal at 100: 10000

3. Using Literals in Lists

In this example I’ll show you some of the methods of list that require literals as arguments. Frequently if you were to do this in Java there would be mutable types being used, here there are none.

Here I make a list

scala> val myList = List("foo", "bar", "baz", "abcd")
myList: List[java.lang.String] = List(foo, bar, baz, abcd)

Checking the number of elements whose length are 3.

scala> myList.count(s => s.length == 3)
res0: Int = 3

Checking if bar exists in the list

scala> myList.exists(s => s == "bar")
res1: Boolean = true

Adding another “bar” to the end of every element.  This does not modify the current list, but rather returns a new list.

scala> myList.map(s => s + "bar")
res2: List[java.lang.String] = List(foobar, barbar, bazbar, abcdbar)

Verifying that myList has not changed.

scala> println(myList)
res3: List(foo, bar, baz, abcd)

This will return a new list without the elements whose length are 3

scala> myList.remove(s => s.length == 3)
res4: List[java.lang.String] = List(abcd)

Again, verifying that our list has not changed.

scala> println(myList)
res5: List(foo, bar, baz, abcd)