Grokking simplicity taming complex software with functional thinking
"Developers rightly fear the unintended complexity that infects most code. This book shows you how to write software that keeps complexity close to its inherent minimum. As you write software you should distinguish between code that alters your system's state, and code that does not. Once...
Otros Autores: | , , |
---|---|
Formato: | Libro electrónico |
Idioma: | Inglés |
Publicado: |
Shelter Island, New York :
Manning Publications Company
[2021]
|
Edición: | [First edition] |
Materias: | |
Ver en Biblioteca Universitat Ramon Llull: | https://discovery.url.edu/permalink/34CSUC_URL/1im36ta/alma991009634719006719 |
Tabla de Contenidos:
- Intro
- Title Page
- Copyright
- Foreword
- Preface
- Acknowledgments
- About This Book
- About the Author
- Chapter 1: Welcome to Grokking Simplicity
- What is Functional Programming?
- The Problems with the Definition for Practical Use
- The Definition of FP Confuses Managers
- We Treat Functional Programming as a Set of Skills and Concepts
- Distinguishing Actions, Calculations, and Data
- Functional Programmers Distinguish Code That Matters When You Call It
- Functional Programmers Distinguish Inert Data From Code That Does Work
- Functional Programmers See Actions, Calculations, and Data
- The Three Categories of Code in FP
- How Does Distinguishing Actions, Calculations, and Data Help Us?
- Why is this Book Different from Other FP Books?
- What is Functional Thinking?
- Ground Rules for Ideas and Skills in this Book
- Chapter 2: Functional Thinking in Action
- Welcome to Toni's Pizza
- Part 1: Distinguishing Actions, Calculations, and Data
- Organizing Code by "Rate of Change"
- Part 2: First-Class Abstractions
- Timelines Visualize Distributed Systems
- Multiple Timelines Can Execute in Different Orderings
- Hard-won Lessons About Distributed Systems
- Cutting the Timeline: Making the Robots Wait for Each Other
- Positive Lessons Learned About Timelines
- Part 1: Actions, Calculations, and Data
- Chapter 3: Distinguishing Actions, Calculations, and Data
- Actions, Calculations, and Data
- Actions, Calculations, and Data Apply to Any Situation
- Lessons from Our Shopping Process
- Applying Functional Thinking to New Code
- Drawing the Coupon Email Process
- Implementing the Coupon Email Process
- Applying Functional Thinking to Existing Code
- Actions Spread Through Code
- Actions Can Take Many Forms
- Chapter 4: Extracting Calculations from Actions
- Welcome to MegaMart.com!.
- Calculating free Shipping
- Calculating Tax
- We Need to Make It More Testable
- We need to Make It More Reusable
- Distinguishing Actions, Calculations, and Data
- Functions Have Inputs and Outputs
- Testing and Reuse Relate to Inputs and Outputs
- Extracting a Calculation from An Action
- Extracting Another Calculation from an Action
- Let's See All of Our Code in One Place
- Chapter 5: Improving the Design of Actions
- Aligning Design with Business Requirements
- Aligning the Function with Business Requirements
- Principle: Minimize Implicit Inputs and Outputs
- Reducing Implicit Inputs and Outputs
- Giving the Code a Once-Over
- Categorizing Our Calculations
- Principle: Design Is About Pulling Things Apart
- Improving the Design by Pulling add_item() Apart
- Extracting a Copy-On-Write Pattern
- Using add_item()
- Categorizing Our Calculations
- Smaller Functions and More Calculations
- Chapter 6: Staying Immutable in a Mutable Language
- Can Immutability be Applied Everywhere?
- Categorizing Operations into Reads, Writes, or Both
- The Three Steps of the Copy-On-Write Discipline
- Converting a Write to a Read With Copy-On-Write
- Complete Diff from Mutating to Copy-On-Write
- These Copy-On-Write Operations are Generalizable
- JavaScript Arrays at a Glance
- What to do if an Operation is a Read and a Write
- Splitting a Function that does a Read and Write
- Returning Two Values from One Function
- Reads to Immutable Data Structures are Calculations
- Applications Have State That Changes Over Time
- Immutable Data Structures are Fast Enough
- Copy-On-Write Operations on Objects
- JavaScript Objects at a Glance
- Converting Nested Writes to Reads
- What Gets Copied?
- Visualizing Shallow Copies and Structural Sharing
- Chapter 7: Staying Immutable with Untrusted Code
- Immutability with Legacy Code.
- Our Copy-On-Write Code has to Interact with Untrusted Code
- Defensive Copying Defends the Immutable Original
- Implementing Defensive Copies
- The Rules of Defensive Copying
- Wrapping Untrusted Code
- Defensive Copying You May Be Familiar With
- Copy-On-Write and Defensive Copying Compared
- Deep Copies are More Expensive Than Shallow Copies
- Implementing Deep Copy in JavaScript is Difficult
- A Dialogue Between Copy-On-Write and Defensive Copying
- Chapter 8: Stratified Design: Part 1
- What is Software Design?
- What is Stratified Design?
- Developing Our Design Sense
- Patterns of Stratified Design
- Pattern 1: Straightforward Implementations
- Three Different Zoom Levels
- Extracting the for Loop
- Pattern 1 Review: Straightforward Implementation
- Chapter 9: Stratified Design: Part 2
- Patterns of Stratified Design
- Pattern 2: Abstraction Barrier
- Abstraction Barriers Hide Implementations
- Ignoring Details is Symmetrical
- Swapping the Shopping Cart's Data Structure
- Re-Implementing the Shopping Cart as an Object
- The Abstraction Barrier Lets Us Ignore Details
- When to Use (and When 'Not' to Use!) Abstraction Barriers
- Pattern 2 Review: Abstraction Barrier
- Our Code is More Straightforward
- Pattern 3: Minimal Interface
- Pattern 3 Review: Minimal Interface
- Pattern 4: Comfortable Layers
- Patterns of Stratified Design
- What Does the Graph Show Us About Our Code?
- Code at the Top of the Graph is Easier to Change
- Testing Code at the Bottom is More Important
- Code at the Bottom is More Reusable
- Summary: What the Graph Shows Us About Our Code
- Part 2: First-Class Abstractions
- Chapter 10: First-Class Functions: Part 1
- Marketing Still Needs to Coordinate with Dev
- Code Smell: Implicit Argument in Function Name
- Refactoring: Express Implicit Argument.
- Recognize What Is and What Isn't First-Class
- Will Field Names as Strings Lead to More Bugs?
- Will First-Class Fields Make the API Hard to Change?
- We Will Use a Lot of Objects and Arrays
- First-Class Functions Can Replace any Syntax
- For loop example: Eating and cleaning up
- Refactoring: Replace Body with Callback
- What is this Syntax?
- Why are we Wrapping the Code in a Function?
- Chapter 11: First-Class Functions: Part 2
- One Code Smell and Two Refactorings
- Refactoring Copy-On-Write
- Refactoring Copy-On-Write for Arrays
- Returning Functions from Functions
- Chapter 12: Functional Iteration
- One Code Smell and Two Refactorings
- MegaMart is Creating a Communications Team
- Deriving map() from Examples
- Functional Tool: map()
- Three Ways to Pass a Function
- Example: Email Addresses of All Customers
- Deriving filter() from Examples
- Functional Tool: filter()
- Example: Customers with Zero Purchases
- Deriving reduce() from Examples
- Functional Tool: reduce()
- Example: Concatenating Strings
- Things You Can Do With reduce()
- Three Functional Tools Compared
- Chapter 13: Chaining Functional Tools
- The Customer Communications Team Continues
- Clarifying Chains, Method 1: Name the Steps
- Clarifying Chains, Method 2: Naming the Callbacks
- Clarifying Chains: Two Methods Compared
- Example: Emails of Customers Who Have Made One Purchase
- Refactoring Existing for Loops to Functional Tools
- Tip 1: Make Data
- Tip 2: Operate on Whole Array at Once
- Tip 3: Take Many Small Steps
- Tip 3: Take Many Small Steps
- Comparing Functional to Imperative Code
- Summary of Chaining Tips
- Debugging Tips for Chaining
- Many Other Functional Tools
- reduce() for Building Values
- Getting Creative with Data Representation
- Line Up Those Dots
- Chapter 14: Functional Tools for Nested Data.
- Higher-Order Functions for Values in Objects
- Making the Field Name Explicit
- Deriving update()
- Using update() to Modify Values
- Refactoring: Replace Get, Modify, Set with update()
- Functional Tool: update()
- Visualizing Values in Objects
- Visualizing Nested Updates
- Applying update() to Nested Data
- Deriving updateOption()
- Deriving update2()
- Visualizing update2() on Nested Objects
- Writing incrementSizeByName() Four Ways
- Deriving update3()
- Deriving nestedUpdate()
- The Anatomy of Safe Recursion
- Visualizing nestedUpdate()
- The Superpower of Recursion
- Design Considerations with Deep Nesting
- Abstraction Barriers on Deeply Nested Data
- A Summary of Our Use of Higher-Order Functions
- Chapter 15: Isolating Timelines
- There's a Bug!
- Now We Can Try to Click Twice Fast
- The Timeline Diagram Shows What Happens Over Time
- The Two Fundamentals Of Timeline Diagrams
- Two Tricky Details About the Order of Actions
- Drawing the Add-to-Cart Timeline: Step 1
- Asynchronous Calls Require New Timelines
- Different Languages, Different Threading Models
- Building the Timeline Step-by-Step
- Drawing the Add-to-Cart Timeline: Step 2
- Timeline Diagrams Capture the Two Kinds of Sequential Code
- Timeline Diagrams Capture the Uncertain Ordering of Parallel Code
- Principles of Working with Timelines
- JavaScript's Single-Thread
- JavaScript's Asynchronous Queue
- AJAX and the Event Queue
- A complete asynchronous example
- Simplifying the Timeline
- Reading Our Finished Timeline
- Simplifying the Add-to-Cart Timeline Diagram: Step 3
- Review: Drawing the Timeline (Steps 1-3)
- Summary: Drawing Timeline Diagrams
- Timeline Diagrams Side-by-Side Can Reveal Problems
- Two Slow Clicks Get the Right Result
- Two Fast Clicks Can Get the Wrong Result
- Timelines That Share Resources Can Cause Problems.
- Converting a Global Variable to a Local One.