41,99 €
Function literals, Monads, Lazy evaluation, Currying, and more
This book is for Golang developers comfortable with OOP and interested in learning how to apply the functional paradigm to create robust and testable apps. Prior programming experience with Go would be helpful, but not mandatory.
Functional programming is a popular programming paradigm that is used to simplify many tasks and will help you write flexible and succinct code. It allows you to decompose your programs into smaller, highly reusable components, without applying conceptual restraints on how the software should be modularized.
This book bridges the language gap for Golang developers by showing you how to create and consume functional constructs in Golang.
The book is divided into four modules. The first module explains the functional style of programming; pure functional programming (FP), manipulating collections, and using high-order functions. In the second module, you will learn design patterns that you can use to build FP-style applications. In the next module, you will learn FP techniques that you can use to improve your API signatures, to increase performance, and to build better Cloud-native applications. The last module delves into the underpinnings of FP with an introduction to category theory for software developers to give you a real understanding of what pure functional programming is all about, along with applicable code examples.
By the end of the book, you will be adept at building applications the functional way.
This book takes a pragmatic approach and shows you techniques to write better functional constructs in Golang. We'll also show you how use these concepts to build robust and testable apps.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 628
Veröffentlichungsjahr: 2017
BIRMINGHAM - MUMBAI
Copyright © 2017 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: November 2017
Production reference: 1221117
ISBN 978-1-78728-139-4
www.packtpub.com
Author
Lex Sheehan
Copy Editor
Pranjali Chury
Reviewer
John Pradeep
Project Coordinator
Vaidehi Sawant
Commissioning Editor
Merint Mathew
Proofreader
Safis Editing
Acquisition Editor
Karan Sadawana
Indexer
Rekha Nair
Content Development Editor
Rohit Kumar Singh
Graphics
Jason Monteiro
Technical Editor
Pavan Ramchandani
Production Coordinator
Shraddha Falebhai
Lex Sheehan has a B.S. in Computer Science from Auburn University, resides in Atlanta, GA, and works as a senior software engineer with over 20 years of experience. He has a deep understanding of functional programming; His first encounter was using high-order functions in Ruby, Scala, JavaScript, Haskell, Java, and Go.
Lex worked for IBM Software Group and IBM Global Business Services, designing and building various enterprise business systems. He is the author of eight US patents (IT security and data transformations) and he writes a blog titled Application Development with Lex Sheehan.
Lex is available to consult and meet with your CTO, or provide in-house training on the information in this book.
I would like to acknowledge the people who helped me during the writing of this book.
Thank you, Rohit, for editing my writing and providing your insight, guidance, and words of encouragement.
Thank you, John and Wayne, for reviewing this book for technical accuracy. Thank you to all other reviewers who helped improve the quality of this book's content.
Thank you, Mac, for being my wise counsel.
Thank you, Marty, for being my sounding board.
Thank you, Erik, for providing legal counsel regarding the Forgetful Functor.
Thank you all who lifted me up in your prayers during this endeavor.
Thank you, Salim, for your support. Your leadership style has earned my trust and loyalty.
Thank you, to the one who would say, "Lex Brilliance". That was and still is a great source of inspiration. Words matter.
We are all given talents. Some fear failure and suffer for it; others invest their talents.
This book is dedicated to those who invest in themselves and go on to help others.
John Pradeep is a software engineer with over 10 years of experience in designing and developing various applications in an agile way.
After working on multiple languages (Lisp being his favorite), he has recently started using Go for its clear set of design goals and simplicity. Now, Go has become his language of choice for most projects that he works on.
He loves finding simple solutions to complex problems, and he is also a huge fan of methodologies that help build elegant systems such as functional programming, domain-driven design, CQRS, reactive architectures, and so on.
For support files and downloads related to your book, please visit www.PacktPub.com.
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.
https://www.packtpub.com/mapt
Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career.
Fully searchable across every book published by Packt
Copy and paste, print, and bookmark content
On demand and accessible via a web browser
Thanks for purchasing this Packt book. At Packt, quality is at the heart of our editorial process. To help us improve, please leave us an honest review on this book's Amazon page at https://www.amazon.com/dp/1787281396.
If you'd like to join our team of regular reviewers, you can e-mail us at [email protected]. We award our regular reviewers with free eBooks and videos in exchange for their valuable feedback. Help us be relentless in improving our products!
Until recently, the message has been Go and functional programming—don't do it.
Functional programming (FP) is a perfect fit for multicore, parallel processing. Go is a concurrency baller (with Goroutines, channels, and so on) and already runs on every available CPU core. FP reduces complexity; simplicity is one of Go's biggest strengths.
So, what can FP bring to Go that will actually improve our software applications? Here's what it offers:
Composition
: FP shows us how to decompose our apps and rebuild them by reusing small building blocks.
Monads
: Using monads, we are able to safely order our workflows into pipelines of data transformations.
Error handling
: We can leverage monadic error handling and still maintain compatibility with idiomatic Go code.
Performance
: Referential transparency is where we can evaluate our function once and then subsequently refer to its pre-computed value.
Expressive code
: FP allows us to concisely express business intent in our code. We declare what our functions do, without the clutter of error checking after every function call, and without having to follow state changes (pure FP means immutable variables).
Simpler code
: No shared data means not having to deal with semaphores, locks, race conditions, or deadlocks.
Most people have difficulty grasping FP.
I did too. And when I got it, I wrote this book. Take this journey with me. We'll see hundreds of illustrations, read easy-to-understand explanations, and implement FP in Go code along the way.
I enjoyed coaching soccer. The litmus test I used to determine whether I succeeded as a coach was the answer to this simple question: Did they all register for next season and request me to be their coach? Just like planning practice, I planned each chapter, starting with simple concepts and adding to them. Read this book, then you too will be able to say, I got it.
If you want to improve your FP skills, this book is for you.
If you want to run the Go projects discussed in each chapter, you need to install Go. Next, you need to get your Go development environment running and start writing code.
Read the TL;DR subsection of the How to build and run Go projects section of the Appendix. Go to Chapter 1, Pure Functional Programming in Go in the book and start reading the Getting the source code section. Continue reading on how to set up and run your first project.
Other Go resources include:
Tour of Go (
https://tour.golang.org/welcome/1
)
Go by Example (
https://gobyexample.com/
)
Learning Go book (
https://www.miek.nl/go/
)
Go language specification (
https://golang.org/ref/spec
)
A lot of the information in this book requires only a high school education.
For the programming sections in this book, you should have at least one year programming experience. Proficiency with Go or Haskell is ideal, but experience with other languages such as C/C++, Python, Javascript, Java, Scala or Ruby is also sufficient. You should have some familiarity using the command line.
This book should appeal to two groups:
Non-programmers (read
Chapter 11
,
Category Theory That Applies
) If you are one of these:
K-12 math teacher and want to see why what you are teaching matters
Math teacher and want to see how what you are teaching relates to other branches of mathematics
Student in law school and want to understand what you will be doing when you plead your client’s case
Soccer enthusiast and like math
Person interested in learning category theory
Lover of the Lambda Calculus and want to see it illustrated with diagrams, pictures, and Go code
Manager of software projects and want to see a better correspondence between requirement gathering, implementation, and testing
C-level executive and want to understand what motivates and excites your IT staff
Programmers: If you are one of these:
Software enthusiast and want to learn Functional Programming
Software tester and want to see a better correspondence between requirement gathering, implementation, and testing
Software architect and want to understand how to use FP
Go developer and like soccer
Go developer and want to implement your business use case programming tasks with more expressive code
Go developer and want to understand Generics
Java developer and would like to understand why we say,
l
ess is more
Your_language_here
developer who knows FP and wants to transfer your skills to Go
Go developer looking for a better way to build data transformation pipelines
Go developer and would like to see a viable way to write less code, that is, fewer if
err != nil
blocks
Experienced Go developer and want to learn FP or add some tools to your toolbox
Person involved in software development and want to understand any of the terms below.
If you are a Go developer looking for working code, with line-by-line explanations for any of the following, this book is for you:
Benchmark testing
Concurrency (Goroutines/Channels)
Currying
Data transformation pipeline
Decorator Pattern
Dependency Injection
Duck typing
Embedding Interfaces
Error handler
Function composition
Funcitonal parameters
Functors
Generics via code generation
Hollywood Principle
Interface-driven development
I18N (language translation)
IoC
Lambda expressions in Go
Layered application framework
Log handler
Monads
Monoids
Observer Pattern
Partial application
Pipeline to process credit card payments
Recursion
Reduce function to sum invoice totals
Solve circular dependency errors
Table-driven http API test framework
Type Class
Upload/download files to/from Google Cloud Buckets
Y-Combinator
In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning. Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: "We update code, run the glide-update and go-run commands, and repeat until done." A block of code is set as follows:
func newSlice(s []string) *Collection { return &Collection{INVALID_INT_VAL, s}}
When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:
[default] exten => s,1,Dial(Zap/1|30) exten => s,2,Voicemail(u100)
exten => s,102,Voicemail(b100)
exten => i,1,Voicemail(s0)
Any command-line input or output is written as follows:
go get --help
New terms and important words are shown in bold. Words that you see on the screen, for example, in menus or dialog boxes, appear in the text like this: "In order to download new modules, we will go toFiles|Settings|Project Name|Project Interpreter."
Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you. You can download the code files by following these steps:
Log in or register to our website using your e-mail address and password.
Hover the mouse pointer on the
SUPPORT
tab at the top.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box.
Select the book for which you're looking to download the code files.
Choose from the drop-down menu where you purchased this book from.
Click on
Code Download
.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR / 7-Zip for Windows
Zipeg / iZip / UnRarX for Mac
7-Zip / PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Learning-Functional-Programming-in-Go. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
We also provide you with a PDF file that has color images of the screenshots/diagrams used in this book. The color images will help you better understand the changes in the output. You can download this file from https://www.packtpub.com/sites/default/files/downloads/LearningFunctionalProgramminginGo_ColorImages.pdf.
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.
To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy. Please contact us at [email protected] with a link to the suspected pirated material. We appreciate your help in protecting our authors and our ability to bring you valuable content.
If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.
Do you love Go? If so, why? Could it be better? Can you write your code better today?
Yes! Because Go is simple yet powerful; Go does not make me wait; its compiler is fast and cross-platform; Go makes concurrent programming easy; Go also provides useful tooling, and it has a great development community. Perhaps. Yes, that's what this book is about: using the functional programming (FP) style of coding.
In this chapter, I will share the benefits of pure FP as well as its performance implications in Go by working through Fibonacci sequence code samples. Starting with a simple imperative implementation, you will explore functional implementations and learn some test-driven development and benchmark techniques along the way.
The goal of this chapter is to:
Become grounded in the theory of FP
Learn how to implement functional solutions
Determine what type of FP will best fit your business requirements
The FP style of programming can help you write less code in a more concise and expressive way, with fewer errors. How is that possible? Well, FP treats computation as an evaluation of mathematical functions. FP leverages this computational model (and the work of some brilliant mathematicians and logicians) to enable optimizations and performance gains that are simply not possible using traditional imperative coding techniques.
Developing software is not easy. You must handle numerous non-functional requirements (NFRs) first, such as:
Complexity
Extensibility
Maintainability
Reliability
Concurrency
Scalability
Software is becoming more and more complex. What is the average number of third-party dependencies in your typical application? What did that look like 5 years ago? Our applications often must integrate with other services within our own company and with our partners as well as external customers. How can we manage this growing complexity?
Applications used to run on-site on servers that were given pet names, such as Apollo, Gemini, and so on. It seems like every client would have a different naming scheme. Nowadays, most applications are deploying into a cloud environment, for example, AWS or the Google Cloud Platform. Do you have a lot of software applications that run on a lot of servers? If so, you should treat your servers more like cattle; there's just so many of them. Also, since you've got auto scaling, what's important is not a single server but the herd. As long as you always have at least one server in your cluster running for the accounting department, that's all that really matters.
With numbers comes complexity. Can you compose your applications to fit together like Lego blocks, and do you find it easy to write useful tests that run really fast. Alternatively, do you ever feel like there's too much scaffolding/for loops in your code? Do you like handling theerr != nilcondition so frequently? Would you like to see a simpler, cleaner way to do the same thing? Do your applications have any global variables? Do you have code in place to always properly manage its state and prevent all the possible side effects? Have race conditions ever been a problem?
Are you aware of all the possible error conditions in your applications, and do you have code in place to handle them? Can you look at the function signature of any function in your code and immediately have an intuition as to what it does?
Are you interested in learning about a better way to achieve your NFRs and enjoy developing Go software even more than you do right now? Looking for the silver bullet? If so, please continue reading. (Note that the rest of this book will be written in first person plural since we will be learning together.)
Directories correspond to the book's units and chapters:
Each chapter is divided into sequentially numbered directories that are in the order of their appearance in the book.
First, let's make sure we have Go installed, our GOPATH is properly set, and that we can run a Go application.
If you are using a macOS, then check out the instructions on how to use the brew command to install Go in the appendix; otherwise, to install Go, visit: http://golang.org/doc/install. To set your GOPATH, visit: https://github.com/golang/go/wiki/Setting-GOPATH.
Many people use a global GOPATH to store the source code for all their Go applications or, frequently, manually reset their GOPATH. I found this practice to be troublesome when working with multiple Go projects for multiple clients, each of which had differing Go versions and third-party dependencies.
The example Go applications that we'll use in this chapter do not have dependencies; that is, we don't have to import any third-party packages. So, all we have to do to run our first app--cars.go--is verify that Go is installed, set our GOPATH, and type go run cars.go:
Using a global GOPATH is easy for projects that are super simple, like the examples in this chapter.
In Chapter 2, Manipulating Collections, our Go applications will start getting more complex, and we'll get introduced to a simple, more consistent way to manage our Go development environments.
We can use this insanity principle to our advantage with pure functions.
Assigning values to variables during an imperative function's execution may result in the modification of a variable in the environment in which it has run. If we run the same imperative function again, using the same input, the result may differ.
Given the results of an imperative function and given the same input, different results may be returned each time it is run. Is that not insanity?
Pure functions:
Treat functions as first-class citizens
Always return the same result given the same input(s)
Have no side effects in the environment in which they run
Do not allow an external state to affect their results
Do not allow variable values to change over time
Two characteristics of a pure function include referential transparency and idempotence:
Referential transparency
: This is where a function call can be replaced with its corresponding value without changing the program's behavior
Idempotence
: This is where a function call can be called repeatedly and produce the same result each time
Referentially transparent programs are more easily optimized. Let's see whether we can perform optimizations using a caching technique and Go's concurrency features.
Let's look at a few simple code examples to understand the difference between an anonymous function and a closure.
Here's a typical named function:
func namedGreeting(name string) { fmt.Printf("Hey %s!n", name)}
The following is an example of the anonymous function:
func anonymousGreeting() func(string) { return func(name string) { fmt.Printf("Hey %s!n", name) }}
Now, let's call them both and call an anonymous inline function to say Hey to Cindy:
func main() { namedGreeting("Alice") greet := anonymousGreeting() greet("Bob") func(name string) { fmt.Printf("Hello %s!n", name) }("Cindy")}
The output will be as follows:
Hello Alice!Hello Bob!Hello Cindy!
Now, let's look at a closure named greeting and see the difference between it and the anonymousGreeting()
