Scala for the Impatient

Functional Programming L1

Copyright © Cay S. Horstmann 2015

Understand the concept of functional programming

Functions as Values

Anonymous Functions

Work with higher-order functions

Functions with Function Parameters

Functions That Produce Functions

Parameter Inference

Apply the map, filter, and reduce methods

Map, Filter, Reduce

Understand the concepts of closures and currying

Closures

Currying

Image source: https://wiki.haskell.org/Haskell_Brooks_Curry

Currying for Type Inference

Develop control abstractions

Control Abstractions

Lab

Scary looking lab

Practice applying map, filter, reduce

Part 1: Life Without Loops

  1. In Scala, we prefer to use higher-order functions instead of loops. Let's explore that with an interesting data set. In a new worksheet, enter the following:
    val zones = java.util.TimeZone.getAvailableIDs
    What do you get?
  2. We want to get rid of the continents. Try this:
    zones.map(s => s.split("/"))
    
  3. Okay, halfway there. Add a map that takes an array and yields a(1). What did you do? What happens?
  4. Hmmm, that's weird. There seem to be arrays of length < 2. How can you find them?
  5. Okay, now get rid of them and try again. What did you do?
  6. That's a lot of values. Can we get every tenth of them? (Hint: grouped(10))
  7. What would it have taken to write that in Java?

Part 2: Reductions

  1. Evaluate
    1.to(10).reduceLeft(_ * _)
    What do you get?
  2. Write a function that computes n! in this way.
  3. Surely you have written a factorial function before. How did you used to do it? Which approach do you like better?
  4. Now we'd like to compute 2n with the same trick. How can you get a sequence of n copies of the number 2? Hint: map
  5. What is your function that computes 2n?
  6. Given a Seq[String], how can you use reduceLeft to concatenate them with some separator in between? Write a function concat(strings: Seq[String], separator: String) that does this. For example, concat(Array("Mary", "had", "a", "little", "lamb"), " ") should give a string "Mary had a little lamb".

Practice developing higher-order functions

Part 3: Do-It-Yourself while

  1. You've seen how to implement a runInThread statement in Scala. You can even implement basic control statements such as while. We'll have to call it While so it doesn't conflict with the Scala keyword. We'll have two arguments, the condition and the body. We start out the ugly way, with zero-arg functions. For example:
    val n = 10
    var i = 1
    var f = 1
    While(() => i < n, () => { f *= i; i += 1 })
    
    How do you declare While? (Just the header, not the implementation)
  2. Now on with the implementation. If the condition is true, execute the body. Then call the function recursively. What do you get when running the code snippet above?
  3. Now use by-name parameters so that you can make the call in this way:
    While(i < n, { f *= i; i += 1 })
    
  4. It's still a little ugly. Make it so that you can call the following:
    While(i < n) { f *= i; i += 1 }
    Hint: Curry