CS 330 Lecture 28 – Lambdas
Agenda
- what ?s
- program this
- passing behaviors in C
- lambdas
- map and map! in Ruby
TODO
- Read Execution in the Kingdom of Nouns and Why We Need Lambda Expressions in Java. On a 1/4 sheet, write down 2-3 questions, observations, or predictions about Java and lambdas.
Note
We start today with a little Program This, inspired by a supposedly common interview question:
Write a Haskell function
fizzbuzzOne
that accepts three parameters: two factors and a numbern
. Ifn
is a multiple of both factors, return “fizzbuzz”. If it’s a multiple of neither, returnn
as a string. If it’s a multiple of only the first, return “fizz”. If it’s a multiple of only the second, return “buzz”.Write a second function
fizzbuzzAll
that accepts a list of integers and returns a list of their fizzbuzz strings.
A major goal of programming is to push repeated code into a reusable abstraction. But we can’t push everything—only the repeated parts. Inside those repeated parts we do a lot of custom work. We need to leave holes in the the abstractions. Different languages make filling those holes easy or difficult, but most languages do allow it in some form. In Haskell, we’ve seen a couple of ways:
- pass a named function
- create a new function from another by partially applying parameters
Today we’ll look at another way of passing in custom work without having to first name our function: lambdas. As mentioned earlier, lambdas are to functions as 5 is to int a = 5
. They are function literals. We’ll look at lambdas first in Ruby and then in Java 8. Next class we’ll see lambdas in Haskell as we continue our discussion of abstractions by looking at the fold/reduce pattern.
Code
fizzbuzz.hs
fizzbuzzOne :: Int -> Int -> Int -> String
-- fizzbuzzOne f1 f2 n
-- | n `mod` f1 == 0 && n `mod` f2 == 0 = "fizzbuzz"
-- | n `mod` f1 == 0 = "fizz"
-- | n `mod` f2 == 0 = "buzz"
-- | otherwise = show n
-- | n `mod` f1 /= 0 && n `mod` f2 /= 0 = show n
fizzbuzzOne f1 f2 n = case (mod n f1, mod n f2) of
(0, 0) -> "fizzbuzz"
(0, _) -> "fizz"
(_, 0) -> "buzz"
_ -> show n
fizzbuzzAll :: Int -> Int -> [Int] -> [String]
fizzbuzzAll f1 f2 = map (fizzbuzzOne f1 f2)
fizzbuzzAll35 = fizzbuzzAll 3 5
torus.c
/usr/lib/ruby/2.7.0/rubygems/dependency.rb:311:in `to_specs': Could not find 'coderay' (>= 0) among 56 total gem(s) (Gem::MissingSpecError) Checked in 'GEM_PATH=/.gem/ruby/2.7.0:/var/lib/gems/2.7.0:/usr/lib/ruby/gems/2.7.0:/usr/share/rubygems-integration/2.7.0:/usr/share/rubygems-integration/all:/usr/lib/x86_64-linux-gnu/rubygems-integration/2.7.0:/home/johnch/.gems', execute `gem env` for more information from /usr/lib/ruby/2.7.0/rubygems/dependency.rb:323:in `to_spec' from /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_gem.rb:62:in `gem' from ./coderay:24:in `'
map.rb
/usr/lib/ruby/2.7.0/rubygems/dependency.rb:311:in `to_specs': Could not find 'coderay' (>= 0) among 56 total gem(s) (Gem::MissingSpecError) Checked in 'GEM_PATH=/.gem/ruby/2.7.0:/var/lib/gems/2.7.0:/usr/lib/ruby/gems/2.7.0:/usr/share/rubygems-integration/2.7.0:/usr/share/rubygems-integration/all:/usr/lib/x86_64-linux-gnu/rubygems-integration/2.7.0:/home/johnch/.gems', execute `gem env` for more information from /usr/lib/ruby/2.7.0/rubygems/dependency.rb:323:in `to_spec' from /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_gem.rb:62:in `gem' from ./coderay:24:in `'