A real-world functional programming example in Scala

Table of Contents

  1. Problem
  2. Solution
  3. Discussion
  4. See Also

This is an excerpt from the 1st Edition of the Scala Cookbook (partially modified for the internet). This is Recipe 9.9, “A real-world functional programming example in Scala.”

Problem

Understanding functional programming concepts is one thing; putting them into practice in a real project is another. You’d like to see a real example of functional programming in Scala.

Solution

To demonstrate some of the functional programming (FP) techniques that I introduced earlier in this chapter, the following example shows one way to implement Newton’s Method, a mathematical method that can be used to solve the roots of equations.

As you can see from the code, the method named newtonsMethod takes functions as its first two parameters. It also takes two other Double parameters, and returns a Double. The two functions that are passed in should be the original equation (fx) and the derivative of that equation (fxPrime).

The method newtonsMethodHelper also takes two functions as parameters, so you can see how the functions are passed from newtonsMethod to newtonsMethodHelper. Here is the complete source code for this example:

object NewtonsMethod {

    def main(args: Array[String]) {
        driver
    }

    /**
      * A "driver" function to test Newton's method.
      * Start with (a) the desired f(x) and f'(x) equations,
      * (b) an initial guess and (c) tolerance values.
      */
    def driver {
        // the f(x) and f'(x) functions
        val fx = (x: Double) => 3*x + math.sin(x) - math.pow(math.E, x)
        val fxPrime = (x: Double) => 3 + math.cos(x) - math.pow(Math.E, x)
        val initialGuess = 0.0
        val tolerance = 0.00005
        // pass f(x) and f'(x) to the Newton's Method function, along with
        // the initial guess and tolerance
        val answer = newtonsMethod(fx, fxPrime, initialGuess, tolerance)
        println(answer)
    }

    /**
      * Newton's Method for solving equations.
      * @todo check that |f(xNext)| is greater than a second tolerance value
      * @todo check that f'(x) != 0
      */
    def newtonsMethod(fx: Double => Double,
                      fxPrime: Double => Double,
                      x: Double,
                      tolerance: Double): Double = {
        var x1 = x
        var xNext = newtonsMethodHelper(fx, fxPrime, x1)
        while (math.abs(xNext - x1) > tolerance) {
            x1 = xNext
            println(xNext) // debugging (intermediate values)
            xNext = newtonsMethodHelper(fx, fxPrime, x1)
        }
        xNext
    }

    /**
      * This is the "x2 = x1 - f(x1)/f'(x1)" calculation
      */
    def newtonsMethodHelper(fx: Double => Double,
                            fxPrime: Double => Double,
                            x: Double): Double = {
        x - fx(x) / fxPrime(x)
    }
}

Discussion

As you can see, a majority of this code involves defining functions, passing those functions to methods, and then invoking the functions from within a method.

The method name newtonsMethod will work for any two functions fx and fxPrime, where fxPrime is the derivative of fx (within the limits of the “to do” items that are not implemented).

To experiment with this example, try changing the functions fx and fxPrime, or implement the @todo items in newtonsMethod.

The algorithm shown comes from an old textbook titled Applied Numerical Analysis, by Gerald and Wheatley, where the approach was demonstrated in pseudocode.

See Also