Download ebooks file Functional Light JavaScript Balanced Pragmatic FP in JavaScript 1st Edition Kyle Simpson all chapters
Download ebooks file Functional Light JavaScript Balanced Pragmatic FP in JavaScript 1st Edition Kyle Simpson all chapters
https://ebookfinal.com
https://ebookfinal.com/download/functional-light-
javascript-balanced-pragmatic-fp-in-
javascript-1st-edition-kyle-simpson/
https://ebookfinal.com/download/javascript-unlocked-1st-edition-
sheiko/
ebookfinal.com
https://ebookfinal.com/download/javascript-bible-danny-goodman/
ebookfinal.com
https://ebookfinal.com/download/javascript-creativity-1st-edition-
edition-hudson/
ebookfinal.com
https://ebookfinal.com/download/you-don-t-know-js-es6-beyond-kyle-
simpson/
ebookfinal.com
Learning JavaScript 2nd Edition Shelley Powers
https://ebookfinal.com/download/learning-javascript-2nd-edition-
shelley-powers/
ebookfinal.com
https://ebookfinal.com/download/test-driven-javascript-
development-1st-edition-christian-johansen/
ebookfinal.com
https://ebookfinal.com/download/pro-javascript-design-patterns-1st-
edition-ross-harmes/
ebookfinal.com
https://ebookfinal.com/download/javascript-essentials-for-dummies-1st-
edition-paul-mcfedries/
ebookfinal.com
Functional Light JavaScript Balanced Pragmatic FP in
JavaScript 1st Edition Kyle Simpson Digital Instant
Download
Author(s): Kyle Simpson, Brian MacDonald (editor)
ISBN(s): 9781981672349, 1981672346
Edition: 1
File Details: PDF, 3.00 MB
Year: 2018
Language: english
Functional-Light JavaScript
Balanced, Pragmatic FP in JavaScript
Kyle Simpson
This version was published on 2018-02-09
ISBN 9781617296512
DISTRIBUTED BY MANNING
This book was created solely by its Author and is being distributed by Manning
Publications “as is,” with no guarantee of completeness, accuracy, timeliness, or
other fitness for use. Neither Manning nor the Author make any warranty
regarding the results obtained from the use of the contents herein and accept no
liability for any decision or action taken in reliance on the information in this book
nor for any damages resulting from this work or its application.
Contents
Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii
Mission . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv
Functional-Light JavaScript
CONTENTS
Functional-Light JavaScript
CONTENTS
Functional-Light JavaScript
CONTENTS
Functional-Light JavaScript
Foreword i
Foreword
It’s no secret that I am a Functional Programming nut. I evangelize functional ideas
and languages wherever I can, try to read the latest academic papers, study abstract
algebra in my spare time…the works. Even in JavaScript, I refuse to write an impure
statement, which is what led to writing Professor Frisby’s Mostly Adequate Guide to
Functional Programming. Yep, full on, dogmatic zealot.
I was not always this way… I was once obsessed with objects. I loved modeling the
“real world”. I was the inventor of synthetic automatons, tinkering through the night
with masterful precision. The creator of sentient puppets, fingers dancing on the
keyboard to give them life – a real 1337 h4x0r Geppetto. Yet, after 5 solid years of
writing object-oriented code, I was never quite satisfied with the outcome. It just
never worked out well for me. I felt like a lousy programmer. I even lost faith that a
simple, flexible codebase of decent scale was possible.
I figured I’d try something different: Functional Programming. I began to dabble
with functional ideas in my everyday codebase, and much to my coworkers’ dismay,
hadn’t the slightest clue what I was doing. The code I wrote in those days was awful.
Atrocious. Digital sewage. The reason was a lack of clear vision or goal on what I
was even trying to accomplish. My Jiminy-Coding-Cricket, if you like, was not there
to guide me. It took a long time and a lot of garbage programs to figure out how to
FP.
Now, after all that messy exploration, I feel that pure Functional Programming has
delivered on its promise. Readable programs do exist! Reuse does exist! I no longer
invent, but rather discover my model. I’ve become a rogue detective uncovering
a vast conspiracy, cork board pinned full of mathematical evidence. A digital-age
Cousteau logging the characteristics of this bizarre land in the name of science! It’s
not perfect and I still have a lot to learn, but I’ve never been more satisfied in my
work and pleased with the outcome.
Had this book existed when I was starting out, my transition into the world of
Functional Programming would have been much easier and less destructive. This
Functional-Light JavaScript
Foreword ii
book is two-fold (right and left): it will not only teach you how to use various
constructs from FP effectively in your daily code, but more importantly, provide
you with an aim; guiding principles that will keep you on track.
You will learn Functional-Light: A paradigm that Kyle has pioneered to enable
declarative, Functional Programming while providing balance and interop with the
rest of the JavaScript world. You will understand the foundation which pure FP is
built upon without having to subscribe to the paradigm in its entirety. You will gain
the skills to practice and explore FP without having to rewrite existing code for it
to work well together. You can take a step forward in your software career without
backtracking and wandering aimlessly as I did years ago. Coworkers and colleagues
rejoice!
Kyle is a great teacher known for his relentless pursuit of the whole picture, leaving
no nook or cranny unexplored, yet he maintains an empathy for the learner’s plight.
His style has resonated with the industry, leveling us all up as a whole. His work
has a solid place in JavaScript’s history and most people’s bookmarks bar. You are in
good hands.
Functional Programming has many different definitions. A Lisp programmer’s
definition is vastly different from a Haskell perspective. OCaml’s FP bears little
resemblance to the paradigm seen in Erlang. You will even find several competing
definitions in JavaScript. Yet there is a tie that binds – some blurry know-it-when-
I-see-it definition, much like obscenity (indeed, some do find FP obscene!) and this
book certainly captures it. The end result might not be considered idiomatic in certain
circles, but the knowledge acquired here directly applies to any flavor of FP.
This book is a terrific place to begin your FP journey. Take it away, Kyle…
-Brian Lonsdorf (@drboolean)
Functional-Light JavaScript
Preface iii
Preface
A monad is just a monoid in the category of endofunctors.
Did I just lose you? Don’t worry, I’d be lost, too! All those terms that only
mean something to the already-initiated in Functional ProgrammingTM (FP) are just
jumbled nonsense to many of the rest of us.
This book is not going to teach you what those words mean. If that’s what you’re
looking for, keep looking. In fact, there are already plenty of great books that teach
FP the right way, from the top-down. Those words have important meanings and if
you formally study FP in-depth, you’ll absolutely want to get familiar with them.
But this book is going to approach the topic quite differently. I’m going to present
fundamental FP concepts from the ground-up, with fewer special or non-intuitive
terms than most approaches to FP. We’ll try to take a practical approach to each
principle rather than a purely academic angle. There will be terms, no doubt. But
we’ll be careful and deliberate about introducing them and explaining why they’re
important.
Sadly, I am not a card-carrying member of the FP Cool Kids Club. I’ve never been
formally taught anything about FP. And though I have a CS academic background
and I am decent at math, mathematical notation is not how my brain understands
programming. I have never written a line of Scheme, Clojure, or Haskell. I’m not an
old-school Lisp’r.
I have attended countless conference talks about FP, each one with the desperate
clinging hope that finally, this time would be the time I understood what this
whole functional programming mysticism is all about. And each time, I came away
frustrated and reminded that those terms got all mixed up in my head and I had no
idea if or what I learned. Maybe I learned things. But I couldn’t figure out what those
things were for the longest time.
Little by little, across those various exposures, I teased out bits and pieces of
important concepts that seem to just come all too naturally to the formal FPer.
Functional-Light JavaScript
Preface iv
I learned them slowly and I learned them pragmatically and experientially, not
academically with appropriate terminology. Have you ever known a thing for a long
time, and only later found out it had a specific name you never knew!?
Maybe you’re like me; I heard terms such as “map-reduce” around industry segments
like “big data” for years with no real idea what they were. Eventually I learned what
the map(..) function did – all long before I had any idea that list operations were a
cornerstone of the FPer path and what makes them so important. I knew what map
was long before I ever knew it was called map(..).
Eventually I began to gather all these tidbits of understanding into what I now call
“Functional-Light Programming” (FLP).
Mission
But why is it so important for you to learn functional programming, even the light
form?
I’ve come to believe something very deeply in recent years, so much so you could
almost call it a religious belief. I believe that programming is fundamentally about
humans, not about code. I believe that code is first and foremost a means of human
communication, and only as a side effect (hear my self-referential chuckle) does it
instruct the computer.
The way I see it, functional programming is at its heart about using patterns in your
code that are well-known, understandable, and proven to keep away the mistakes
that make code harder to understand. In that view, FP – or, ahem, FLP! – might be
one of the most important collections of tools any developer could acquire.
The curse of the monad is that… once you understand… you lose the
ability to explain it to anyone else.
Functional-Light JavaScript
Preface v
I hope this book “Maybe” breaks the spirit of that curse, even though we won’t talk
about “monads” until the very end in the appendices.
The formal FPer will often assert that the real value of FP is in using it essentially
100%: it’s an all-or-nothing proposition. The belief is that if you use FP in one part of
your program but not in another, the whole program is polluted by the non-FP stuff
and therefore suffers enough that the FP was probably not worth it.
I’ll say unequivocally: I think that absolutism is bogus. That’s as silly to me as
suggesting that this book is only good if I use perfect grammar and active voice
throughout; if I make any mistakes, it degrades the entire book’s quality. Nonsense.
The better I am at writing in a clear, consistent voice, the better your reading
experience will be. But I’m not a 100% perfect author. Some parts will be better
written than others. The parts where I can still improve are not going to invalidate
the other parts of this book which are useful.
And so it goes with our code. The more you can apply these principles to more parts
of your code, the better your code will be. Use them well 25% of the time, and you’ll
get some good benefit. Use them 80% of the time, and you’ll see even more benefit.
With perhaps a few exceptions, I don’t think you’ll find many absolutes in this text.
We’ll instead talk about aspirations, goals, principles to strive for. We’ll talk about
balance and pragmatism and trade-offs.
Welcome to this journey into the most useful and practical foundations of FP. We
both have plenty to learn!
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 1
Functional Programming (FP) is not a new concept by any means. It’s been around
almost the entire history of programming. However, and I’m not sure it’s fair to
say, but… it sure hasn’t seemed like as mainstream of a concept in the overall
developer world until perhaps the last few years. I think FP has more been the realm
of academics.
That’s all changing, though. A groundswell of interest is growing around FP, not just
at the languages level but even in libraries and frameworks. You very well might be
reading this text because you’ve finally realized FP is something you can’t ignore
any longer. Or maybe you’re like me and you’ve tried to learn FP many times before
but struggled to wade through all the terms or mathematical notation.
This first chapter’s purpose is to answer questions like “Why should I use FP
style with my code?” and “How does Functional-Light JavaScript compare to what
others say about FP?” After we’ve laid that groundwork, throughout the rest of the
book we’ll uncover, piece by piece, the techniques and patterns for writing JS in
Functional-Light style.
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 2
At a Glance
Let’s briefly illustrate the notion of “Functional-Light JavaScript” with a before-and-
after snapshot of code. Consider:
pickFavoriteNumbers();
calculateMagicNumber();
outputMsg(); // The magic number is: 42
// ***************
function calculateMagicNumber() {
for (let fave of faves) {
magicNumber = magicNumber + fave;
}
}
function pickFavoriteNumbers() {
for (let num of numbers) {
if (num >= 10 && num <= 20) {
faves.push( num );
}
}
}
function outputMsg() {
var msg = `The magic number is: ${magicNumber}`;
console.log( msg );
}
Now consider a very different style that accomplishes exactly the same outcome:
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 3
// ***************
Once you understand FP and Functional-Light, this is likely how you’d read and
mentally process that second snippet:
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 4
All those moving pieces speak to an FP developer in ways that likely seem highly
unfamiliar to you right now. This book will help you speak that same kind of
reasoning so that it’s as readable to you as any other code, if not more so!
A few other quick remarks about this code comparison:
• It’s likely that for many readers, the former snippet feels closer to comfort-
able/readable/maintainable than the latter snippet. It’s entirely OK if that’s
the case. You’re in exactly the right spot. I’m confident that if you stick it out
through the whole book, and practice everything we talk about, that second
snippet will eventually become a lot more natural, maybe even preferable!
• You might have done the task significantly or entirely different from either
snippet presented. That’s OK, too. This book won’t be prescriptive in dictating
that you should do something a specific way. The goal is to illustrate the
pros/cons of various patterns and enable you to make those decisions. By the
end of this book, how you would approach the task may fall a little closer to
the second snippet than it does right now.
• It’s also possible that you’re already a seasoned FP developer who’s scanning
through the start of this book to see if it has anything useful for you to read.
That second snippet certainly has some bits that are quite familiar. But I’m
also betting that you thought, “Hmmm, I wouldn’t have done it that way…” a
couple of times. That’s OK, and entirely reasonable.
This is not a traditional, canonical FP book. We’ll at times seem quite heretical
in our approaches. We’re seeking to strike a pragmatic balance between the
clear undeniable benefits of FP, and the need to ship workable, maintainable JS
without having to tackle a daunting mountain of math/notation/terminology.
This is not your FP, it’s “Functional-Light JavaScript”.
Confidence
I have a very simple premise that sort of underlies everything I do as a teacher of
software development (in JavaScript): code that you cannot trust is code that you do
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 5
not understand. The reverse is true also: code that you don’t understand is code you
can’t trust. Furthermore, if you cannot trust or understand your code, then you can’t
have any confidence whatsoever that the code you write is suitable to the task. You
run the program and basically just cross your fingers.
What do I mean by trust? I mean that you can verify, by reading and reasoning,
not just executing, that you understand what a piece of code will do; you aren’t just
relying on what it should do. More often than is perhaps prudent, we tend to rely
on running test suites to verify our programs’ correctness. I don’t mean to suggest
tests are bad. But I do think we should aspire to be able to understand our code well
enough that we know the test suite will pass before it runs.
The techniques that form the foundation of FP are designed from the mindset of
having far more confidence over our programs just by reading them. Someone who
understands FP, and who’s disciplined enough to diligently use it throughout their
programs, will write code that they and others can read and verify that the program
will do what they want.
Confidence is also increased when we use techniques that avoid or minimize likely
sources of bugs. That’s perhaps one of the biggest selling points of FP: FP programs
often have fewer bugs, and the bugs that do exist are usually in more obvious places,
so they’re easier to find and fix. FP code tends to be more bug-resistant – certainly
not bug-proof, though.
As you journey through this book, you will begin to develop more confidence in the
code you write, because you will use patterns and practices that are already well
proven; and you’ll avoid the most common causes of program bugs!
Communication
Why is Functional Programming important? To answer that, we need to take a bigger
step back and talk about why programming itself is important.
It may surprise you to hear this, but I don’t believe that code is primarily a set
of instructions for the computer. Actually, I think the fact that code instructs the
computer is almost a happy accident.
I believe very deeply that the vastly more important role of code is as a means of
communication with other human beings.
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 6
You probably know by experience that an awful lot of your time spent “coding” is
actually spent reading existing code. Very few of us are so privileged as to spend all
or most of our time simply banging out all new code and never dealing with code
that others (or our past selves) wrote.
It’s widely estimated that developers spend 70% of code maintenance time on reading
to understand it. That is eye-opening. 70%. No wonder the global average for a
programmer’s lines of code written per day is about 10. We spend up to 7 hours
of our day just reading the code to figure out where those 10 lines should go!
We need to focus a lot more on the readability of our code. And by the way,
readability is not just about fewer characters. Readability is actually most impacted
by familiarity.¹
If we are going to spend our time concerned with making code that will be more
readable and understandable, FP is central in that effort. The principles of FP are
well established, deeply studied and vetted, and provably verifiable. Taking the time
to learn and employ these FP principles will ultimately lead to more readily and
recognizably familiar code for you and others. The increase in code familiarity, and
the expediency of that recognition, will improve code readability.
For example, once you learn what map(..) does, you’ll be able to almost instantly
spot and understand it when you see it in any program. But every time you see a
for loop, you’re going to have to read the whole loop to understand it. The syntax
of the for loop may be familiar, but the substance of what it’s doing is not; that has
to be read, every time.
By having more code that’s recognizable at a glance, and thus spending less time
figuring out what the code is doing, our focus is freed up to think about the higher
levels of program logic; this is the important stuff that most needs our attention
anyway.
FP (at least, without all the terminology weighing it down) is one of the most effective
tools for crafting readable code. That is why it’s so important.
¹Buse, Raymond P. L., and Westley R. Weimer. “Learning a Metric for Code Readability.” IEEE Transactions on Software
Engineering, IEEE Press, July 2010, dl.acm.org/citation.cfm?id=1850615.
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 7
Readability
Readability is not a binary characteristic. It’s a largely subjective human factor
describing our relationship to code. And it will naturally vary over time as our skills
and understanding evolve. I have experienced effects similar to the following figure,
and anecdotally many others I’ve talked to have as well.
Readability of Declarative FP
You may just find yourself experiencing similar effects as you work through the book.
But take heart; if you stick this out, the curve comes back up!
Imperative describes the code most of us probably already write naturally; it’s
focused on precisely instructing the computer how to do something. Declarative code
– the kind we’ll be learning to write, which adheres to FP principles – is code that’s
more focused on describing the what outcome.
Let’s revisit the two code snippets presented earlier in this chapter.
The first snippet is imperative, focused almost entirely on how to do the tasks; it’s
littered with if statements, for loops, temporary variables, reassignments, value
mutations, function calls with side effects, and implicit data flow between functions.
You certainly can trace through its logic to see how the numbers flow and change to
the end state, but it’s not at all clear or straightforward.
The second snippet is more declarative; it does away with most of those afore-
mentioned imperative techniques. Notice there’s no explicit conditionals, loops, side
effects, reassignments, or mutations; instead, it employs well-known (to the FP
world, anyway!) and trustable patterns like filtering, reduction, transducing, and
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 8
composition. The focus shifts from low-level how to higher level what outcomes.
Instead of messing with an if statement to test a number, we delegate that to a
well-known FP utility like gte(..) (greater-than-or-equal-to), and then focus on
the more important task of combining that filter with another filter and a summation
function.
Moreover, the flow of data through the second program is explicit:
You may still feel this approach is convoluted, and that the imperative snippet was
easier to understand. You’re much more accustomed to it; familiarity has a profound
influence on our judgments of readability. By the end of this book, though, you will
have internalized the benefits of the second snippet’s declarative approach, and that
familiarity will spring its readability to life.
I know asking you to believe that at this point is a leap of faith.
It takes a lot more effort, and sometimes more code, to improve its readability as I’m
suggesting, and to minimize or eliminate many of the mistakes that lead to bugs.
Quite honestly, when I started writing this book, I could never have written (or even
fully understood!) that second snippet. As I’m now further along on my journey of
learning, it’s more natural and comfortable.
If you’re hoping that FP refactoring, like a magic silver bullet, will quickly transform
your code to be more graceful, elegant, clever, resilient, and concise – that it will
come easy in the short term – unfortunately that’s just not a realistic expectation.
FP is a very different way of thinking about how code should be structured, to make
the flow of data much more obvious and to help your reader follow your thinking. It
will take time. This effort is eminently worthwhile, but it can be an arduous journey.
It still often takes me multiple attempts at refactoring a snippet of imperative code
into more declarative FP, before I end up with something that’s clear enough for me
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 9
to understand later. I’ve found converting to FP is a slow iterative process rather than
a quick binary flip from one paradigm to another.
I also apply the “teach it later” test to every piece of code I write. After I’ve written
a piece of code, I leave it alone for a few hours or days, then come back and try to
read it with fresh eyes, and pretend as if I need to teach or explain it to someone else.
Usually, it’s jumbled and confusing the first few passes, so I tweak it and repeat!
I’m not trying to dampen your spirits. I really want you to hack through these weeds.
I am glad I did it. I can finally start to see the curve bending upward toward improved
readability. The effort has been worth it. It will be for you, too.
Perspective
Most other FP texts seem to take a top-down approach, but we’re going to go the
opposite direction: working from the ground up, we’ll uncover the basic foundational
principles that I believe formal FPers would admit are the scaffolding for everything
they do. But for the most part we’ll stay arm’s length away from most of the
intimidating terminology or mathematical notation that can so easily frustrate
learners.
I believe it’s less important what you call something and more important that you
understand what it is and how it works. That’s not to say there’s no importance
to shared terminology – it undoubtedly eases communication among seasoned
professionals. But for the learner, I’ve found it can be distracting.
So this book will try to focus more on the base concepts and less on the fancy fluff.
That’s not to say there won’t be terminology; there definitely will be. But don’t get
too wrapped up in the sophisticated words. Wherever necessary, look beyond them
to the ideas.
I call the less formal practice herein “Functional-Light Programming” because I think
where the formalism of true FP suffers is that it can be quite overwhelming if you’re
not already accustomed to formal thought. I’m not just guessing; this is my own
personal story. Even after teaching FP and writing this book, I can still say that the
formalism of terms and notation in FP is very, very difficult for me to process. I’ve
tried, and tried, and I can’t seem to get through much of it.
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 10
I know many FPers who believe that the formalism itself helps learning. But I think
there’s clearly a cliff where that only becomes true once you reach a certain comfort
with the formalism. If you happen to already have a math background or even some
flavors of CS experience, this may come more naturally to you. But some of us don’t,
and no matter how hard we try, the formalism keeps getting in the way.
So this book introduces the concepts that I believe FP is built on, but comes at it by
giving you a boost from below to climb up the cliff wall, rather than condescendingly
shouting down at you from the top, prodding you to just figure out how to climb as
you go.
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 11
Reminder, any extensibility point that’s never used isn’t just wasted
effort, it’s likely to also get in your way as well
Remember, every single line of code you write has a reader cost associated with it.
That reader may be another team member, or even your future self. Neither of those
readers will be impressed with overly clever, unnecessary sophistication just to show
off your FP prowess.
The best code is the code that is most readable in the future because it strikes exactly
the right balance between what it can/should be (idealism) and what it must be
(pragmatism).
Resources
I have drawn on a great many different resources to be able to compose this text. I
believe you, too, may benefit from them, so I wanted to take a moment to point them
out.
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 12
Books
Some FP/JavaScript books that you should definitely read:
Blogs/sites
Some other authors and content you should check out:
Libraries
The code snippets in this book largely do not rely on libraries. Each operation that
we discover, we’ll derive how to implement it in standalone, plain ol’ JavaScript.
However, as you begin to build more of your real code with FP, you’ll soon want a
library to provide optimized and highly reliable versions of these commonly accepted
utilities.
By the way, you need to check the documentation for the library functions you use to
ensure you know how they work. There will be a lot of similarities in many of them
Functional-Light JavaScript
Chapter 1: Why Functional Programming? 13
to the code we build on in this text, but there will undoubtedly be some differences,
even between popular libraries.
Here are a few popular FP libraries for JavaScript that are a great place to start your
exploration with:
• Ramda
• lodash/fp
• functional.js
• Immutable.js
Summary
You may have a variety of reasons for starting to read this book, and different
expectations of what you’ll get out of it. This chapter has explained why I want
you to read the book and what I want you to get out of the journey. It also helps
you articulate to others (like your fellow developers) why they should come on the
journey with you!
Functional programming is about writing code that is based on proven principles so
we can gain a level of confidence and trust over the code we write and read. We
shouldn’t be content to write code that we anxiously hope works, and then abruptly
breathe a sigh of relief when the test suite passes. We should know what it will do
before we run it, and we should be absolutely confident that we’ve communicated all
these ideas in our code for the benefit of other readers (including our future selves).
This is the heart of Functional-Light JavaScript. The goal is to learn to effectively
communicate with our code but not have to suffocate under mountains of notation
or terminology to get there.
The journey to learning functional programming starts with deeply understanding
the nature of what a function is. That’s what we tackle in the next chapter.
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 14
What Is a Function?
The question “What is a function?” superficially seems to have an obvious answer: a
function is a collection of code that can be executed one or more times.
While this definition is reasonable, it’s missing some very important essence that is
the core of a function as it applies to FP. So let’s dig below the surface to understand
functions more completely.
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 15
Do you remember learning anything about f(x) back in school? What about the
equation y = f(x)?
Let’s say an equation is defined like this: f (x) = 2x2 + 3. What does that mean?
What does it mean to graph that equation? Here’s the graph:
f (x) = 2x2 + 3
What you can notice is that for any value of x, say 2, if you plug it into the equation,
you get 11. What is 11, though? It’s the return value of the f(x) function, which
earlier we said represents a y value.
In other words, we can choose to interpret the input and output values as a point
at (2,11) on that curve in the graph. And for every value of x we plug in, we get
another y value that pairs with it as a coordinate for a point. Another is (0,3),
and another is (-1,5). Put all those points together, and you have the graph of that
parabolic curve as shown here.
So what’s any of this got to do with FP?
In math, a function always takes input(s), and always gives an output. A term you’ll
often hear around FP is “morphism”; this is a fancy way of describing a set of values
that maps to another set of values, like the inputs of a function related to the outputs
of that function.
In algebraic math, those inputs and outputs are often interpreted as components of
coordinates to be graphed. In our programs, however, we can define functions with all
sorts of input(s) and output(s), even though they’ll rarely be interpreted as a visually
plotted curve on a graph.
Function vs Procedure
So why all the talk of math and graphs? Because essentially Functional Programming
is about embracing using functions as functions in this mathematical sense.
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 16
Function Input
So far, we can conclude that functions must expect input. But let’s dig into how
function inputs work.
You sometimes hear people refer to these inputs as “arguments” and sometimes as
“parameters”. So what’s that all about?
Arguments are the values you pass in, and parameters are the named variables inside
the function that receive those passed-in values. Example:
function foo(x,y) {
// ..
}
var a = 3;
foo( a, a * 2 );
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 17
Note
In JavaScript, there’s no requirement that the number of arguments
matches the number of parameters. If you pass more arguments than
you have declared parameters to receive them, the values pass in just fine
untouched. These values can be accessed in a few different ways, including
the old-school arguments object you may have heard of before. If you
pass fewer arguments than the declared parameters, each unmatched
parameter is treated as an “undefined” variable, meaning it’s present and
available in the scope of the function, but just starts out with the empty
undefined value.
Defaulting Parameters
As of ES6, parameters can declare default values. In the case where the argument
for that parameter is not passed, or it’s passed the value undefined, the default
assignment expression is substituted.
Consider:
function foo(x = 3) {
console.log( x );
}
foo(); // 3
foo( undefined ); // 3
foo( null ); // null
foo( 0 ); // 0
It’s always a good practice to think about any default cases that can aid the usability
of your functions. However, defaulting parameters can lead to more complexity in
terms of reading and understanding the variations of how a function is called. Be
judicious in how much you rely on this feature.
Counting Inputs
The number of arguments a function “expects” – how many arguments you’ll likely
want to pass to it – is determined by the number of parameters that are declared:
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 18
function foo(x,y,z) {
// ..
}
foo(..) expects three arguments, because it has three declared parameters. This
count has a special term: arity. Arity is the number of parameters in a function
declaration. The arity of foo(..) is 3.
Furthermore, a function with arity 1 is also called “unary”, a function with arity 2 is
also called “binary”, and a function with arity 3 or higher is called “n-ary”.
You may wish to inspect a function reference during the runtime of a program to
determine its arity. This can be done with the length property of that function
reference:
function foo(x,y,z) {
// ..
}
foo.length; // 3
One reason for determining the arity during execution would be if a piece of
code received a function reference from multiple sources, and sent different values
depending on the arity of each.
For example, imagine a case where an fn function reference could expect one, two,
or three arguments, but you always want to just pass a variable x in the last position:
if (fn.length == 1) {
fn( x );
}
else if (fn.length == 2) {
fn( undefined, x );
}
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 19
else if (fn.length == 3) {
fn( undefined, undefined, x );
}
Tip
The length property of a function is read-only and it’s determined at
the time you declare the function. It should be thought of as essentially
a piece of metadata that describes something about the intended usage of
the function.
One gotcha to be aware of is that certain kinds of parameter list variations can
make the length property of the function report something different than you might
expect:
function foo(x,y = 2) {
// ..
}
function bar(x,...args) {
// ..
}
foo.length; // 1
bar.length; // 1
baz.length; // 1
What about counting the number of arguments the current function call received?
This was once trivial, but now the situation is slightly more complicated. Each
function has an arguments object (array-like) available that holds a reference to each
of the arguments passed in. You can then inspect the length property of arguments
to figure out how many were actually passed:
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 20
function foo(x,y,z) {
console.log( arguments.length );
}
foo( 3, 4 ); // 2
Except, how will you access an argument that was passed in a position beyond the
declared parameters? I’ll answer that in a moment; but first, take a step back and ask
yourself, “Why would I want to do that?” Seriously. Think about that closely for a
minute.
It should be pretty rare that this occurs; it shouldn’t be something you regularly
expect or rely on when writing your functions. If you find yourself in such a scenario,
spend an extra 20 minutes trying to design the interaction with that function in a
different way. Name that extra argument even if it’s exceptional.
A function signature that accepts an indeterminate amount of arguments is referred
to as a variadic function. Some people prefer this style of function design, but I think
you’ll find that often the FPer wants to avoid these where possible.
OK, enough harping on that point.
Say you do need to access the arguments in a positional array-like way, possibly
because you’re accessing an argument that doesn’t have a formal parameter at that
position. How do we do it?
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 21
ES6 to the rescue! Let’s declare our function with the ... operator – variously
referred to as “spread”, “rest”, or (my preference) “gather”:
function foo(x,y,z,...args) {
// ..
}
See the ...args in the parameter list? That’s an ES6 declarative form that tells the
engine to collect (ahem, “gather”) all remaining arguments (if any) not assigned to
named parameters, and put them in a real array named args. args will always be
an array, even if it’s empty. But it will not include values that are assigned to the
x, y, and z parameters, only anything else that’s passed in beyond those first three
values:
function foo(x,y,z,...args) {
console.log( x, y, z, args );
}
So, if you really want to design a function that can account for an arbitrary number
of arguments to be passed in, use ...args (or whatever name you like) on the end.
Now, you’ll have a real, non-deprecated, non-yucky array to access those argument
values from.
Just pay attention to the fact that the value 4 is at position 0 of that args, not position
3. And its length value won’t include those three 1, 2, and 3 values. ...args gathers
everything else, not including the x, y, and z.
You can use the ... operator in the parameter list even if there’s no other formal
parameters declared:
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 22
function foo(...args) {
// ..
}
Now args will be the full array of arguments, whatever they are, and you can use
args.length to know exactly how many arguments have been passed in. And
you’re safe to use args[1] or args[317] if you so choose. Please don’t pass in
318 arguments, though.
Arrays of Arguments
What if you wanted to pass along an array of values as the arguments to a function
call?
function foo(...args) {
console.log( args[3] );
}
var arr = [ 1, 2, 3, 4, 5 ];
foo( ...arr ); // 4
Our new friend ... is used, but now not just in the parameter list; it’s also used
in the argument list at the call-site. It has the opposite behavior in this context. In a
parameter list, we said it gathered arguments together. In an argument list, it spreads
them out. So the contents of arr are actually spread out as individual arguments to
the foo(..) call. Do you see how that’s different from just passing in a reference to
the whole arr array?
By the way, multiple values and ... spreadings can be interleaved, as you see fit:
var arr = [ 2 ];
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 23
Tip
Actually, these methods are not entirely useless. There will be a few places
we rely on them throughout the code in this book. But certainly in most
places, ... will be much more declaratively readable, and preferable as a
result.
Parameter Destructuring
Consider the variadic foo(..) from the previous section:
function foo(...args) {
// ..
}
foo( ...[1,2,3] );
What if we wanted to change that interaction so the caller of our function passes
in an array of values instead of individual argument values? Just drop the two ...
usages:
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 24
function foo(args) {
// ..
}
foo( [1,2,3] );
Simple enough. But what if now we wanted to give a parameter name to each of the
first two values in the passed-in array? We aren’t declaring individual parameters
anymore, so it seems we lost that ability.
Thankfully, ES6 destructuring is the answer. Destructuring is a way to declare a
pattern for the kind of structure (object, array, etc.) that you expect to see, and how
decomposition (assignment) of its individual parts should be processed.
Consider:
foo( [1,2,3] );
Do you spot the [ .. ] brackets around the parameter list now? This is called array
parameter destructuring.
In this example, destructuring tells the engine that an array is expected in this
assignment position (aka parameter). The pattern says to take the first value of that
array and assign to a local parameter variable called x, the second to y, and whatever
is left is gathered into args.
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 25
function foo(params) {
var x = params[0];
var y = params[1];
var args = params.slice( 2 );
// ..
}
Named Arguments
Just as we can destructure array parameters, we can destructure object parameters:
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 26
foo( {
y: 3
} ); // undefined 3
We pass in an object as the single argument, and it’s destructured into two separate
parameter variables x and y, which are assigned the values of those corresponding
property names from the object passed in. It didn’t matter that the x property wasn’t
on the object; it just ended up as a variable with undefined like you’d expect.
But the part of parameter object destructuring I want you to pay attention to is the
object being passed into foo(..).
With a normal call-site like foo(undefined,3), position is used to map from
argument to parameter; we put the 3 in the second position to get it assigned to
a y parameter. But at this new kind of call-site where parameter destructuring is
involved, a simple object-property indicates which parameter (y) the argument value
3 should be assigned to.
We didn’t have to account for x in that call-site because in effect we didn’t care
about x. We just omitted it, instead of having to do something distracting like passing
undefined as a positional placeholder.
Some languages have an explicit feature for this: named arguments. In other words,
at the call-site, labeling an input value to indicate which parameter it maps to.
JavaScript doesn’t have named arguments, but parameter object destructuring is the
next best thing.
Another FP-related benefit of using an object destructuring to pass in potentially
multiple arguments is that a function that only takes one parameter (the object) is
much easier to compose with another function’s single output. Much more on that
in Chapter 4.
Unordered Parameters
Another key benefit is that named arguments, by virtue of being specified as object
properties, are not fundamentally ordered. That means we can specify inputs in
Functional-Light JavaScript
Chapter 2: The Nature Of Functions 27
foo( {
y: 3
} ); // undefined 3
Tip
If this style of function arguments seems useful or interesting to you, check
out coverage of the FPO library in Appendix C.
Function Output
Let’s shift our attention from a function’s inputs to its output.
In JavaScript, functions always return a value. These three functions all have identical
return behavior:
Functional-Light JavaScript
Random documents with unrelated
content Scribd suggests to you:
LES TROIS SEMEURS
II
III
II
III
IV
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
ebookfinal.com