Last updated on
Callback: Find, with lazy evaluation
Introduction
Recall that in the first callback lab we were not able to refactor the
findFirstByNameAndPrint function, even though it is quite similar to the
other ones. But today, using lazy evaluation we will be able to generalize it
as well.
Step 1: Implement findLazy
Implement the findLazy function in find.scala.
This function takes two arguments:
- a root
cs214.Entryto search in, - a predicate function that takes an
cs214.Entryand returns aBoolean.
It should return a LazyList[Entry] containing all the entries satisfying the
predicate.
Be careful, until a particular result is requested, this function should not do any useless evaluation. For instance, given the following code, which prints all entry lazily, nothing gets printed immediately:
// Nothing is printed there
val entries = findLazy(entry, e => {println(e.name()); true})
But if we take the first element, then it will evaluate the head of the list, and hence, prints its name:
// This prints the first element's name
entries(0)
// This prints the second element's name
entries(1)
Also, this function should iterate through the tree lazily. Even if the tree happens to be infinite, it would still work.
Step 2: Rewrite the findFirstByNameAndPrint function
Rewrite findFirstByNameAndPrint using the findLazy function you just
implemented.
Step 3: Rewrite the findAndPrint function
Notice how the findLazy function is more versatile than the initial
findAndPrint. What’s interesting is that we have now split the control part
(how much should we iterate) from the iteration through the file tree itself.
This can be used to implement all sort of control flow, such as taking only the
first element, like you did in Step 2, or taking all elements, which is what
findAndPrint is doing. Therefore, you should now update findAndPrint using
findLazy. This will allow you to use the existing test suite to verify if
your implementation maintains its previous behavior.
Testing
This lab includes all the previous tests, plus a new suite in
FindLazyTest.scala, it can be relevant to have a look, if you are unsure
about how lazy your implementation should be.
You can run all suites as usual with:
$ sbt test
The tests in FindLazyTest.scala and FindTest.scala will be marked.
Once you are done with the lab, don’t forget to fill in the Moodle poll for that week!