
English: 
Hi, everybody.
How we doing?
We got caffeinated?
Feeling good?
Nice.
So I'm Anjana Vakil, hello.
You can find me on Twitter at my name and
today I'd like to talk to you about immutable
data structures for functional programming
in JavaScript.
We're going to take a look at what immutable
data structures are, why they're a really
cool way to handle the immutability that we
typically use when we're doing functional

Chinese: 
大家好。
我们怎么样
我们含咖啡因吗？
感觉好吗？
真好
我是Anjana Vakil，您好。
您可以在Twitter上以我的名字找到我，
今天我想和你谈谈不可变
功能编程的数据结构
在JavaScript中。
我们将看看什么是不变的
数据结构是，为什么它们是真正的
处理我们不变性的好方法
通常在我们执行功能时使用

English: 
programming and how we can do that in JavaScript
because I hear y'all like JavaScript!
So a little about me.
I'm probably the only not-web-developer in
the room.
I am an engineer for Uber Research.
I work with them to develop a custom query
language for data in the scientific research
funding domain.
I'm also an alum of the Recurse Center, which
is a fantastic programming community in New
York City, and I am an alum of the Outreach
Program, which if you have haven't heard of
it, it's getting women and more folks involved
in these by giving them internships at Mozilla.
So I'm really happy to chat about those things
if you want to come grab me after the talk.
But you might know that I like functional
programming.
I think it rocks.
Anybody else agree with me that functional
programming is cool?

Chinese: 
编程以及我们如何在JavaScript中做到这一点
因为我听说你们都喜欢JavaScript！
关于我的一点点。
我可能是唯一的非网络开发人员
房间。
我是Uber Research的工程师。
我与他们一起开发自定义查询
科学研究中的数据语言
资金领域。
我也是递归中心的校友
是New一个很棒的编程社区
约克市，我是外展活动的明矾
程序，如果您尚未听说过
它吸引了更多的女性参与
在Mozilla中给他们提供实习机会。
所以我很高兴谈论这些事情
如果您想在谈话后来抓住我。
但是你可能知道我喜欢功能
编程。
我认为这很糟糕。
其他人都同意我的观点
编程很酷吗？

English: 
Yeah!
Yeah, so functional programming is a pretty
great way to avoid some of the headaches of
like imperative and object-oriented programming.
In functional programming, what we typically
do is conceive of our programs as being just
pure functions.
That means their transform their inputs to
outputs, and that's all they do.
They don't have my side effects like changing
things in the console, and my taking things
in the global state are side effects.
But our data becomes data in, data out, and
transformers of data.
And one thing that goes hand-in-hand with
this, with avoiding side effects is immutable
data.
Immutable data meaning once we've created
it, it never changes.
So this is a really good way of changing something
accidental outside of your function.
If everything is immutable, you can't change
anything.

Chinese: 
是的
是的，所以函数式编程非常漂亮
避免一些头痛的好方法
例如命令式和面向对象的编程。
在函数式编程中，通常
所做的只是将我们的程序视为公正
纯函数。
这意味着他们将输入转换为
输出，这就是他们所做的全部。
他们没有改变我的副作用
控制台中的内容以及我的拍摄内容
在全球范围内都有副作用。
但是我们的数据变成了数据输入，数据输出和
数据转换器。
与之紧密相连的一件事
这样，避免副作用是一成不变的
数据。
不变的数据意味着我们创建之后
它，它永远不会改变。
所以这是改变某些事情的一种非常好的方法
功能外的意外。
如果一切都是不变的，那么你就无法改变
任何东西。

Chinese: 
永恒不变的另一件事
由于其他原因，它很难摇晃
我们待会儿见。
但是说到岩石，让我们谈谈岩石。
所以这是一块岩石，而不变性岩石
以晃动的方式
现在我不认识你，但是我一直
最近要参加很多技术会议
我一直觉得那里有足够的
诗歌。
所以我想读一首诗：
没有人像岩石一样坐着。
你摇滚，摇滚。
岩石就此静坐。
您向我们展示了如何坐在这里。
这就是我们所需要的。
如此真实，如此深刻。
这是-
不用了，谢谢，我的心Huckabees，那是
一部很棒的电影。
一探究竟。
因此，这确实是不可变数据的摇动方式。
它只是坐在那里。
就是这样
创建之后，它就永远不会改变，
太神奇了，因为它可以帮助我们避免

English: 
So immutability another thing that rocks and
it rocks pretty hard for other reasons that
we'll see in a moment.
But speaking of rocks, let's talk about rocks.
So this is a rock, and immutability rocks
in the way that rocks rock.
Now I don't know about you, but I've been
going to a lot of tech conferences recently
and I've been feeling like there has enough
poetry.
So I'd like to read you a poem:
Nobody sits like this rock sits.
You rock, rock.
The rock just sits and is.
You show us how to just sit here.
And that's what we need.
It's so true, so deep.
This is from --
Don't thank me, thank I Heart Huckabees, that's
a great movie.
Check it out.
So this is really how immutable data rocks.
It just sits there.
It just is.
Once we've created it, it never changes and
that's amazing because it can help us avoid

English: 
some of the headaches of immutability.
So with immutability, we have some things
pretty easy, but other things become harder
and we'll see how that looks.
So let's say I have an array called foo and
it's got some numbers in it.
Hm, and I'm already bored.
Let's make it more fun.
Let's say I have a zoo with some animals -- more
fun!
And I decided that I want to change something
up about my zoo.
Maybe I want to replace that rabbit there
with something a little more exotic.
Like an alien!
So this is cool.
I'm happy because I wanted a more exotic zoo.
I got an alien in my zoo now.
I didn't have to change anything except for
that one little cell in my array.
That's pretty sweet but my co-worker over
was expecting zoo to be filled with earth
beings, earth animals, and wasn't accounting
for there being an alien in it.
Who put that in there?
Now my program doesn't work anymore.

Chinese: 
不变性的一些头痛。
因此，有了不变性，我们有了一些东西
很容易，但是其他事情变得更困难
我们将看看它的外观。
假设我有一个名为foo和
它里面有一些数字。
嗯，我已经很无聊了。
让我们变得更有趣。
假设我有一个动物园里有一些动物-更多
好玩！
我决定要改变一些东西
关于我的动物园。
也许我想在那里替换那只兔子
有点异国情调。
像外星人一样！
所以这很酷。
我很高兴，因为我想要一个更具异国情调的动物园。
我现在在动物园里有一个外星人。
我除了不需要改变任何东西
我数组中的那个小细胞。
真是太好了，但我的同事
原本希望动物园充满泥土
生物，地球上的动物，并且不算账
因为里面有一个外星人。
谁把它放在那里？
现在我的程序不再起作用。

English: 
Who did that?
So immutability has a couple problems.
We have to manage who's been changing what,
when -- who's been putting which animals in
the zoo.
We have to have a lot of overhead to manage
that state, and that gives us headaches as
individuals, and as teams.
We also get bugs in the code because maybe
I was only planning -- or my co-worker was
only planning -- to handle terrestrial beings
and didn't have a case of aliens being accounted
for, and that broke something.
So these are some side effects of immutability
that don't make us happy.
Let's try doing things the immutable way.
So in an immutable world, my array, my zoo,
once I've created it, it just sits and is
forever.
I cannot change it.
What I can do if I want a new zoo that's more
exotic is I can make a copy that's the same

Chinese: 
谁做的？
因此，不变性有两个问题。
我们必须管理谁在改变什么，
什么时候-谁在放哪些动物
动物园。
我们必须管理很多开销
这种状态，这让我们头疼
个人和团队。
我们还会在代码中出现错误，因为也许
我只是在计划-或者我的同事是
仅计划-处理陆地生物
也没有外星人的案件
对于，那打破了一些东西。
所以这些是不变性的一些副作用
那不会让我们开心。
让我们尝试以不变的方式做事。
所以在一个不变的世界里，我的阵营，我的动物园，
一旦我创建了它，它就可以坐着
永远。
我无法更改。
如果我想要一个更多的新动物园怎么办
异国情调是我可以复制相同的副本

English: 
size as my original array, and I can make
the modification I want, so I can put my alien
in there in place of the rabbit.
And so this is pretty sweet because now my
co-worker is maybe, and they're, like, whoo,
nothing broke in my program, and it's all
still animal creatures but I had to copy over
that whole array.
I had to allocate the space for that entire
array, even all of the stuff that didn't change.
I had to copy all of that over, as well.
So this means that my code runs pretty slow.
And it also takes up a lot of memory.
It takes up a lot of space and time.
The complexity on those things are bad because
copying is a waste of both time and space.
It makes us sad face!
We don't want that.
So if we want to do immutability, we must
be able to find a better way of doing that.
Luckily for us, a lot of very smart folks
have been thinking very hard about this problem

Chinese: 
大小与原始数组一样，我可以制作
我想要的修改，所以我可以把我的外星人
在那里代替兔子。
所以这很不错，因为现在我的
同事也许是，他们就像，哇，
在我的程序中什么都没有中断，仅此而已
仍然是动物，但我不得不复制
整个阵列。
我必须为整个空间分配空间
数组，甚至所有不变的东西。
我也必须全部复制。
因此，这意味着我的代码运行得很慢。
而且它还占用大量内存。
它占用大量空间和时间。
这些事情的复杂性不好，因为
复制是浪费时间和空间。
它使我们悲伤的表情！
我们不想要那个。
因此，如果要实现不变性，我们必须
能够找到一种更好的方法。
对我们来说幸运的是，很多非常聪明的人
一直在认真思考这个问题

Chinese: 
有一阵子，他们想出了一些办法
关于我们如何应对的非常好的解决方案
具有不变性。
不变的数据结构！
因此，不变的数据结构是一个术语，
您可能已经听说过
编程，或者就React而言
他们派上用场了。
从技术上讲，不变的数据结构是
就像石头一样，它就坐着，一旦你
创造它。
它永远不会改变。
但是也可以听到术语持久数据结构
猛撞。
有时这些可以互换使用，
但它们的含义略有不同。
因此，如果不可变数据是永远不变的数据，
持久数据是我们拥有的数据
访问旧版本。
因此，由于我们一直在创建新的修改版本
我们的数据结构中，我们保留了旧版本
周围。
您可能听说过部分持久性
可以看旧的数据结构
版本，我们可以访问它们，但不能
返回并更新其中任何一个。

English: 
for a while, and they've come up with some
really good solutions for how we can deal
with immutability efficiently.
immutable data structures!
So immutable data structures is a term that
you may have heard about, with functional
programming, or also in terms of React where
they come in handy.
Technically, an immutable data structure is
like the rock, it just sits, and is once you
create it.
It never changes.
But also hear the term persistent data structures
banged about.
Sometimes these are used interchangeably,
but they have slightly different meanings.
So if immutable data is data that never changes,
persistent data is data for which we have
access to old versions.
So as we've been creating new modified versions
of our data structures, we keep the old versions
around.
You might hear about partially persistent
data structures where we can look at the old
versions, we can access them, but we can't
go back and update any of them.

Chinese: 
我们可以更新的是最新版本
我们有。
然后您可能还会听说完全持久
我们可以实际计时的数据结构
旅行，我们可以回去更新我们的任何
过去的版本。
如果这开始像敲钟一样
它是像git这样的版本控制，
同样的想法。
因此，我们将这些称为持久性
不变的数据结构，它们都是持久的，
并且一成不变。
让我们看看它是如何工作的。
所有这些的关键是我们想要旧的
我们的数据版本，例如我的原始动物园
留在原地。
我们只是想像岩石一样坐着，但是我们
希望有效地创建新版本。
因此，我们必须使用哪些魔术技巧，
像，做到这一点？
我们是否必须召唤跳舞
时空之神的复杂性？
没有。
非常简单。
树木和共享。
那不甜吗？

English: 
All we can update is the most current version
that we have.
And then you might also hear about fully persistent
data structures where we can actually time
travel, we can go back and update any of our
past versions.
And if this is starting to ring a bell like
it's version control like git, it's sort of
the same idea.
So we're going to talk about these as persistent
immutable data structures, they're both persistent,
and immutable.
Let's see how this works.
The key to all of this is we want the old
versions of our data, like, my original zoo
to stay put.
We just want to to sit like the rock but we
want new versions to be created efficiently.
So what magical tricks do we have to use to,
like, make this happen?
Do we have to make invocations do dances to
the gods of space and time complexity?
No.
It's very simple.
Trees and sharing.
Isn't that sweet?

Chinese: 
这两个简单的概念将使我们高效
不变的数据。
怎么样？
所以我们来谈谈树木，因为树木在摇晃
不幸的是，也很难替代
对不起，我没有这首诗。
想象一下，我们可以找到一种表示方式
我们的动物园像一棵树。
所以我可以做的一件事就是我可以把所有
我所有的动物-我所有的价值观-在
一棵树的叶子，我可以做到
每片叶子拥有一种价值，一只动物。
但是他们可能会变得寂寞，所以让我们把它们
和一个伙伴。
让我们把它们放2x2。
所以我们的每一片叶子都有两个值
我们希望朋友们相处融洽
而不是彼此-看着你，
老虎，六号，不要吃考拉，
我们可以上升到中间节点
直到我们到达整体的根节点
结构，现在根是一个表示的数组
以前是一棵树。

English: 
These two simple concepts will get us efficient
immutable data.
How?
So let's talk about trees because trees rock
pretty hard, as well, alternative, unfortunately
I don't have a poem for that, sorry.
Imagine that we could find a way to represent
our zoo array as a tree.
So one thing I could do is I could put all
of my animals -- all of my values -- in the
leaves of a tree, and I could make it so that
each leaf holds one value, one animal.
But they might get lonely, so let's put them
with a buddy.
Let's put them 2x2.
So each of our leaves will have two values
and we'll hope that the buddies get along
and not each each other -- looking at you,
tiger, number six, don't eat that koala, and
we can go up to intermediate nodes up and
up, until we get to the root node of the whole
structure, and now that root is an array represented
previously by a tree.

English: 
So this is my tree now in this structure.
So given this type of structure, how do we
update something?
Given that my data is immutable, and it can
never change, how can I handle the fact that
it has an alien in it.
So here what I would do is I would take the
node that contains the value that I want to
change.
So in this case it would be the 0/1 node that
you see on the bottom of the screen.
And so I make a new copy where I've still
got my monkey but I've changed the rabbit
to an alien.
And then I need to copy any of the intermediate
nodes in the tree that were pointing to the
node that I changed.
So I basically trace a path up towards the
root of the tree, which, now, I've got a new
root, which means another version of the data
structure.
So this technique of making this update by
copying the path from the leaf I changed to
the root is called path copying.

Chinese: 
所以这是我现在的树。
因此，鉴于这种类型的结构，我们如何
更新一些东西？
鉴于我的数据是不可变的，并且它可以
永不改变，我该如何处理
它里面有一个外星人。
所以在这里我要做的是
包含我想要的值的节点
更改。
因此，在这种情况下，将是0/1节点
您会在屏幕底部看到。
所以我仍然在新位置
有我的猴子，但我换了兔子
给外星人。
然后我需要复制任何中间
树中指向节点的节点
我更改的节点。
所以我基本上可以找到一条通往
树的根，现在，我有了新的
根，表示数据的另一个版本
结构体。
因此，通过
从我更改为的叶子复制路径
根称为路径复制。

Chinese: 
那很酷，因为现在我没有
复制整个数组；我只需要复制
从根到节点的途中的节点
我改变的叶子。
因此，如果我们已经将线性关系
复制到对数中。
这很酷，性能更高，
数据是所有这些
这里的节点是黄色的，所以大部分树
在两个版本之间共享
旧版本和新版本。
因此，这为我节省了很多空间，因为
我实际上可以重用原始的部分
版本没有变化，而以前
我也必须复制这些内容。
所以这意味着以前的情况
很多内存消耗变得很多
较小，因为您不必存储为
如果没有改变，可以复制很多东西。
这就是所谓的结构变更，因为
我们之间共享树的结构
两个版本。
所以我们一直在谈论更新事物
但是我们如何获得数据中的值

English: 
That's pretty cool because now I didn't have
to copy the entire array; I just had to copy
the nodes on the way from the root to the
leaf that I changed.
So if we've turned in something linear and
copying into something logarithm.
That's pretty cool, that's more performant,
and the data of this is that all of these
nodes in yellow here, so most of the tree
is shared between the two versions, between
the old version and the new.
And so this saves me a lot of space because
I can actually reuse the parts of the original
version that didn't change, whereas, before,
I had to copy those over, as well.
So this means that what was before, like,
a lot of memory consumption becomes a lot
smaller because you don't have to store as
many copies of the things if they didn't change.
And that's called structural changing because
we're sharing the structure of the tree between
the two versions.
So we've been talking about updating things
but how do we get at the values in our data

English: 
structure?
How do we access them?
Well, it turns out this isn't just a tree,
it's a special type of tree called a TRIE
tree, which originally came from the world
"retrieval," so people could, I guess, call
it tree, which is funny because we also call
TREE trees, so we can call them "tries" if
we want.
So a try is a type of tree, where the leaves
represent the values, and the paths to the
value are the keys that that data is associated
with.
So often you see TRIEs with values stored
as keys.
So, for example, if I have T stored as a key,
what I do to get to the T is I trace the tree
one letter at a time.
Then I go to T, and then to E, and then to
EA, is my key, and then my value there is

Chinese: 
结构体？
我们如何访问它们？
好吧，事实证明这不仅仅是一棵树，
这是一种叫做TRIE的特殊树种
最初来自世界的树
“检索”，所以我猜人们可以打电话
它是树，这很有趣，因为我们还称
树木，所以我们可以称它们为“尝试”
我们想要。
所以尝试一下是一棵树，那里的叶子
代表值，以及通往
值是与数据关联的键
用。
因此，通常您会看到带有存储值的TRIE
作为键。
因此，例如，如果我将T存储为密钥，
我要做的就是追踪树
一次一封信。
然后我去T，然后去E，然后去
EA，是我的关键，然后我的价值就是

English: 
three.
Because everything at the end sounds like
"ee" in this talk.
So this is pretty cool, but in our data structure,
we weren't using words, we just wanted an
array-type thing, we wanted indeces, right?
So the insight here is if we treat the index
as a binary number, then we can pretend that
that's kind of, like, our word and we can
descend the tree, bit-by-bit as if each representation
of our binary representation is a letter.
So let's see how that works.
If I'm trying to get at item five in my array,
so the animal at index five, I'd convert that
to binary, so that's one, zero, one, and then
I step through that as if it was a word.
I step through it letter-by-letter, bit-by-bit.
So I go from the root to the branch.
I have a choice of either zero or one.
I go to branch one first.

Chinese: 
三。
因为最后的一切听起来像
在本次演讲中的“ ee”。
所以这很酷，但是在我们的数据结构中，
我们没有使用文字，我们只是想要一个
数组类型的东西，我们想要索引，对吗？
所以这里的见解是我们是否处理索引
作为一个二进制数，那么我们可以假装
就像我们的话，我们可以
像每个表示一样逐位下降树
我们的二进制表示形式是一个字母。
因此，让我们看看它是如何工作的。
如果我想获得阵列中的第五项，
因此，索引为5的动物将转换为
到二进制，所以是一，零，一，然后
我一步一步地仿佛是一个单词。
我一步一步地逐个字母地介绍它。
所以我从根到分支。
我可以选择零或一。
我先去一个分支。

English: 
And then I go to branch zero, and then I take
the thing on the one side.
So I go one, zero, one, down my tree and then
I end up at my frog at index five.
So this is a pretty simple insight but it
ends up being incredibly powerful because
it allows us to quickly traverse this tree
structure, which lets us use that structural
sharing to more efficiently represent our
new copies of our immutable data structure.
And, importantly, we don't have to be using
a binary tree, meaning we have two branches
from each node.
That fits pretty well on a slide, but actually
what you mostly see is a 32-way branching.
So in our trees that we've been looking at,
we've kind of had one bit of information per
level.
And we've been descending bit-by-bit but if
we had a 32-way branching tree, it would be
five bits of information that we would be
representing at each level.

Chinese: 
然后我去零分支，然后我拿
一方面。
所以我沿着树走一，零，一
我最终在索引5处掉了青蛙。
所以这是一个非常简单的见解，但是
最终变得非常强大，因为
它使我们能够快速遍历这棵树
结构，让我们使用该结构
分享以更有效地代表我们
我们不变数据结构的新副本。
而且，重要的是，我们不必使用
一棵二叉树，意味着我们有两个分支
来自每个节点。
非常适合幻灯片，但实际上
您最常看到的是32向分支。
因此，我们一直在观察树木，
我们每一种都有一点信息
水平。
而且我们一直在逐位下降，但是如果
我们有一棵32向分支树
我们将获得的五点信息
代表每个级别。

Chinese: 
这样看起来像这样。
如果我们有更大的数字，例如18,977，
在二进制中，就是一堆零。
如果我有的话，这将是一棵非常深的树
一次降入它，它会
像15级深
太多，太久。
因此，如果我要在每个级别建立更多分支，
然后我可以将其分成5位
照原样字母，然后从树上掉下来
现在只有使用32路的三个级别
分枝。
所以这是如何
你的树会变深，有多大
节点将是因为如果我有
每个级别只有一点点信息
那我的节点很小。
复制很快，但我必须走了
在树上非常非常深的深处
数组。
通常，研究发现32
在深度之间是一个很好的权衡
的树。

English: 
So that would look something like this.
If we had a much bigger number, like, 18,977,
in binary, that's that bunch of ones and zeros.
This would be a really deep tree if I had
to descend into it one at a time, it would
be like 15 levels deep.
Too much, too long.
So if I'd make more branches at each level,
then I can chunk this up into kind of 5-bit
letters as it were, and descend the tree that
it's now only three levels using the 32-way
branching.
So this is kind of a tradeoff between how
deep your tree is going to be, and how big
the nodes are going to be because if I have
just one bit of information at each level
then I have really small nodes.
That's quick to copy over but I have to go
very, very deep down in the tree for a larger
array.
And generally, research has found that 32
is a pretty good tradeoff between the depth
of the tree.

English: 
So what we've seen is a bitmap vector TRIE.
That's just jargon.
We don't need to care about that.
But if you need something to Google, you can
Google that.
This is cool for array-type of things and
we have an index we want to jump there, but
what about objects?
We also want to be able to associate objects
with arbitrary keys, not just indeces, so
we want non-integers as keys, how does that
work?
So if I want a version of my data structure
where it's no longer an array but it's something
like an object where I'm associated letters
with each of my animals like M for monkey,
and P for panda, et cetera, what I can do
is I can take my keys, in this case, they're
letters, and hash them to get a number that
represents the key.
So that each key will have its own number.
They won't be in order necessarily, but that's
okay.
Objects don't have to be in order.

Chinese: 
因此，我们看到的是位图矢量TRIE。
那只是行话。
我们不需要关心。
但是，如果您需要Google的帮助，则可以
谷歌那个。
对于数组类型的东西这很酷
我们有一个索引，我们想跳到那里，但是
那对象呢？
我们还希望能够关联对象
使用任意键，而不仅是indeces，所以
我们希望非整数作为键，那怎么做
工作？
所以如果我想要一个数据结构的版本
它不再是数组，而是某种东西
就像我关联字母的对象
和我的每只动物，例如M代表猴子，
P代表熊猫，等等，我该怎么办
是我可以拿走我的钥匙，在这种情况下，它们是
字母，然后对它们进行哈希处理以获得一个数字
代表关键。
这样每个键都有自己的编号。
他们不一定会井井有条，但这就是
好的。
对象不一定要井井有条。

Chinese: 
然后我们可以使用该数字的哈希
以二进制形式像以前一样降下树。
因此，如果我想查找关联的值
使用键“ F”，我可以对F进行哈希处理，得到一些数字，
假设我有五个，例如A，B，C，D，
E，五个。
那将用二进制表示为
一，我像以前一样降下树，在这里，
为了简单起见，在
时间，双向分支树。
但是通常我们会这样做
每级32个分支。
因此，我们再次使用
我们的密钥的二进制表示形式
情况下，我们使用了哈希函数来转换
它从任意对象变成一个数字
我们得到了我们想要的动物-在这种情况下，
我们的青蛙。
凉。
这样，如果您想使用Google进行搜索
您可能将Google映射为哈希数组映射的TRIE。
这是一个以
菲尔·巴格韦（Phil Bagwell）和里奇·希基（Rich Hickey）

English: 
And then we can use the hash of that number
in binary to descend the tree as before.
So if I wanted to look up the value associated
with key "F," I could hash F, get some number,
and let's say I get five, like, A, B, C, D,
E, five.
And that would be represented in binary as
one, and I descend the tree as before, here,
for simplicity, just using a one bit at a
time, two-way branching tree.
But typically we would be doing this with
32 branches per level.
So, again, we just descend the tree using
the binary representation of our key, in this
case, we used a hash function to transform
it from some arbitrary object into a number
and we get the animal we want -- in this case,
our frog.
Cool.
So that, if you want to Google it, the thing
you could Google is a hash array mapped TRIE.
And this was a data structure parented by
Phil Bagwell, and Rich Hickey, kind of started

Chinese: 
使用它，其中许多已实现
以Clojure之类的语言来实现
高效数据。
通常有很多优化
在这些数据结构上完成以使它们
超级双面打印速度快，还有很多细节
我们不在这里介绍，但这是基本的
理念。
代表我们数据的树，结构共享
这样我们就可以重复使用尽可能多的信息
可能在旧版本和
新版本。
还有使用二进制表示的想法
我们的密钥，无论是索引还是散列密钥
降下树找到我们所要的东西
寻找。
综上所述，易变性会引起头痛。
尤其要避免这样做
函数式编程必不可少
想法是没有副作用而只有
使用不变的纯函数

English: 
using it, and a lot of these an implemented
in languages like Clojure to implement the
data efficiently.
There's a ton of optimizations that are usually
done on these data structures to make them
super-duper fast and lots of details that
we're not covering here but this is the basic
idea.
Trees to represent our data, structural sharing
so that we can reuse as much information as
possible between the old versions and the
new versions.
And this idea of using binary representations
of our keys, whether indeces, or hashed keys
to descend the tree to find the thing we're
looking for.
So to recap, mutability induces headaches.
It is to be avoided especially if you're doing
functional programming where the essential
idea is to not have side effects and only
be using pure functions that don't change

Chinese: 
除了对
输入并返回输出。
另一方面，不变性很好
因为如果我使用不可变数据，我将无法
通过使我的同事的计划混乱
她只以为是动物园的动物突然
里面有一个外星人。
但是复制是一种非常糟糕的处理方式
数据，因为它也不高效
关于时间，也没有空间。
和结构共享，使用这些树结构
-或TRIE结构，并尽可能多地共享
从一个版本到下一个版本的信息是
真正有效的方法
所以你可能在想，好吧，这些
数据结构非常酷。
但是我该怎么办呢？
我不会建造表情符号的盒子
我在这吗
不，您不必。
在JavaScript中，有一些很棒的功能
那里的图书馆可以帮助您使用这些
马上行动。

English: 
anything except do the computation on the
input and return the output.
Immutability, on the other hand, is great
because if I'm using immutable data, I can't
mess up my co-worker's program by making the
zoo she only thought was animals suddenly
have an alien in it.
But copying is a really bad way of handling
data because it is not efficient neither with
respect to time, nor space.
And structural sharing, using these tree structures
-- or TRIE structures, and sharing as much
information from one version to the next is
the really performant way to do this.
And so you're probably thinking, okay, these
data structures are pretty cool.
But what am I supposed to do with them?
I'm not going to be building boxes of emoji
here, am I?
No, you don't have to.
In JavaScript, there are some really great
libraries out there to help you use these
right off the bat.

English: 
There are various solutions but I'm going
to talk about a couple of them.
So one is called Mori.
Mori is basically a port of Clojure script
by David Nolan that allows you to leverage
the implementations of these data structures
from ClojureScript, which is the version of
Clojure which targets JavaScript from the
comfort of your vanilla JavaScript.
And it's got a bit more of a Clojure feel
to it.
A bit more of a functional language feel.
The API is functional and we're going to see
what that looks like in a moment.
But that's one thing that kind of sets this
library apart.
On the other hand, there's also Immutable.js.
This is a library put out by Facebook.
It was created by Lee Byron.
And this is a JavaScript implementation of
these data structures.
So it has a bit more of that native JavaScript
feel to it.
It doesn't have kind of the Clojure background
brought in.
And that means it's got a more object-oriented
style API, although it is still returning

Chinese: 
有各种解决方案，但我要去
谈论其中的几个。
所以一个叫做森。
森基本上是Clojure脚本的移植
大卫·诺兰（David Nolan）的著作
这些数据结构的实现
来自ClojureScript，它是
Clojure的目标是从
舒适的原始JavaScript。
而且还有Clojure的感觉
对它。
有点功能语言的感觉。
该API正常运行，我们将看到
片刻之后的样子。
但这是设置这件事的一件事
图书馆分开。
另一方面，还有Immutable.js。
这是Facebook推出的图书馆。
它是由李·拜伦（Lee Byron）创建的。
这是一个JavaScript实现
这些数据结构。
因此，它具有更多的本机JavaScript
感觉到。
它没有Clojure背景
带入。
这意味着它具有更多的面向对象
样式的API，尽管它仍在返回

Chinese: 
新版本的数据结构，而不是
改变可变结构的位置。
因此，让我们看看它们的外观。
这就是您可以使用Mori来创建内容的方式
称为向量。
向量是森的数据结构，
您可能将其用作数组类型的东西。
所以我有一个向量，我称之为A，因为
这有点像数组。
它有一个和两个。
如果我想在上面推些东西，
我要使用的功能是conj。
这是来自Clojure的Lisp语言。
我要输入的是原始A，
然后我想要的就是这种情况
三。
您会看到这创建了新的
右边的结构。
这些向量1、2和1、2、3，
它们看起来不一样，因为它们不是真的

English: 
new versions of data structures instead of
changing mutable structures in place.
So let's see what those look like.
This is how you might use Mori to create what's
called a vector.
A vector is the data structure from Mori that
you'd probably be using as an array-type thing.
So I've got a vector that I'm calling A because
it's sort of array-ish.
It's got one and two in it.
And if I want to push something onto that,
the function that I'd use is conj.
This is from the Clojure called, Lisp-speak.
And what I would put in is the original A,
and then what I want, which is, in this case,
three.
And you'll see that this creates this new
structure on the right.
These vector, one, two, and one, two, three,
they look different because they're not really

Chinese: 
JavaScript数组虽然可以转换
来来回回。
但是重点是这个cong函数返回
我可以捕捉为A2和我的新值
可以向我证明我原来的A没有
通过使用count函数进行更改以查看
里面有多少东西。
而且其中只有两件事。
但是我可以证明我的版本A2具有
第三件事，尝试通过使用
尝试获取两个的get函数，其中
它告诉我，确实是三个。
这与您将使用的东西相同
在Immutable.js中。
在这里，您将使用Immutable.js.list.of，即
有趣的语法。
但是它创建了更像JavaScript的东西
数组。
尽管它不是数组，但它是一个JS列表。
那我叫一个数组，如果我想添加
在A的新版本中使用的内容
我们使用的一种点方法符号
至。

English: 
JavaScript arrays although you can convert
back and forth.
But the point is this cong function returns
a new value which I can catch as A2 and I
can prove to myself that my original A didn't
change by using the count function to see
how many things are in it.
And there's only two things in it.
But I can prove that my version, A2, has the
third thing by trying to access, by using
the get function to trying to get two, which
it tells me, it is indeed three.
This is the same thing that you would use
in Immutable.js.
Here you would use Immutable.js.list.of, that's
interesting syntax.
But it creates something more like a JavaScript
array.
Although it is not an array, it is a JS list.
That I'll call an array and if I want to add
something onto a new version of A, I use this
sort of dot-method notation that we're used
to.

Chinese: 
我会说a.push（3），但重要的是，
没有改变
它只是返回a的新值
我将捕获为a2，我可以证明
对我自己来说，它没有改变。
A.size告诉我是两个，如果我尝试
得到索引2的项目，我发现它是
三，正如我所料。
因此，类似地，对于所谓的地图
是我们可能会想到的键值对象
正在使用，如果我创建一个对象，o，
将成为我的森哈希表数据结构，
我再次将a为1，将b与2关联，
我们看到语法有点不同
不是我们的常规JavaScript怪兽
常规JavaScript对象。
它们是超特殊的不可变数据结构，
他们需要特殊的语法。

English: 
I'd say a.push(3), but, importantly, this
is not changing a.
It's just returning a new value of a, which
I'm going to capture as a2 and I can prove
to myself that it didn't change.
A.size tells me it's two, and if I try to
get the item at index two, I find that it's
three, as I expected.
So, similarly, for what are called maps, which
is kind of the key-value object that we might
be using, if I create an object, o, which
is going to be my Mori hashmap data structure,
I'm associating a is one, b with two, again,
we see that the syntax is a little different
from our regular JavaScript beastlier not
regular JavaScript objects.
They're super special immutable data structures,
they need special syntax.

Chinese: 
因此，如果我想更改一个的值
我的钥匙，我可以使用这个asoc函数，
然后在我的新商品中更改三的值
版本o2，然后我可以向自己证明
通过使用
获取功能以确保原始
一个-o是1，而o2中的a是3，
正如我所期望的。
在Immutable.js中看起来非常相似
除了结构称为map而不是hashmap之外，
我可以传入一个JavaScript对象
它给了我一点点，更多
JavaScript语法比我们惯用的。
这有点语法，感觉
您可能已经习惯了JavaScript编程，
我可以在o上使用set方法来创建一个
新版本，其中a现在是3，我可以
在我的旧版本o上使用get方法，并且
我的新版o2向我证明
旧的没有改变。
因此，这些实际上是不可变的数据结构。

English: 
And so if I want to change the value of one
of my keys, I can use this asoc function,
and then change the value of three in my new
version, o2, and then I can prove to myself
that the original didn't change by using the
get function to make sure that a in the original
one -- o, is one, and the a in o2 is three,
as I would expect.
And it looks quite similar in Immutable.js
except the structure is called map, not hashmap,
and I can pass in a little JavaScript object,
and it gives me a little o, a little more
JavaScript syntax than we're used to.
This has a bit more of a syntax and feel that
you might be used to from JavaScript programming,
I can use the set method on o to create a
new version where a is now three, and I can
use the get methods on my old version o, and
my new-version o2 to prove to myself that
the old one didn't change.
So these are really immutable data structures.

Chinese: 
如果你试着看，它们看起来真的很奇怪
在控制台中像JavaScript一样
对象。
他们真的很有趣
因为它们具有这种复杂的树结构。
因此，我强烈建议您尝试这些
图书馆，看看有什么适合您的。
我可以很简单地告诉你
我在这里没时间了，他们如何比较
基本上，森也是来自Clojure
世界，这是ClojureScript。
但是Immutable.js具有更多的o.get（）
如果你很舒服的话
这样写JavaScript。
但是，对我来说，这给了我一点点
那里的认知失调是因为
看起来我们正在用那些东西
电话-我们不是-但是对我来说，获得更多
进入函数式编程的思维方式
我更喜欢Mori的函数式编程
因为它达到了我们构想的方式
东西作为输入，而不仅仅是输出。

English: 
They look really weird if you try to look
at them in the console just as JavaScript
objects.
They're really fun to kind of poke down into
because they have this complicated tree structure.
So I highly recommend that you try out these
libraries and see what works for you.
I can tell you really just briefly before
I run out of time here, that how they compare
is basically, again, Mori is from the Clojure
world, it's ClojureScript.
But the Immutable.js has more of the o.get()
kind of feel to it, if you're comfortable
writing JavaScript like that.
However, for me, it gives me a little bit
of a cognitive dissonance there because it
looks like we're mutating things with those
calls -- we're not -- but for me, to get more
into the mindset of functional programming,
I prefer the functional programming of Mori
because it gets to the way that we conceive
things as inputs and not just outs.

English: 
We don't want to be in the mindset of making
changes in place to objects.
There's also some minor performance differences
between the two, Mori is a bit faster, and
Immutable.js is a bit smaller.
But they're both great options, try them out,
and I hope one of them works for you.
So that's my talk.
I hope it's been useful.
Go forth and don't mutate your data!
Here's some references for you.

Chinese: 
我们不想成为制造的心态
更改对象的位置。
也有一些小的性能差异
两者之间，森的速度更快，并且
Immutable.js较小。
但是它们都是不错的选择，尝试一下，
我希望其中之一能为您工作。
这就是我的话题。
我希望它会有用。
继续，不要变异您的数据！
这里有一些参考资料供您参考。
