Learning Functional Programming in Go
Lex Sheehan更新时间:2021-07-02 23:15:16
最新章节:An explanation and call to action封面
版权信息
Credits
About the Author
Acknowledgments
About the Reviewer
www.PacktPub.com
Why subscribe?
Customer Feedback
Preface
What this book covers
What you need for this book
Who this book is for
Conventions
Reader feedback
Customer support
Downloading the example code
Downloading the color images of this book
Errata
Piracy
Questions
Pure Functional Programming in Go
Motivation for using FP
Getting the source code
The directory structure of the source files
How to run our first Go application
Imperative versus declarative programming
Pure functions
Fibonacci sequence - a simple recursion and two performance improvements
Memoization
The difference between an anonymous function and a closure
FP using Go's concurrency constructs
Testing FP using test-driven development
A note about paths
How to run our tests
A journey from imperative programming to pure FP and enlightenment
Benchmark test for the imperative SumLoop function
Benchmark test for the SumRecursive function
A time of reckoning
A quick example of a function literal
Summary
Manipulating Collections
Iterating through a collection
Piping Bash commands
Functors
Functions that modify functions
A coding example of functions that modify functions
A visual example of functions that modify functions
Composition in Mindcraft
Tacit programming
Tacit programming with Unix pipes
Programming CMOS with Unix pipes
Tacit programming with FP
Non-TCO recursive example
TCO recursive example
The importance of recursion
Various intermediate and terminal functions
Reduce example
Intermediate functions
Common intermediate functions
Map Example
Terminal functions
Common terminal functions
Join example
GroupBy example
Reduce example
Predicates
Reflection
Combinator pattern
Map and filter
Contains
Iterating over a collection of cars
The empty interface
The Contains() method
If Go had generics
Map function
Testing our empty interface-based Map function
Itertools
Go channels used by the New function
Testing itertool's Map function
Testing iterators for element equality
Functional packages
Another time of reflection
Go is awesome
Go is awesome but
The cure
Gleam - distributed MapReduce for Golang
LuaJIT's FFI library
Unix pipe tools
Processing Gleam collections
Summary
Using High-Order Functions
Characteristics of FP
Function composition
Monads allow us to chain continuations
Generics
First-class functions
Closure
Dynamically scoped
Pure function
Immuable Data
Persistent data structures for Go
Use of expressions
Sample HOF application
The chapter4 application code
Build and runtime instructions
More application code
The Filter function
Reality check
FilterFunc
Filter function
RESTful resources
Chaining functions
More cars
Reality check
The Map function
Improved performance from the Map function
The Reduce function
More high-order functions
Generators
RESTful server
The GenerateCars function
Currying Goroutine
A closer look at currying
Extending our currying example
Using a WaitGroup variable to manage concurrency
Finishing up the GenerateCars function
Handling concurrency
The final HOF example
Summary
SOLID Design in Go
Why many Gophers eschew Java
More reasons for eschewing Java
Digging deeper into error handling
Software design methodology
Good design
Bad design
Good versus bad design over time
SOLID design principles
Single responsibility principle
Function composition
Open/closed principle
Open / close principle in functional programming
FantasyLand JavaScript specification
Setoid algebra
Ord algebra
The expression problem
Liskov substitution principle
This OOP method stinks
Our FP function smells like roses
In FP contracts don't lie
Duck typing
What can go wrong with inheritance?
Interface segregation principle
Dependency inversion principle
The big reveal
MapReduce
MapReduce example
What else can Monads do?
Viva La Duck
Pass by value or reference?
Type embedding with Go interfaces
Interface embedding to add minor features
A Go error handling idiom
It's time to run our program
Summary
Adding Functionality with Decoration
Interface composition
Go's complimentary Reader and Writer interfaces
Example usages of the Reader and Writer interfaces
Design with Duck Typing
More reasons to design using interfaces
Using the Reader and Writer interfaces
Decorator pattern
Type hierarchy UML
How Procedural design compares to functional Inversion of Control (IoC)
Procedural design example
Functional IoC example
A decorator implementation
The main.go file
The decorator/simple_log.go file
Example InitLog calls
Back to our main package
Understanding our statistics using the easy-metrics GUI
Quick look at the Dot Init update
Easy-metrics - 1 of 3
The decorator/decorator.go file
A framework to inject dependencies
Wrapping a client request with decorators (in main)
Authorization decorator
Logging decorator
LoadBalancing decorator
Strategy pattern
Inversion of control and dependency injection
Our first failure
Easy metrics - 2 of 3
Groking our trace log file
The rest of the graph
Easy metrics - 3 of 3
Examining the trace log
The decorator/requestor.go file
The job variable declared in main()
Back to the requestor.go file
Using channels to manage the life cycle
All requests done
Launching our makeRequest goroutine
Our DI framework in action
Summary
Applying FP at the Architectural Level
Application architectures
What is software architecture?
Client-server architecture
Cloud architecture
Why does architecture matter?
The role of systems engineering
Real systems
IT system specialty groups
Systems engineering is lean
Requirements scope and terms
Defining terms
Software requirements
System
System architecture
System elements
System Boundaries
Managing Complexity
The best tool for the job
Divide and conquer
Designing for state management
Add a microservice
FP influenced architectures
Domain Driven Design
Dependency rule
Cyclic dependency
Working code
Code with cyclic dependency error
The Golang difference
Solution for cyclic dependencies
Domain Driven Design
Interface-driven development
Hollywood principle
Observer pattern
Dependency injection
A cloud bucket application
Directory structure
main.go
func HandlePanic
Dependency injection
func main()
Layers in the architecture
Domain layer
Use cases layer
Compatible interfaces
Interfaces layer
Why global variables are bad
Format the response
Testing our interfaces
Infrastructure layer
Context object
Benefits of DDD
Adaptability
Sustainability
Testability
Comprehensibility
A solid architectural foundation
FP and Micyoservices
Message passing
All parties must participate
Communication across boundaries
Polyglot Persistence
Lambda architecture
Speed
Batch
Servicing
Next generation big data architecture
CQRS
Benefits of CQRS
Infrastructure architecture
Share nothing architecture
Integrating services
Agreed upon protocol
Circuit breakers
Functional reactive architecture
Go is ideal for building microservices
Size matters
Benefits of gRPC
Who is using Go?
Summary
Functional Parameters
Refactoring long parameter lists
What's wrong with a function signature with more than seven parameters?
Refactoring - the book
Edsger W. Dijkstra says OOP is a bad idea
What else did Edsger W. Dijkstra say?
The underlying OOP problem
OOP inconsistency
Functional programming and cloud computing
A closer look at f(x)
A closer look at refactoring
Passing every parameter a function requires to do its job is not a good idea
Methods can query other objects' methods internally for data required to make decisions
Methods should depend on their host class for needed data
Pass a whole object with required attributes to reduce the number of required parameters
Replace parameter with method technique to reduce the number of required parameters
Before applying Replace Parameter with Method technique
After applying Replace Parameter with Method technique
Use a parameter object when we have unrelated data elements to pass
Long parameter lists will change over time and are inherently difficult to understand
The solution
Three ways to pass multiple parameters
Simply passing multiple parameters
Passing a configuration object/struct that contains multiple attributes
Partial application
Functional parameters
Contexts
Context limitations
Report example
Writing good code is not unlike a good game of soccer
Functional parameters - Rowe
Report example
A more practical Context use case
src/server/server.go
The src/server/server_options.go file
Summary
Increasing Performance Using Pipelining
Introducing the pipeline pattern
Grep sort example
Pipeline characteristics
Examples
Website order processing
Boss worker pattern
Load balancer
Data flow types
Building blocks
Generalized business application design
Example implementations
Imperative implementation
Decrypt authenticate charge flow diagram
Concurrent implementation
Buffered implementation
Leverage all CPU cores
Improved implementation
Imports
BuildPipeline
Immediately executable Goroutine
Receive order
Filterer interface
A Filterer object
Authenticate filter
Decrypt filter
Complete processing
The ChargeCard helper function
Charge filter
The encrypt and decrypt helper functions
Testing how the application handles invalid data
Invalid credit card cipher text
Invalid password
Changing the order of authenticate and decrypt filters
Attempting to charge before decrypting credit card number and authentication
Attempting to charge before authentication
Further reading
Summary
Functors Monoids and Generics
Understanding functors
An imperative versus pure FP example
What did that Map function do for us?
What possible benefits can this afford us?
A magical structure
Color blocks functor
Fingers times 10 functor
Definition of a functor in Haskell
Kinds of types
Maybe
Polymorphism at a higher level
No Generics results in a lot of boilerplate code
Solve lack of generics with metaprogramming
Generics code generation tool
The clipperhouse/gen tool
If Go supported generics
Adding new methods
Defining a filter function
Nums revisited
The slice typewriter
Aggregate[T]
Generics implementation options
We used the gen tool
The shape of a functor
Functor implementation
ints functor
Functor definition
Identity operation
Composition operation
Composition example in Go
Haskell version of compose
(g.f)(x) = g(f(x)) composition in Go
The (g.f)(x) = g(f(x)) implementation
A note about composition naming conventions in Go
The directions of the arrows are significant
EmphasizeHumanize ordered incorrectly
Function composition is associative
Functional composition in the context of a legal obligation
Decisions determine state transitions
Category theory review
Categorical rules
Results oriented
The forgetful functor and the law
The rule of law
Lucy’s forgetful functor
Larry’s forgetful functor
Build a 12-hour clock functor
Clock functor helpers
The Unit function
The AmPmMapper function
The AmHoursFn helper
The String helper function
main.go
Terminal output log
Functor summary
The car functor
The functor package
main.go
Compare one line of FP to a bunch of imperative lines
Car functor terminal session
Monoids
Monoid rules
Closure rule
Closure rule examples
Closure axiom
Associativity rule
Identity rule
Identity rule examples
An identity of 0
Writing a reduction function
A semigroup is a missing neutral value
Converting binary operations into operations that work on lists
Using monoids with divide and conquer algorithms
Referential transparency
Handling no data
More examples of monoids
What are not monoids?
Monoid examples
Name monoid
Name monoid terminal session
Int slice monoid
Lineitem slice monoid
Int slice monoid terminal session
Summary
Monads Type Classes and Generics
Mother Teresa Monad
The bind operation
The lift operation
Monadic functions
Basic monadic functions
Monadic list functions
Monadic workflow implementation
Lambda calculus
Y-Combinator
The Y in Y-Combinator
How the Y-Combinator works
The Lexical Workflow solution
Is our ProcessCar method idomatic Go code?
The non idiomatic parts
The idiomatic parts
An alternative workflow option
Business use case scenarios
Y-Combinator re-examined
What is tail recursion?
Big-Oh notation
InternationalizatioN (I18N) package
Type classes
Base class definitions
Int base class
String base class
Our main.go file
Sum parent type class
Sum base classes
Generics revisited
Impact of Golang
Personal opinion
Summary
Where to go from here
Category Theory That Applies
Our goal
Break it down
Algebra and the unknown
Real-world application of algebra
Linear equation and the law of demand
Quadratic equations all around us
Function composition with linear and quadratic functions
More examples of quadratic equations
The golden ratio
Basic laws of algebra
Correspondence in mathematics
Proof theory
Logical connectives
Logical inconsistency
Partial function
Truth table
Conditional propositions
Logical equivalence
Converse of a conditional proposition
Order matters
The Curry Howard isomorphism
Examples of propositions
Not propositions
Lambda calculus
Why so formal?
The importance of protocol
Historical Events in Functional Programming
George Boole (1815 - 1864)
Augustus De Morgan (1806 - 1871)
Friedrich Ludwig Gottlob Frege (1848 – 1925)
Modus Ponens
Charles Lutwidge Dodgson (1832 –1898)
Alfred Whitehead and Bertrand Russell (1903)
Moses Schonfinkel (1889–1942)
Haskell Curry - 1927
Gerhard Gentzen (1936)
Alonzo Church (1930 1940)
Alan Turing (1950)
MacLane and Eilenberg (1945)
John McCarthy (1950)
Curry-Howard-Lambek Correspondence (1969)
Roger Godement (1958)
Moggi Wadler Jones (1991)
Gibbons Oliveira (2006)
The history of FP in a nutshell
Where to go from here
Programming language categories
A declarative example
An imperative example
An OOP example
Venn diagram of four programming paradigms
Five generations of languages
The Forth language
The LINQ language
Type systems
The Lambda Calculus
Lambda Expressions
Anonymous function example and type inference
Lambda expression ingredients
Visualizing a lambda expression
A Lambda calculus is like chocolate milk
Lambda examples in other languages
JavaScript
JavaScript (ES6)
Ruby
The importance of Type systems to FP
Static versus dynamic typing
Type inference
Haskell
Type classes in Haskell
Domains codomains and morphisms
Set theory symbols
Category theory
Algebra of functions
Abstract functions
Official definition of a function
Intuitive definition of a function
Function composition with sets
Composition operation example using travel expenses
A Category
Category axioms
Category laws
More rules
More examples
Invalid categories
Morphisms
The behaviors of morphisms
Composition operation
Identity operation
Law of associativity
Only concerned with morphisms
Interface-driven development
More morphisms
A review of Category theory
Even more correspondence
Table of morphisms
Morphism examples
Modens ponens
Type theory version
Logic version
Correspondence between logic and type theory
Cartesian closed category
Unit type
Homomorphism
Homomorphisms preserve correspondence
Homomorphic encryption
An example of homomorphic encryption
Lesson learned
Isomorphism
Injective morphism
Surjective morphism
Endomorphism
SemiGroup homomorphism
SemiGroup Homomorphism Algebra
Homomorphism table
Car crash analogy
Composable concurrency
Finite state machines
Graph Database Example
Using mathematics and category theory to gain understanding
Laws of exponentials for building a lambda expression
Table legend
For the top right law...
Sums and products
Isomorphic equations
Fun with Sums Products Exponents and Types
Big data knowledge-driven development and data visualization
Data visualization
Summary
Miscellaneous Information and How-Tos
How to build and run Go projects
TL;DR
Development workflow
Dot init features and benefits
Aliases available
Functions available
Motivation for using goenv
Motivation for using the init script
Ways to manage Go dependencies
The go get tool
The Godep tool
Vendoring in Go
Glide - the modern package manager
Each dot init step in detail
The cd command to project root directory
Using homebrew to install Go
Examining the initial directory structure and files
The init script contents
Running the init script
Re-examining the initial directory structure and files
The goenv shows what's been updated
Running glide-update to get third-party dependency files
Adding standard library imports
The Go standard library
Adding third-party imports
Importing statement referencing go_utils
Development workflow summary
Troubleshooting dot init
A note about Go Dependency Management
A conversation - Java developer idiomatic Go developer FP developer
How to propose changes to Go
The first step - search specs
Second step - Google search
The official Golang change proposal process
Search for existing issues
Reading existing proposals
Adding a comment to the existing TCO proposal
Creating a new proposal
Creating a design document
Sending an email to notify the golang-dev group
An example proposal
Monitoring a proposal until the resolution is reached
FP resources
Minggatu - Catalan number
An explanation and call to action
更新时间:2021-07-02 23:15:16