How to design a function. Using
natural recursion, higher-order functions, various modules and lazy
streams. When is the best time to use direct recursion vs. higher-order
functions?
It is generally not necessary to design a function that performs an
operation on every item in a collection (or filters items out of a
collection based on some criteria). Rather, design a function that
performs the operation (or the predicate) on a single item, then use a
higher-order function to apply this function to every element in a
collection.
Function properties. Metadata
(specifically module doc and doc strings), arity, etc. Recursion,
especially tail recursion vs. not and its impact on the amount of stack
space used by a program.
Data properties. The importance of persistent, immutable data and the implications for how we write functions.
Design methodology. Make your functions easier to understand by documenting the function contract @spec, descriptions, examples of use, and tests. You can leave out examples if the tests are nearby. The best option for testing functions is to create a separate test file using the test framework, but this won't be covered on this exam.
Important collection types: lists, maps, ranges, sets. These have a number of useful operations that work on all of them and other operations specific to each type, in the appropriate modules. Make sure you know how each of these operations works.
Impact of laziness. In functional programming, how can we replace various types of recursion with operations on lazy streams?
Functional programming. The idea of a pure vs. impure function (as in, if I show a function, can you id it as pure/impure?), the use of lazy streams and their functions, properties of functional code (such as referential transparency, reusability, composability).
Links to homework solutions: Daily assignments and HW1; HW2