Chapter 11: First-class functions: Part 2
Introduces the chapter’s planned practice with higher-order functions, copy-on-write, and logging improvements.
After this chapter you will be able to
- Expressing the hidden argument. Explain how to refactor an implicit argument into an explicit one: add a parameter, use it instead of the hard-coded value, and update callers.
- Replacing the body with callback. Describe how to extract shared before-and-after code into a function while passing the changing body as a callback.
- Copy-on-write callback pattern. Explain how replace body with callback applies to copy-on-write: making a copy is the before section, modifying it is the variable body, and returning it is the after section.
- Array copy-on-write refactoring. Trace how replace body with callback turns an array copy-on-write operation into withArrayCopy(): keep copying and returning in the shared function, and pass the modification as a callback.
- Logging function factory. Explain how wrapLogging() takes an existing function and returns a new function that runs it with standard error catching and logging, rather than requiring a try/catch at every call site.
- Judicious higher-order function use. Justify using a higher-order function when it reduces meaningful repetition, while comparing it with a straightforward solution for clarity.
What it builds on
- Code smell: Implicit argument in function name (chapter 10) · the earlier introduction of the implicit-argument code smell
- Refactoring: Express implicit argument (chapter 10) · the earlier treatment of expressing an implicit argument
- Refactoring: Replace body with callback (chapter 10) · the earlier treatment of replacing a body with a callback
- The three steps of the copy-on-write discipline (chapter 6) · Introduces the three steps of copy-on-write.
- These copy-on-write operations are generalizable (chapter 6) · Copy-on-write operations on arrays
Section by section
Introduction
Introduces the chapter’s planned practice with higher-order functions, copy-on-write, and logging improvements.
11.1 One code smell and two refactorings
This section recaps a code smell and two refactorings for turning hard-coded values and changing behavior into first-class arguments.
- Implicit argument code smell: Describe how to recognize an implicit argument in a function name: similar functions differ by a value used in their bodies, and their names indicate that difference.
Why it matters: Spotting the hidden value shows where similar functions may be combined. - Expressing the hidden argument: Explain how to refactor an implicit argument into an explicit one: add a parameter, use it instead of the hard-coded value, and update callers.
Why it matters: Passing the varying value directly can make intent clearer and remove repeated implementations. - Replacing the body with callback: Describe how to extract shared before-and-after code into a function while passing the changing body as a callback.
Why it matters: A callback lets one function reuse the surrounding structure while accepting different behavior.
Key terms: implicit argument in function name, first-class values, express implicit argument, explicit argument, first-class, replace body with callback, before, body, and after, higher-order functions
11.2 Refactoring copy-on-write
This section shows that replace body with callback can apply to the repeated steps of copy-on-write, not just repeated syntax.
- Copy-on-write callback pattern: Explain how replace body with callback applies to copy-on-write: making a copy is the before section, modifying it is the variable body, and returning it is the after section.
Why it matters: Recognizing the changing step lets you see how the same refactoring can address repeated copy-on-write code.
Key terms: replace body with callback, copy-on-write, before, body, after
11.3 Refactoring copy-on-write for arrays
The section refactors array copy-on-write operations into a reusable function that standardizes the discipline, accommodates new array operations, and can avoid intermediate copies.
- Array copy-on-write refactoring: Trace how replace body with callback turns an array copy-on-write operation into withArrayCopy(): keep copying and returning in the shared function, and pass the modification as a callback.
Why it matters: It shows how a callback can make the copy-on-write rule part of a reusable function. - Reusable array modification wrapper: Explain why withArrayCopy() can support a new array-modifying operation without a dedicated copy-on-write routine for that operation.
Why it matters: A new array operation can follow the existing copy-on-write rule without duplicating its implementation. - Single-copy modification sequences: Explain how withArrayCopy() offers an optimization for a sequence of array modifications and why that can help.
Why it matters: Avoiding intermediate copies can reduce the time and memory used by a sequence of changes.
Key terms: copy-on-write, replace body with callback, withArrayCopy(), modify, copy-on-write discipline, intermediate copies
11.4 Returning functions from functions
This section shows how returning a function can turn repeated error-handling code into a reusable function factory, and when that abstraction is worth using.
- Logging function factory: Explain how wrapLogging() takes an existing function and returns a new function that runs it with standard error catching and logging, rather than requiring a try/catch at every call site.
Why it matters: A function factory can apply one consistent behavior across many functions without repeating it at every call. - Returned function inputs and outputs: Describe how the generated function can pass arguments to the wrapped function and expose its return value.
Why it matters: A wrapper is more useful when callers can still supply the original inputs and receive its result. - Judicious higher-order function use: Justify using a higher-order function when it reduces meaningful repetition, while comparing it with a straightforward solution for clarity.
Why it matters: Removing duplication helps only if the resulting code remains clear enough for others to read.
Key terms: wrapLogging(), higher-order function, function factories, try/catch, Snap Errors®, inner function, return value, rest arguments, spread operator, higher-order functions
11.5 Conclusion
The conclusion links higher-order functions to the earlier distinction between actions, calculations, and data, and previews their exploration in later chapters.
11.6 Summary
11.7 Up next…
The section previews the next chapter’s exploration of functional array iteration, building on forEach().
Where this is used later
- Deriving map() from examples (chapter 12) · deriving an iteration tool by passing changing behavior into a function
- A summary of our use of higher-order functions (chapter 14) · The earlier refactoring of copy-on-write code.
Concepts explained in this chapter
- higher-order functionA function that accepts functions as arguments, returns functions as results, or otherwise treats functions as values.
- factoryA function factory is a function that creates and returns other functions, often with a shared behavior or configuration.
- replace body with callbackA refactoring technique that extracts unchanged before-and-after code into a function and supplies the varying body as a callback argument.
- copy-on-writeA data-management technique that creates a copy before modifying data so the original remains unchanged.
- code smellA code smell is a characteristic of source code that may indicate deeper design or maintenance problems.
- extract function argument refactoringA refactoring technique that converts information encoded implicitly in a function name or surrounding code into an explicit function argument.
- implicit argumentA code smell in which a function's name encodes a value that would more appropriately be supplied explicitly as an argument.
- functional, stateless philosophyA programming paradigm that emphasizes composing computations as evaluations of functions while minimizing mutable state and side effects.
These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.
