3.4 First-class functions

Scala also supports functions that are not declared to be part of a specific class. Indeed, functions in Scala are first-class objects: you can do anything with a function that you can do with an object value, such as assign a function to a variable, pass a function as a parameter to another function, or return a function from another function.

Because function values are such an important aspect of Scala programs, the language provides a convenient way to define function values via function literals. Function literals have no names, and can be used like any other type of value.

The Scala APIs are rich in methods that consume function values. For instance, Scala's List class defines a method, map, that consumes a function, applies the function to all list elements, and returns a new list of the resulting values. Using a function literal to define the parameter passed into map affords a concise way to transform list elements:

  val myList = List(123)
  val plusOne = myList.map(x => x + 1)
  ...
  List(234)

There's an even handier way to define the above function literal:

  val plusTwo = myList.map(_ + 2)
  ...
  List(345)

The underscore (_) in this function literal stands for the argument being passed to the function.

By-name parameters

In Java, all method parameters are passed by value, even object references: the parameter value is evaluated before invoking the method. Scala's default behavior also passes parameters by value. However, when passing a function or a function literal to a method, it is sometimes helpful to delay the evaluation of the parameter value:

  // Pseudocode
  myMethod(someBlockOfCodeOrFunction) = {
  
  // Do something else first   ...    // Evaluate the parameter and return its value   someBlockOfCodeOrFunction() }

Scala supports that behavior with by-name parameters. By-name parameters are not evaluated when the method is invoked; instead, you can delay the parameter's evaluation to the first time you refer to that parameter by name inside the method. To pass a parameter by name, prefix the parameter type with =>, as shown here:

  def doItByName(block: => Any) {
    println("Doing something first")
    block
  }

Invoking the doItByName method, you would get the following output:

  doItByName(println("Hello, there"))
  ...
  Doing something first
  Hello, there
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset