📕
Dan Fitz's Notes
  • README
  • Ai
    • Supervised Machine Learning
      • Introduction To Machine Learning
      • Regression With Multiple Input Variables
      • Classification
  • Csharp
    • C Sharp Advanced
      • Generics
      • Delegates
      • Lambda Expressions
      • Events
    • C Sharp Fundamentals
      • Intro To C
      • Primitive Types And Expressions
      • Non Primitive Types
      • Control Flow
      • Arrays And Lists
      • Working With Dates
      • Working With Text
      • Working With Files
      • Debugging Applications
    • C Sharp Intermediate
      • Classes
      • Association Between Classes
      • Inheritance
      • Polymorphism
      • Interfaces
  • Java
    • Inheritance Data Structures Java
      • Inheritance Polymorphism Using Overriding And Access Modifiers
      • Abstract Classes And Debugging
      • File I O And Exceptions
      • Collections Maps And Regular Expressions
    • Intro To Java
      • Introduction To Java Classes And Eclipse
      • Unit Testing Arrays And Array Lists
      • Static Variables Methods And Polymorphism Using Overloading
  • Javascript
    • Algorithms Data Structures
      • Big O Notation
      • Analyzing Performance Of Arrays And Objects
      • Problem Solving Approach
      • Problem Solving Patterns
      • Recursion
      • Searching Algorithms
      • Bubble Selection And Insertion Sort
      • Merge Sort
      • Quick Sort
      • Radix Sort
      • Data Structures Introduction
      • Singly Linked Lists
      • Doubly Linked Lists
      • Stacks And Queues
      • Binary Search Trees
      • Tree Traversal
      • Binary Heaps
    • Complete Nodejs
      • Understanding Node.js
      • REST AP Is And Mongoose
      • API Authentication And Security
      • Node.js Module System
      • File System And Command Line Args
      • Debugging Node.js
      • Asynchronous Node.js
      • Web Servers
      • Accessing API From Browser
      • Application Deployment
      • Mongo DB And Promises
    • Complete React Native
      • Working With Content
      • Building Lists
      • Navigating Users Between Screens
      • State Management
      • Handling Screen Layout
      • Setting Up An App
      • More On Navigation
      • Advanced Statement Management With Context
      • Building A Custom Express API
      • In App Authentication
    • Epic React
      • React Fundamentals
      • React Hooks
      • Advanced React Hooks
      • Advanced React Patterns
      • React Performance
    • Fireship Firestore
      • Firestore Queries And Data Modeling Course
      • Model Relational Data In Firestore No SQL
    • Functional Light Javascript
      • Intro
      • Function Purity
      • Argument Adapters
      • Point Free
      • Closure
      • Composition
      • Immutability
      • Recursion
      • List Operations
      • Transduction
      • Data Structure Operations
      • Async
    • Js Weird Parts
      • Execution Contexts And Lexical Environments
      • Types And Operators
      • Objects And Functions
      • Object Oriented Java Script And Prototypal Inheritance
      • Defining Objects
    • Mastering Chrome Dev Tools
      • Introduction
      • Editing
      • Debugging
      • Networking
      • Auditing
      • Node.js Profiling
      • Performance Monitoring
      • Image Performance
      • Memory
    • React Complete Guide
      • What Is React
      • React Basics
      • Rendering Lists And Conditionals
      • Styling React Components
      • Debugging React Apps
      • Component Deep Dive
      • Building A React App
      • Reaching Out To The Web
      • Routing
    • React Testing
      • Intro To Jest Enzyme And TDD
      • Basic Testing
      • Redux Testing
      • Redux Thunk Testing
    • Serverless Bootcamp
      • Introduction
      • Auction Service Setup
      • Auction Service CRUD Operations
      • Auction Service Processing Auctions
    • Testing Javascript
      • Fundamentals Of Testing
      • Static Analysis Testing
      • Mocking Fundamentals
      • Configuring Jest
      • Test React Components With Jest And React Testing Library
    • Typescript Developers Guide
      • Getting Started With Type Script
      • What Is A Type System
      • Type Annotations In Action
      • Annotations With Functions And Objects
      • Mastering Typed Arrays
      • Tuples In Type Script
      • The All Important Interface
      • Building Functionality With Classes
    • Web Performance With Webpack
      • Intro
      • Code Splitting
      • Module Methods Magic Comments
  • Other
    • Algo Expert
      • Defining Data Structures And Complexity Analysis
      • Memory
      • Big O Notation
      • Logarithm
      • Arrays
      • Linked Lists
      • Hash Tables
      • Stacks And Queues
      • Strings
      • Graphs
      • Trees
    • Aws Solutions Architect
      • AWS Fundamentals IAM EC 2
    • Fundamentals Math
      • Numbers And Negative Numbers
      • Factors And Multiples
      • Fractions
    • Mysql Bootcamp
      • Overview And Installation
      • Creating Databases And Tables
      • Inserting Data
      • CRUD Commands
      • The World Of String Functions
      • Refining Our Selections
      • The Magic Of Aggregate Functions
    • Random Notes
      • Understanding React Hooks
  • Python
    • Data Analysis Using Python
      • Loading Querying And Filtering Data Using The Csv Module
      • Loading Querying Joining And Filtering Data Using Pandas
      • Summarizing And Visualizing Data
    • Intro To Python
      • Course Introduction Intro To Programming And The Python Language Variables Conditionals Jupyter Notebook And IDLE
      • Intro To Lists Loops And Functions
      • More With Lists Strings Tuples Sets And Py Charm
      • Dictionaries And Files
Powered by GitBook
On this page
  • Example of Composition
  • Declarative Data Flow
  • Piping vs. Composition
  • Associativity
  • Composition with Currying
  1. Javascript
  2. Functional Light Javascript

Composition

Example of Composition

It's common to store function return values into temp variables and then pass that into other functions.

// Calculating the shipping rate
var temp = increment(4);
temp = triple(temp);

const totalCost = basePrice + minus2(temp);

You may have manually performed composition if you refactored this code to remove the temp variables, instead passing your functions directly as arguments to other functions.

const totalCost = basePrice + minus2(triple(increment(4)));

We can improve this code even more though. We can abstract the calculation of the shipping rate into a shippingRate function.

function shippingRate(x) {
  return minus2(triple(increment(x)));
}

const totalCost = basePrice + shippingRate(4);

Pro tip: Abstraction is valuable because it creates a semantic boundary around your code. It allows you to reason about some section of your code independently of the rest.

Declarative Data Flow

In our example, suppose that we need to calculate different kinds of shipping rates: international, national, local, etc.

There is a pattern in each of these shipping rate calculations. They each take in an input and pass them into a bunch of composed functions. The functions themselves may change, but the act of composition remains the same.

So we can create a compose helper function to handle all the different shipping rates:

function composeThree(fn3, fn2, fn1) {
  return function composed(v) {
    return fn3(fn2(fn1(v)));
  };
}

const shippingRate = composeThree(minus2, triple, increment);
const intShippingRate = composeThree(plus5, quadruple, increment);

This act of composition is a form of declarative data flow. Your shipping rate functions get defined declaratively and point-free, and it's really easy to read that your inputs (the data) get passed from right to left in a series of functions found in composeThree.

As a metaphor, think of compose as a machine-making machine. It spits out as many factory lines as you want, each one taking inputs, running them through a series of functions, and spitting out outputs.

Piping vs. Composition

Compose is right to left. Pipe is left to right.

Here's an example of pipe and how it might look behind the scenes:

function pipeThree(fn1, fn2, fn3) {
  return function piped(v) {
    return fn3(fn2(fn1(v)));
  };
}

const shippingRate = pipeThree(increment, triple, minus2);

Pro tip: Compose might feel more unintuitive at first (probably because we read left to right), but it's actually a better way to approach functional programming.

Associativity

Associativity is a property of an operation where rearranging the parentheses in an expression does not change the result.

Composition is associative.

// These two forms of composition are identical
const f = composeTwo(composeTwo(minus2, triple), increment);
const g = composeTwo(minus2, composeTwo(triple, increment));

Why it matters: If composition is associative, it means we can perform currying and partial application alongside it!

In other words, you don't have to know all the functions that are going to participate in a composition upfront. You can curry the compose utility and use the result to compose it with whatever you want later.

Composition with Currying

The natural way to compose a series of functions is for them all to be unary. After all, it's easier to pass the output of one function into the input of another when the input expected is always unary.

So how can you compose functions that are not unary? You can curry them, turning them into unary functions.

// divBy and sum are both binary
divBy(2, triple(sum(3, 5))); // 12

// By currying divBy and sum become unary
divBy = curry(2, divBy);
sum = curry(2, sum);
const calc = compose(divBy(2), triple, sum(3));
calc(5); // 12
PreviousClosureNextImmutability

Last updated 3 years ago