SURMA: Also, I just
learned my camera, Jake's camera, two shot. JAKE ARCHIBALD: Is
that what it is? SURMA: That's the two shot. JAKE ARCHIBALD: Oh-- sorry. SURMA: Because it shoots two-- 03. [SNAPS] [MUSIC PLAYING] So you're sick? JAKE ARCHIBALD: Yeah, I
guess we should explain. Like, we decided to come
to the studio and film "203," which is, like,
what we do, yeah? SURMA: That's our job. That's it. JAKE ARCHIBALD:
And we picked today because it's the only day that
we have for the next month. SURMA: Pretty much. JAKE ARCHIBALD:
And then I got ill. Yeah, and my eyes are running. My nose is running. My ears are running. They're not actually
running, but they're dying. Like, it's only
going to get worse. SURMA: Because
you're going to be moany and insufferable
to listen to. JAKE ARCHIBALD: Well, what
I'm going to try and do is I'm going to do the kind
of forced talking thing that I used to do as a
teenager when I got home drunk and I didn't want my
parents to know I was drunk. And then, sort of-- oh, yeah. Oh, yeah, they
always knew, right? SURMA: But they
knew, right? yeah. JAKE ARCHIBALD: But this is
me pretending not to be ill. So there might be some sniffles. So our editor, Lucas, he's going
to do an amazing job of editing all of that out. Cheers, Lucas. Thank you! SURMA: Hashtag, #nopressure. So. JAKE ARCHIBALD: So. SURMA: This is probably one of
the most clickbaitiest titles I've-- well, not even clickbait. Just polarizing titles. JAKE ARCHIBALD: Well,
the answer is yes. SURMA: Yes, it is bad. Is reduce() bad? Yes. Thank you for joining us. JAKE ARCHIBALD: Bye-bye. SURMA:
[SNAPS, CHANTS WORDLESSLY] All right. [LAUGHS] JAKE ARCHIBALD: I like your
impression of the theme. That was quite good. OK. SURMA: So there is,
obviously, a background story to why this is a topic now. JAKE ARCHIBALD: Yeah. SURMA: But first,
just to make sure everybody knows
we're talking about, we're talking about
the array method. So you have an array
it with stuff in it. JAKE ARCHIBALD: Right. SURMA: And reduce() it's one
of these array methods that you mutate or process
whatever's in it. And reduce() specifically, you
give it and accumulate a start value and the function. JAKE ARCHIBALD: Yes. SURMA: And then,
for each element, the accumulator and
element will be passed in, and whatever the
function returns becomes the new
accumulator value. JAKE ARCHIBALD: Yep. SURMA: And that just keeps
going until the entire array has been processed. That can be used for
a couple of things. JAKE ARCHIBALD: Yes. SURMA: That can also be
abused for a couple of things. JAKE ARCHIBALD: Or many things. SURMA: And you did a tweet. JAKE ARCHIBALD: I did. SURMA: Which was
actually triggered by another conversation
that we had on the side. JAKE ARCHIBALD: Yes. This is me sub-tweeting
one of our colleagues. SURMA: And I think we've talked
about this before a couple times. But we basically both think most
of the time what reduce() is, or where reduce() is used, it
shouldn't actually be used. There's better ways of achieving
the things where people use reduce(). There's a couple
of very few cases where it actually makes sense. One of them is like if
you want to look smart. JAKE ARCHIBALD: Yes, absolutely. I mean, I want to point out that
I'm not shaming people here. Well, actually, there is
one person I'm shaming, and it's myself. Because I definitely went
through three phases, like, learning code. First one, my code
is very simple, and I didn't use things
like regex and array.reduce because they were scary. SURMA: Agreed. JAKE ARCHIBALD: And then
I learned these things, and I learned all
of the programming techniques of, like, couriering,
recursion, blah, blah, blah. And I though, you know-- SURMA: Why not use them? JAKE ARCHIBALD: Yeah, my
code should demonstrate how clever I am to everyone. And so I will use
all of these things so anyone can look at any one
bit in my code, and they'll go, that guy is smart, and
he knows lots of things. SURMA: And then, I think that's
because if the other person doesn't understand
your code, you are smarter than that person. JAKE ARCHIBALD: Exactly, yeah. Yeah, yeah, and they
should just get cleverer, which is really-- which
was a lot of the replies I got to this thread. But I'm now-- I've been doing JavaScript for
20 years, and I'm kind of-- I've got into this third
phase, which is just like-- SURMA: 20 years? JAKE ARCHIBALD: Yeah. SURMA: That old? JAKE ARCHIBALD: I'm quite old. I look particularly old
today with the illness. But I feel like I'm now in
the third phase of my coding experience, which is
like I want my code to look like the code
in a beginner's book. Like, I want it to be
that straightforward. SURMA: Yeah, definitely,
over the years, I've learned to appreciate
code that you can just read, and you're like, I
understand what is happening. That is so invaluable when
you have that in a project and you actually know
where to go and fix it. And so that's basically
what I want to talk about. So what I did is look
at some examples. And I kind of want to throw
an hypothesis out here, where I think when
you see you reduce(), it will fall into one
of four categories. JAKE ARCHIBALD: Four? Right, OK. SURMA: The first category is,
it's a sum, or something that's like a sum. JAKE ARCHIBALD: It's sumlike? SURMA: Sumlike. JAKE ARCHIBALD: I like that. SURMA: [LAUGHS] The second
category is it should really be just using array methods. Maybe with some object entries
and object from entries. JAKE ARCHIBALD: Yes. And those things are-- some of the things are new. Like, from entries
is particular new. SURMA: Yes. And we're gonna talk about that. JAKE ARCHIBALD: Yeah, OK. SURMA: But basically, sometimes
I see a reduce() that is just a glorified filter or map. And really, you should have
been using filter and map. JAKE ARCHIBALD: Yep. SURMA: The third category
is it's a loop, isn't it? Like, just use a loop, and don't
do reduce() to abuse a loop. Like that's just using the loop
aspect of reduce() and actually don't use the thing that
makes reduce() reduce(). JAKE ARCHIBALD: I
would agree right now. SURMA: And then, the third
category is, hashtag, #IAmSmarterThanYou. JAKE ARCHIBALD: Yes! SURMA: And those were examples
where I looked at them and I just couldn't
figure out what they were trying to achieve. So my theory is that these
would fall into category one to three if I could understand
what they were doing. JAKE ARCHIBALD: Yeah. SURMA: And I didn't put any
examples of category four in here, because otherwise,
people would just explain in the comments to
me what this fragment does, and that would just be,
you know, what's the point? JAKE ARCHIBALD: Well, and
in that thread, there was-- I was asking people
for examples as well. And yes, there
was a lot of times where I had to just,
like, really stare at it. And like I say, 20
years of experience. I'm not the smartest
person by any stretch, but I had to really
stare at the code. SURMA: I'll agree. [LAUGHS] JAKE ARCHIBALD: Thank you. And then, once I'd kind
of be like, oh, oh, oh, I know what this is doing
now, and then I would write it as a loop(), and
so much clearer-- to me. But then, the code you write
is always clearer to you. But what-- yeah. SURMA: And so I thought I would
look at some popular projects. JAKE ARCHIBALD: Oh! SURMA: Clone them, and just do
a code search for dot reduce(). JAKE ARCHIBALD:
What's Spectrum Chat? SURMA: Spectrum Chat is a chat. JAKE ARCHIBALD:
That's really cool. I should have figured
that out for myself. It's written on the
Sinclair Spectrum. SURMA: With React Redux. That's all I remember. But I thought, you know,
if Redux is in there, there probably is
reduce() in there. That was my assumption. And so I just used
a couple of projects I knew, looked through the code,
and picked some examples of-- good examples for these
categories that I have. JAKE ARCHIBALD: Let's see 'em. SURMA: So let's start. First category. I'll let you take a look
and try to explain it. This one is a pretty
easy start, I think. JAKE ARCHIBALD: Oh, I see. OK, yeah. OK, so you've got an
array of durations, and you're trying to
find out the maximum one. SURMA: It turns out there's
a better way to do this. JAKE ARCHIBALD: Yes, it is that. SURMA: Yes. JAKE ARCHIBALD: There it is. SURMA: I'm not sure if this is
just a pattern that exists now because spread of the thing,
but even before that, you could use Apply or Recall. JAKE ARCHIBALD: Yes. SURMA: It's easier to read. The entire reduce() just is
more mental overhead to parse, I think this would be a
preferable way to write it. JAKE ARCHIBALD: So I heard
someone actually say that this hits a limit of argument count,
whereas the other one doesn't. Now, I don't-- I've
not tested this, so I don't know
what that limit is. SURMA: OK. JAKE ARCHIBALD: But even then,
I think you could fold it out to a loop, right? SURMA: Even then--
or just, at least, contain this slightly
overhead-y version and put it in a
function called "max." JAKE ARCHIBALD: Yes, absolutely. SURMA: Which just takes an
array, [INAUDIBLE] apparent. JAKE ARCHIBALD: Yeah, right . And even then, I'd use a loop. SURMA: Yeah. JAKE ARCHIBALD: Because it'd
be faster and easier to read. SURMA: This one I
found interesting. JAKE ARCHIBALD: OK. SURMA: Because I
actually am not sure-- yes, you could probably write
it as a loop, but it's-- so the good thing about this
example is they used reduce(), but they contained the reduce()
weirdness in a function. So it takes-- gives
an array of values, and you want to basically
accumulate them up for each. JAKE ARCHIBALD: And each one is
the accumulation of the last? I see. SURMA: And as long as you put it
and function has a descriptive name, I actually kind of don't
care how you implement it, because the functions
that use this function are going to be quite easy to read. JAKE ARCHIBALD: Right. SURMA: You could
use a loop in here. I don't think it makes
that big of a difference. JAKE ARCHIBALD: So it's
starting to get to the point where the things
I dislike about-- I've just noticed
there's a extra line of this code missing. Anyway-- SURMA: Oh, is it? JAKE ARCHIBALD: Yeah,
the final [INAUDIBLE].. So my brain's all on fire now. This is starting to get to some
of stuff I don't like about reduce(). And one of the-- it's a problem with quite a
few functions in JavaScript, is that the arguments
are in the wrong order. SURMA: Yeah. JAKE ARCHIBALD: Right? Like if you've got a callback,
that needs to go last, right? Or it needs to be-- because the simplest code
is read sequentially. SURMA: True. JAKE ARCHIBALD: A loop is
fine because you go down, and then you go back. You've got-- like, but it's
still sort of sequentially. Whereas here, to even
start to understand this, you have to go-- SURMA: At the end. JAKE ARCHIBALD: --to
the end of the thing and then read back from there. And-- SURMA: Yeah, JAKE ARCHIBALD: And also, this
is creating a lot of arrays as well. I mean, I know you didn't-- you're not wanting to
talk about performance. SURMA: Oh, yeah. That's actually a
thing I didn't mention. I didn't want to talk about
performance, because I feel like the first order that
you look when you look at code should be readability. JAKE ARCHIBALD: Absolutely. SURMA: Performance should
be a second priority most of the time. JAKE ARCHIBALD: Yes. SURMA: Because-- and that's
only because we have reached a point that the community
looks at performance first to the point where
they have reached a point of return of investment
is just not there anymore. They optimize things that
don't need optimizing at all. And some people have
sacrificed readability in favor of performance
for performance that they don't need. JAKE ARCHIBALD:
Right, but this is doing-- this is sacrificing
readability and performance. SURMA: Potentially, yes. JAKE ARCHIBALD: Yeah. SURMA: I mean, I'd
love to put this in because I want to show that
if you put it in a function has a good name, you can get
away with more, in my opinion. JAKE ARCHIBALD: I absolutely
agree with that as well. And even then, actually, I
would then take the opportunity to just make it a loop. SURMA: Sure, then you
have it well contained. You can write your tests. You can do the
refactoring in one place. JAKE ARCHIBALD: A lot of people
don't like mutations in code, but if you're limiting it
just to one function, it's OK. SURMA: Yeah, I would
agree, definitely. The next one, I
found it interesting, but it's one of the
classic examples. Basically, you get
a graph-- you get-- you have a list
of edges, which is between two points in
the graph, and it's trying to build the graph, which
you can look up for a start edge all the connections that
a start edge has to all the end edges. And this is this example where
you're abusing reduce() just for the loop aspect. JAKE ARCHIBALD:
And the tell here is the thing that is put
in here comes out here, and it's just returned. SURMA: Yes. JAKE ARCHIBALD: It's the
same object every time. It's just a loop. SURMA: So really, if you
have that, just use loop. And this is
actually, I think, so much easier to understand
what's happening. Because you create a map. You loop over the edges. You add sets for the edges
if they don't exist yet. And then, you just add
the individual edges to the array that
corresponds to it. JAKE ARCHIBALD: Yeah. SURMA: If you-- and now I
know that people are like, oh, but this is not Like
I said, some people like the pure aspect. But the pure version is
just not as readable. I tried to write one,
and its like, yes, it is potentially understandable. JAKE ARCHIBALD: Oh, I see. SURMA: But I don't think that
it's worth, for purity's sake. JAKE ARCHIBALD: Yeah. SURMA: Especially because
JavaScript, to me, is still not a functional
programming language. You can write functional
code in JavaScript, but it's not
functional programming by nature or by design. JAKE ARCHIBALD: Yeah, so
readability is tangible. It's subjective,
but it's tangible. You can look at two things and
go, that's the one I prefer. Performance is tangible, right? SURMA: Even measurable. JAKE ARCHIBALD: It's measurable. You can see that. But when people say, like,
purity, it's like, well, but what do you
get for it, right? And I understand,
like, you can actually gain a lot of reliability
by avoiding mutations. But again, if you're isolating
that into one function and the mutation doesn't
happen outside of it-- SURMA: And I think
that's the key. JAKE ARCHIBALD: Yeah. SURMA: It'd be easier-- if
small, self-contained functions are your building
blocks, then you can work with mutability inside
the small, defined scopes. JAKE ARCHIBALD: Because mutation
is happening somewhere, right? SURMA: Yeah. JAKE ARCHIBALD: There
ones are turning to zeros and vice-versa. SURMA: How dare you? JAKE ARCHIBALD: At
some point, yeah. So yeah, OK, let's carry on. SURMA: This one I found cute. And this is one
of these examples where something that exists
now probably didn't exist. JAKE ARCHIBALD: Oh, it's flat. SURMA: It is flat. JAKE ARCHIBALD: Right. SURMA: And so I was
like, OK, let's give him the benefit of the doubt. Because probably, flat
didn't exist at the time they wrote it. JAKE ARCHIBALD: Yeah. SURMA: So what they should
really have been doing it's just [INAUDIBLE]. Which probably didn't
exist at the time. JAKE ARCHIBALD: Yes. SURMA: But even then, write a
function that's called "flat." Because when I see this code, I
have to read it and, like you, go, huh? Huh? Oh, it's flat. Which is a semantic abstract
that makes it so much-- make it so much easier to read. So if "flat" didn't
exist, just write this code, the previous
code, and put it in a function called "flat." JAKE ARCHIBALD: Yes, absolutely. SURMA: Which just makes
it easier to read. JAKE ARCHIBALD:
Yeah, and again, even if I was writing
that function, I would avoid the many array
create-- oh, here we go. SURMA: Even if I do this. JAKE ARCHIBALD: I'd do this. SURMA: Even then you would use
a loop, because once again-- And I know that some people
have problems with the whole, oh, you create a variable, and
then you mutate it in a loop. But I think it's easy to read. It's easier to follow what
is actually happening. JAKE ARCHIBALD: And
if you're trying to be strict about
mutations, as long as it's held within one function, like
we said, I'm fine with it. SURMA: A couple more examples. So this one I looked at,
and I was like, holy crap, this is unnecessarily
complicated. Because what they're
effectively doing is they're creating
an empty array-- JAKE ARCHIBALD: Oh, OK. SURMA: --which they are
concatenating to and returning. So it is kind of like, oh,
this would probably be a loop. JAKE ARCHIBALD: So
we're appending-- SURMA: And this I
looked at, and then I realized, oh, they
want to put commas in between the
individual links except for the first and
the last element. JAKE ARCHIBALD: Oh,
hello, it's join. It's-- SURMA: So I thought-- JAKE ARCHIBALD: It's not, is it? SURMA: It is join. However-- JAKE ARCHIBALD: However-- SURMA: This is a list
of VDOM nodes of JSX. JAKE ARCHIBALD: Right. SURMA: So a join that
basically intersperses the element between
already existing elements and returns a new array
doesn't exist out of the box. JAKE ARCHIBALD: Right. I see, yes. Because the join is
always going to give you-- SURMA: So this is
actually a thing where this one would give
you the wrong result. You can't just use join,
because join returns a string. JAKE ARCHIBALD: OK. SURMA: But again, write
a function that's called JSX joint or
something, which just makes it easier to parse of
what is actually happening-- JAKE ARCHIBALD: So
what they're trying to do is put the text
node with a comma in in-- SURMA: Yes. JAKE ARCHIBALD: --in between? Right, I see. OK. Yeah, fair enough. SURMA: But once
again, I feel like-- JAKE ARCHIBALD: A loop would-- SURMA: Write a function. Functions don't cost anything. JAKE ARCHIBALD:
A loop would have made up so much clearer to me. SURMA: All right, like you say,
I acknowledge it's subjective. But loop would also
work, actually. Yeah, that's a good idea. I just like in this case,
you get a bunch of links and a bunch of
issues, and you turn each issue in its own link tag. The map here I find
very expressive. JAKE ARCHIBALD: Yes. Oh, yeah, yeah. I mean, obviously, but yes,
you would have to change it so you're returning. SURMA: You could do it
as a-- as a flatMap. JAKE ARCHIBALD: Yeah, a
flatMap-- exactly that. Yeah, so because it's valid
to have an array where it's a JSX element and
then a string, which will be a text node. Yeah, OK, flatMap is the thing,
which is also pretty new. SURMA: Yeah. Again, just write
your own function. JAKE ARCHIBALD: OK. All right, OK, so we've
got the usual problem of just passing the object
around, and around, and around. SURMA: Yes. So this is basically something
I would say, write a loop. Except in this case, we're
building up an object. And when that's happening,
in modern JavaScript, I would say this is a use
case for object entries and object from entries. JAKE ARCHIBALD: Yeah. SURMA: So basically,
what they were doing is they would just
look at all the events that were there and
creating a new object that has a function for
each of these events. So in this case, you
could just turn it into an entries list,
map over the values, change them how you like, and
then turn it back to an object. JAKE ARCHIBALD: Yep. SURMA: This is actually
borderline readable to me. I feel like if this gets
a bit more complicated, a loop might be easier to read. JAKE ARCHIBALD: Yeah,
and again, if the idea is you're wanting to assign
it to a constant rather than-- because if-- well,
actually, even, you wouldn't-- it would
be a constant anyway, because it's an objective,
and you just mutate it, right? And again, farm it out to
another function, and-- SURMA: Yeah. JAKE ARCHIBALD: It's fine. SURMA: Now, this is
something you already mentioned to me earlier, so I
didn't talk about it any more. But this [INAUDIBLE]. So here's someone who
put it in the function and wrote a comment-- really good. You're allowed to reuse,
reduce() with a comment and an explanation. Like, I wouldn't have written
it this way necessarily, but you pull in the
function itself, and it points to the
person who wrote this. What they're doing is add
together the top, left, bottom, and right properties
of each client but keep width and
height of the first one. JAKE ARCHIBALD: Right? Oh, interesting. SURMA: So that's what
they're doing here. And now that I've
read the comment, I can almost immediately
see that that's what's actually happening. Personally, I would
have written it like this, where I
would actually make the code give that explanation. JAKE ARCHIBALD: I see. SURMA: I would turn each
property into a sum. However, if this is a hot
path in your code iterating over your rectangles
four times-- or iterating, and
mapping, and summing-- this could, potentially, be
a performance consideration at some point. JAKE ARCHIBALD:
Yes, in which case you can turn it into a
loop-- a single loop. SURMA: Potentially, yes. Yeah. JAKE ARCHIBALD: So yeah, the
reason we start talking about this, and then you
told me to shut up, because you were going to be
talking about in this episode, is when I stuck my neck out
and said, reduce() is bad, obviously, I went and looked
at all the code that I'm likely to be releasing in the next
month and checked to see, have I use reduce()? Because you know, I'm not-- I'm a bit of a
hypocrite sometimes. And like I used reduce() a
few times for adding stuff together. SURMA: Yeah. Sums. JAKE ARCHIBALD: Sums. The one exception was
kind of similar to this, where I had an array of
client [INAUDIBLE] objects. SURMA: Yeah. JAKE ARCHIBALD: And I was
finding the boundings-- the total bounds of all those. SURMA: Yeah. JAKE ARCHIBALD: And I
am still in two minds. However, it's a
good of [INAUDIBLE].. SURMA: So you would
find the minimum of top, the minimum of left,
the maximum of bottom, and the maximum of
right, basically, right? JAKE ARCHIBALD: Yes. SURMA: Yeah. JAKE ARCHIBALD:
So you could map, and max and min would
be fine, potentially? SURMA: Yes. More expressive, but
you know, as I said, this was put in a function. So I'm less inclined to
actually get annoyed by it. I really just dislike
when there's a reduce() in the middle of
a bigger function. Then I have to stare
at it and figure out, what is the semantic
equivalent of that reduce()? JAKE ARCHIBALD: Yes,
and that's probably the-- any tricks you do,
if you can isolate those into a single function. Because sometimes tricks
make the code really fast. Or if you are chasing file
size-- which you probably shouldn't be-- but if
you are, yeah, putting that stuff into
another function, even if it's only used
once, a good minifier will be able to inline that. SURMA: Yeah. JAKE ARCHIBALD: And so you get
the benefits of documentation and readability, and you
still get to use your trick, and it-- yeah. SURMA: Exactly. Do I have more? I think I have some more. So this is a pattern
I've seen quite a bit, actually, where this
filter Boolean-- JAKE ARCHIBALD: Oh,
that's-- yeah, I see. SURMA: --invocation is basically
a way to say, only keep the truthy values. JAKE ARCHIBALD: That's
quite-- that's kind of cool. It's a fun trick. SURMA: And it's
something I think-- JAKE ARCHIBALD: I would
always spell it out, but-- SURMA: But it's a filter-- like f maps to f. Like, it's also not
much more expensive. I feel like this is actually
a bit more expressive, in a sense, what it does. JAKE ARCHIBALD: True, true. You could say it reads
like the Booleans from the other data types. SURMA: Yeah, I guess it
could also be misunderstood if you don't know Java-- JAKE ARCHIBALD: I agree. And I did actually write
a piece of code today which was filter, like,
f, arrow, arrow, f. And yes, because in this
case, I was actually trying to get rid of
the empty strings. SURMA: Yeah. JAKE ARCHIBALD: Yeah, I
actually-- that's good. I don't know which one. And maybe I should have done
f equals equals empty string, would have probably been the
more expressive way of doing that. OK. SURMA: So what they do
is they get the edges, they filter out all
the faulty values, and then, for each remaining
one, they start with zero, and if the node is seen, they
don't increment the count. And otherwise, they do. So they're basically counting
the things that are not seen. JAKE ARCHIBALD: I see. SURMA: So I feel like this
should be done differently, because what you could just
do is like you map to isSeen, then map out the
Boolean, say, dot length. JAKE ARCHIBALD:
Right, of course. SURMA: Yes. JAKE ARCHIBALD: So this
is going to be either-- Yeah SURMA: Either it doesn't
exist, or it is-- JAKE ARCHIBALD: So
it's going to be false. Yes. Yeah, that's much
more obvious to me. And it's nice that it's-- one of the things I like about
the functional programming thing is that, like I said
before, it's simple code is sequential. SURMA: Yeah, and it is
a sequence of steps. That's the key. JAKE ARCHIBALD: And if it was
a series of function calls, you'd have to read
them inside out. SURMA: Yeah. JAKE ARCHIBALD: Which is
not sequential, so this-- I like that element. SURMA: Agreed. JAKE ARCHIBALD: Yeah. SURMA: This is another
example, I think, of we have a combination
of things, really, where you just-- they
reduce() over a list, see if it has a thumbnail,
and if it has a thumbnail, it gets pushed into a list. So really, what they're doing-- JAKE ARCHIBALD: Filter it. SURMA: You filter it,
and then you map it. Or, if you want to use the new
pattern that we just showed, you can map first, and then just
fill it up with two or three [INAUDIBLE]. JAKE ARCHIBALD: Yeah,
that's what I do. SURMA: Both of these
would work just fine. All right, this is all
the examples that I have. JAKE ARCHIBALD: OK. SURMA: It was quite
a bit, I thought. So these were all--
again, these were code examples from these
real projects, and some more. Like, this is real
code out there. And I feel, often, you can have
more expressive, more readable code. "Code," not "cold," although
you have an expressive cold. JAKE ARCHIBALD: Yeah,
you're just making me feel bad for having a cold. SURMA: [LAUGHS] JAKE ARCHIBALD: Right. SURMA: again, anybody who uses
reduce() shouldn't feel bad. You're allowed to use reduce(). This is not us
wagging our fingers. Just saying, like, here's how
we've come to the conclusion that most of the time, reduce()
can be replaced by something that we would deem better. JAKE ARCHIBALD:
And it is something that, like, let's say, I have
made this mistake in code before, and much worse
mistakes with lots of tricks. Like, I often felt like
going back a few years, my attitude to coding was like
I was doing all this smart parkour when I could have just
walked down the street and got there faster, you know? But I wanted people
to think I was cool. And so-- SURMA: Yeah, pretty much. JAKE ARCHIBALD: Even if
you feel, like, seen. By this, and you think, oh
yeah, that is what I'm doing, you're not alone. SURMA: So one last thing
I want to point out. Obviously, if you have
these nice, sequential sort of the map, and the filter, and
another map, and the flatMap, or whatever, some
people might be worried about creating all
these intermediate arrays for the individual steps,
which [INAUDIBLE] will create under the hood. Like one map will create,
take the original array, and create a new array. JAKE ARCHIBALD: Yes. SURMA: It doesn't mutate
the existing array. So each step will be, basically,
an entire copy of the array with a function applied to it. If people are worried about the
intermediate values and arrays being created,
there is also a way of doing this with iterators. JAKE ARCHIBALD: Ooh. SURMA: So I'm going to plug
a super old project of mine-- JAKE ARCHIBALD: OK SURMA: --which is
called Underdash-- JAKE ARCHIBALD: Nice. SURMA: --where I
basically collected all the functions
that underscore and something like
this provides and have little two- to three-line
implementations of it, and you can just copy-paste. So rather than having
a library for it that you download and install,
you just copy-paste the code that you need. And I have it for a
arrays, but most of them also have a synchronous iterator
and an asynchronous iterator version. So instead of chaining
array methods, you could be working
with iterators, which basically prevents all
the intermediate arrays being created. JAKE ARCHIBALD: Yes,
because it's passing-- it's like a stream
essentially, isn't it? SURMA: It's basically streams. JAKE ARCHIBALD: Yeah. SURMA: Yes. And you know, if somebody's
interesting in that, take a look at it. It still exists on my GitHub. JAKE ARCHIBALD: Yep. SURMA: And with that,
is reduce() bad? JAKE ARCHIBALD: Yes. SURMA: Yes. See you next time. [MUSIC PLAYING] [LAUGHTER] I'm going to keep it ending. JAKE ARCHIBALD: Yeah,
I saw go for it. Our Editor Lucas is-- SURMA: Really cool, really cool,
really, really, really cool. JAKE ARCHIBALD: Good, Lucas.