Table of Contents
Why Functional ProgrammingKyle discusses why it's valuable to learn functional programming and how it enables developers to move from imperative to declarative programming.
Functional Programming JourneyKyle shares his journey towards learning functional programming, emphasizing, the incremental nature of learning to utilize functional strategies.
Code is ProvableKyle explains how and why provability is one of the major benefits of functional programming.
Course OverviewKyle gives an overview of the course. Topics include: function purity, closure, composition, immutability, recursion, lists/data structures, asynchronous programming, and functional programming libraries.
Functions vs ProceduresKyle explains the difference between functions and procedures, giving the requirements for a function keyword element to be a function as opposed to a procedure.
Function Naming SemanticsKyle demonstrates how functions in functional programming are named based on the semantics of the inputs and outputs of the function.
Side EffectsKyle explains why the causes of side effects are indirect inputs and outputs, and explains why they are unavoidable. Kyle also explains how they invalidate the properties of functional programming.
Pure Functions & ConstantsKyle continues to refine the definition of pure functions by explaining how constants reduce the purity of functions. Then, Kyle explains how their readability is also harmed by forcing the reader to understand the whole program as opposed to just one line.
Reducing Surface AreaKyle explains that you should reduce the surface area where constants can be set by passing them in close to where the functions are declared.
Same Input, Same OutputKyle analyzes why a function is only pure if it isolates the inputs and returns the outputs based on the inputs alone, and not based on anything defined outside the function.
Level of ConfidenceKyle analyzes the best way to evaluate the purity of a function, which is to look for areas where the programmer has high confidence, and ones where the programmer has low confidence.
Extracting ImpurityKyle discusses how to be obvious about side effects, and how to refactor for function purity by identifying and then extracting or containing it, either moving side effects to the outer shell or reducing their surface area.
Containing ImpurityKyle explains two ways to contain impurity: by using wrapper functions, an impure function wrapped around a pure function, or by using adapter functions, which capture a current state so the state can be restored later.
Impurity Exercise: Wrappers & AdaptersKyle instructs students to refactor functions in order to contain the existing impurity using wrapper functions and adapter functions.
Impurity Solution: WrappersKyle live codes the solution to the wrappers section of the exercise.
Impurity Solution: AdaptersKyle live codes the solution to the adapters section of the exercise.
Function ArgumentsKyle distinguishes between an argument and a parameter, explains what unary and binary functions are, and connects it all by explaining the idea of a function's shape.
Arguments Shape AdaptersKyle demonstrates how to change the arguments in a function to shape it, restricting an n-ary function into a unary function as an example.
Flip & Reverse AdapterKyle walks through a flip adapter function that flips the arguments passed into another function and gives advice regarding functional libraries like Lodash and Ramda.
Spread AdapterKyle discusses a common problem with arguments in functional programming where input elements are in an array instead of being individual arguments, and demonstrates how to use the apply function to spread them.
Equational ReasoningKyle describes how equational reasoning can be used to determine whether two functions have compatible shapes, and therefore whether they are interchangeable with each other.
Point Free RefactorKyle walks through the process of defining a function in terms of another function and then converting it to a point-free function, and explains how this can increase code readability.
Point Free ExerciseKyle instructs students to refactor three given functions to be point-free.
Point Free SolutionKyle live codes the solution to the exercise.
Advanced Point FreeKyle composes two functions into a function that uses currying and composition to demonstrate an advanced point free technique with equational reasoning.
ClosureKyle introduces closure, a function remembering its variables no matter where it is being called, as an essential concept to understand for functional programming. Kyle then discusses how to close over parameters to preserve the purity of a function.
Closure ExerciseKyle instructs students to practice closure by building a string builder utility that makes use of previously closed over variables.
Closure SolutionKyle live codes the solution to the exercise.
Lazy vs Eager ExecutionKyle explains lazy and eager function execution by giving two code samples, one lazy and one eager, which differ based on when the work for each is done. The benefits and drawbacks of each are discussed.
MemoizationKyle introduces memoization, a technique that holds onto the results of a function to avoid doing the work more than once, and explains how this technique is related to functional purity.
Referential TransparencyKyle explains the final requirement for functional purity, referential transparency, which is when a function call can be replaced by its return value without affecting the rest of the program.
Generalized to SpecializedKyle discusses function specialization by demonstrating how to create function definitions and function parameter orders that are arranged from general to specific. Kyle explains why this adds readability.
Partial Application & CurryingKyle introduces two techniques for specializing functions, partial application, where inputs are preset in a series of calls to utilities, and currying, where a function is called with an input a specified number of times.
Partial Application & Currying ComparisonKyle compares partial application and currying, two techniques for function specialization, and explains the distinction between strict currying and loose currying.
Changing Function Shape with CurryKyle demonstrates how to use currying to pre-specify one of the inputs to a function in order to change its shape into something potentially more useful.
Composition IllustrationKyle introduces composition by defining abstraction as the creation of semantic boundaries. An analogy to a candy factory is used to illustrate the process of drawing these boundaries and applying composition in code.
Declarative Data FlowKyle continues using the analogy of the factory to explain what it means for composition to be a method of declarative data flow, with a series of inputs and outputs which flow through a system.
Piping vs CompositionKyle discusses what piping is and how it differs from composition, which evaluates from the left to the right as opposed to right to left, and explains its usefulness.
Piping & Composition ExerciseKyle instructs students to define their own general compose and pipe functions.
Piping & Composition SolutionKyle live codes the solution to the exercise.
AssociativityKyle explains how the associativity property of composition makes it more useful by enabling currying and partial application on compositions for specialization.
Composition with CurryingKyle discusses the reason why only unary functions are used in composition and then demonstrates how to use currying to create unary functions that can be composed together. Then, Kyle revisits point-free in the context of currying and composition.
ImmutabilityKyle introduces immutability by defining what it is and what it implies. Kyle then goes over the first of two kinds of immutability that will be focused on throughout the section, assignment immutability.
Rethinking const ImmutabilityKyle discusses the common confusion with const, which is that the value is immutable, while the only thing that is actually immutable with the const keyword is the variable assignment. The readability of const is put into consideration as a result.
Value ImmutabilityKyle argues that the main case for immutability is value immutability, due to the probability that an error with mutability occurred because of a value change and not a reassignment.
Object.freezeKyle explains the benefits of using Object.freeze to achieve value immutability on an object and signal to the reader of the code that the object cannot be mutated.
Don't Mutate, CopyKyle recommends that, rather than mutating variables passed by reference, it is better to make a copy instead in case the variable was not originally meant to be mutated.
Immutable Data StructuresKyle highlights the strengths of immutable data structures, which mutate objects by making copies of the object instead of mutating the original reference while mitigating the practical cost.
Immutable.js OverviewKyle introduces immutable data structures as a useful tool for when an object needs to be mutated, and explains why this is the case.
Immutability ExerciseKyle instructs students to define pure functions dealing with data structures that are not meant to be changed when passed into a function.
Immutability SolutionKyle live codes the solution to the exercise.
RecursionKyle emphasizes the necessity for functional programmers to understand recursion and proceeds step by step creating a recursive program from an initially iterative problem.
Base Condition LocationKyle offers advice about optimizing recursive operations by changing the location of the base condition, checking to see if there is more work to be done before making the recursive call.
Recursion ExerciseKyle instructs students to define a palindrome checker using recursion.
Recursion SolutionKyle live codes the solution to the exercise.
Stack Frames & Memory LimitsKyle analyzes the practicality concerns of recursion, and explains how stack frames are created and memory limits are potentially surpassed when the computer processes recursive calls.
Refactoring to PTC FormKyle explains how to tell if something is not in proper tail call form and walks through how to refactor the return statement to be in proper form. Then, Kyle uses curry to store information in a closure to clean the refactored function signature.
TrampolinesKyle introduces trampolines, the second and recommended strategy for writing recursive algorithms that don't rely on tail calls. Kyle explains how trampolines allow the call data to be continually made and destroyed, and enables the programmer to write an easily refactorable tail-call function and wrap it in a trampoline.
Map: TransformationKyle introduces map, which takes a data structure and maps a transformation across each element, returning a new data structure of the same type with transformed values from the original structure.
Filter: InclusionKyle discusses the filter method, mentioning that filter is an inclusion operation, and not exclusion. Filter is recommended for when there is a collection where values are being kept in or left out of the result.
Reduce: CombinationKyle defines reduce as a combination operation, starting with an initial value and generating a resulting discrete value from operating on the elements of the collection using a binary reducer function.
Composition with ReduceKyle proves that reduction can be achieved using composition with the reduceRight function and displays an example.
List Operations ExerciseKyle instructs students to practice using list operations by writing three versions of an adding function that take in a list of functions to evaluate.
List Operations Solution: add & constantKyle live codes the first part of the exercise solution, two fixed number functions and two add functions.
List Operations Solution: addnKyle live codes three versions of an addn utility for the exercise solution: iterative, recursive, and reduced.
List Operations Solution: Modify CollectionKyle live codes the part of the solution that uses list operations to modify a collection of numbers in an array.
FusionKyle discusses fusion, a common situation in functional programming where functional methods are chained, and the practical ramifications of chaining in performance and readability. Kyle demonstrates an instance of fusion using map and compose.
TransductionKyle introduces transduction as a way to use a mathematical process to reshape map and filter into reducers so that map, filter, and reduce can all be used in conjunction. The transduce and into functions are covered.
Transduction Q&AKyle fields student questions about whether to use the into helper for multiplication, whether to use transduce for sorting, and whether transduce can be classified as a higher-order reducer.
Deriving Transduction: Extracting ReduceKyle begins to derive transduction step by step by performing map and filter using reduce, and eventually extracting reduce from the inside of these two functions and instead using reduce on functions that return a reducer.
Deriving Transduction: Combiner & CurryingKyle creates a combiner to use in the two reducer functions and extracts the combiner with currying to increase the specificity of both the map and filter reducer functions.
Deriving Transduction: Single ReduceKyle completes the derivation by composing the map and filter reductions, and then turning the remaining two reducers into one by passing sum into the transducer.
Derivation Summary and Q&AKyle summarizes the process of deriving transduction, and then fields questions about initial values to reduce, the situation where only map and filter are being used, and how transduction relates to Rx.js.
Data Structure Operations
Data Structure OperationsKyle emphasizes the importance of being able to generalize functional methods to use across any collection or data structure, such as objects and binary trees.
Object Filter & Reduce ExerciseKyle instructs students to implement filter and reduce methods for objects.
Object Filter & Reduce SolutionKyle live codes the solution to the exercise.
Advanced Point Free ExerciseKyle instructs students to refactor code from the previous exercise using advanced point-free techniques.
Advanced Point Free SolutionKyle live codes the solution to the exercise.
Monad Data StructuresKyle introduces monads, data structures which are wrappers around values which turn the value into a functor, or something that can be interacted with. As an example, Kyle describes the Just monad and its three methods map, chain, and ap.
Just MonadKyle creates a Just monad and a mapping of the monad. Then, Kyle walks through calling map and ap functions on the two created monads, explaining what is occurring at each step.
Maybe MonadKyle discusses the Maybe monad by walking through code that uses chaining and explains how monads can be useful in performing common programming tasks functionally.
Monads Q&AKyle fields questions about getting the value out of a monad, how monads are related to math, monad terminology, and how monads are related to category theory.
Map Lazy & Lazy ArrayKyle analyzes how lazy mapping functions and lazy arrays would work, and how functional principles could be adapted to asynchronous programming - turning synchronous and eager operations into asynchronous and lazy operations.
ObservablesKyle defines observables and explains them as being analogous to a spreadsheet involving a lazy, asynchronous flow of data.
Reactive Programming with Rx.jsKyle introduces Rx.js, a library for observables, or time-oriented data structures that allow for achieving functional concepts.
Async with Rx.js ExerciseKyle instructs students to wire up an observable to create a countdown timer in the console.
Async with Rx.js SolutionKyle live codes the solution to the exercise.
Functional JS Utils
Lodash/FPKyle introduces Lodash/FP, a module of Lodash with functional methods and gives an example of using the Lodash/FP library.
RamdaKyle recommends the Ramda functional library for students who do not yet have a functional library preference and then gives an example of using the Ramda library.
FPOKyle introduces his FPO library, which is meant to be a similar library to Ramda with a different way of dealing with function signatures: by using a named arguments style.