字幕列表 影片播放 列印所有字幕 列印翻譯字幕 列印英文字幕 [Applause] [掌聲] Hi! 你好! First of all, 首先 I just want to give a big shout-out to the organizers of this conference. 我只想向這次會議的主辦單位表达致意 I feel like this has been a fantastic smooth experience from start to finish, 我覺得從開始到尾, 這都是非常棒的體驗 so... 所以 [Applause] [掌聲] Amazing job. 真棒 Hi! I'm Anjana Vakil. 大家好!我是Anjana Vakil I am an English teacher turned computational linguist 我是一名英語老師 後成為計算語言學家 turned software developer 然後再轉為軟件開發人員 and as I mentioned a little bit earlier today, 正如我剛才提到的 about six months ago, I knew nothing about functional programming 大約六個月前, 我對函式編程一無所知 and very little about JavaScript. 只略知小許JavaScript So, what I want to do today is kind of 今天想做的 take you guys along on some of the things I've learned 帶你們走一遍 看看我學過的東西 about doing functional programming in JavaScript 關於使用JavaScript進行函式編程 and I am not an expert in any of this, 我不是這方面的專家 so this is going to be me taking you along on my learning journey 所以這將是我帶你們 一起走過我的學習旅程 and nothing more. 僅此而已 I'm going to try and save a little time for questions at the end, 到最後,我會盡量擠出一些時間 來回答一些問題 but we'll see how that turns out. 看看等下如何吧 So, how did I end up standing here 那 我為什麼會站在這 talking to you guys about functional programming in JavaScript? 與你們分享有關JavaScript函式編程? About six months ago in the fall of 2015, 大約六個月前, 在2015年秋季 I went to a programming community in New York City 我去找了紐約的一個編程團體 called The Recurse Center 叫做 The Recurse Centre which quick plug 它的快宣傳會 is probably the best programming community I've ever experienced 應該是我參加最棒的一個編程團體經驗 and it's a programming retreat 是個編程退修會 where you can go and learn about 你可以去那裡學習 whatever is interesting to you in the world of computer science 在計算機科學界對你來說有趣的事 and so I got there 所以我到了那裡 and a lot of people were talking about functional programming, 很多人在談論函式編程 functional programming, Haskell, Clojure, all this cool stuff, 函式編程,Haskell、Clojure, 所有這些很棒的東西 a lot of people were working in JavaScript getting into node 很多正在使用JavaScript的人開始進入節點 and these were some really interesting topics 這些都是一些非常有趣的話題 and so I started talking to people there 所以我開始和那裡的人聊了起來 and finding out what is all this stuff. 想知道這些東西是什麼 So, what is functional programming? 那函式編程是什麼? Few different ways that question can be answered. 這個問題可以用幾種不同的方式回答 First of all, it's a programming paradigm. 首先,這是一個編程範例 Some other paradigms are like imperative programming 其他範例包括命令式編程 where you say do this and then do that 像是一直說 做這個 然後做那個 or object-oriented programming 或面向對象的編程 which maybe a lot of you write object-oriented JavaScript 也許你們當中很多人 編寫了面向對象的JavaScript where you have objects and they have methods on them 你有對象, 而它們上有方式 and you change them, etc., etc. 然後你更改它們 等等 Functional programming is also a paradigm 函式編程也是一種範式 where functions are king 函式為王 and we'll talk about what that means in a little bit. 我們稍後會討論 這意味著什麼 It's also a style of coding, 這也是一種編碼風格 of organizing your code, 組織代碼 writing your code, 編寫代碼 style of approaching projects 接近項目的風格 and really more than that it's kind of a mindset you can get into, 不僅限於此, 是個可進入的一種心態 a way of thinking about a problem, 一種思考問題的方式 a way of approaching a task 一種接近任務的方式 and it's also a really sexy trend 這也是一個非常有趣的趨勢 with lots of buzzwords that'll make you super popular 有很多流行詞 when you're talking with people at the pre-conference party or whatever it is. 當會前聚會時與人交談或其他場合 會讓你超受歡迎 No, just kidding. 我開玩笑的 But it is something that's gotten a lot of attention 但這引起了很多關注 and, so yeah, I thought it was important 所以我認為這是很重要的一點 to find out why everybody was so excited about it. 去找出每個人都對此 感到如此興奮的原因 So, why do functional programming in JavaScript specifically? 為什麼要專門使用JavaScript進行函式編程呢? Well, I don't know about for all of you, 我不知道你們是否有相似經驗 perhaps more experienced JavaScript developers, 也許對更有經驗的JavaScript開發人員 but when I started learning JavaScript 但我開始學JavaScript時 having had some object-oriented programming experience with Java, C-Sharp, 有些面向對象編程經驗在Java,C-Sharp that kind of thing, 那些東西 I found object-oriented JavaScript super confusing, 我發現面向對象的JavaScript 非常令人困惑 prototypal inheritance, how does that work? 原型繼承, 如何運作? How many of you guys, quick show of hands, 你們當中幾個人, 舉舉手來看 have ever run into a bug or a problem or something unexpected with this, 誰曾經遇到過錯誤, 問題或意外情況 doing something... 做某事... Yeah, exactly. Right? 是咯,對吧? So, I found that really tricky and confusing 我發現那確實很棘手和令人困惑 and so I thought, all right, I know I want to get more into JavaScript 所以我想,好吧, 我知道我想進一步了解JavaScript but let me set aside the object orientation 但讓我放開對象方向 and try to think about things in a functional way 嘗試用函式去思考問題 which is maybe simpler in some ways 在某些方面可能更簡單 and avoid some of these problems 而避免其中一些問題 like bugs introduced by binding this to the wrong thing. 因為把這與錯的東西綁定 而造成了錯誤 So, functional JavaScript to me at least is a bit safer, 因此至少對我而言 函式JavaScript更安全一些 a bit less tricky, 沒那麼棘手 a bit easier to debug 比較容易調試 but easier to maintain as you're building a project 但在構建項目時 更易於維持 and we'll take a look at some of the features 我們稍後會看一些功能 that make that easier in a bit. 會變得容易 Also, there is already a huge community of developers 而且,已經有一個龐大的開發者團體 who are doing JavaScript in a functional style, 他們以函式風格編寫JavaScript so there's a lot of libraries out there 外面很多程序庫 to help you write functional JavaScript. 幫助你編寫函式JavaScript There's a lot of people out there that are experts in this, 有很多人是專家 for example, there was a talk in the next room over earlier today on Ramda 例如,在隔壁庭有個 關於Ramda的演講 and there are people here you can talk to 這裡也有人可以與你交談 that probably know a lot more about functional JavaScript than I do, 而他們可能會比我 更加了解函式JavaScript but the point is there's already a community, 但關鍵是已經有一個團體 so this isn't necessarily something you'd be doing on your own, 所以這不一定需要你憑一己之力完成的事 grappling you versus JavaScript, 與JavaScript搏鬥 there's other people to support you, 還有其他人支持你 which I found really helpful. 而我發現這真的很有幫助 Okay. 好的 So, hopefully by now I've convinced you 希望到現在我已經說服了你 that functional programming is at least interesting 函式編程至少有趣 and that we could do it in JavaScript to avoid these headaches, etc. 並且我們可以使用JavaScript來編 How can we do it? 我們要怎麼做? What does it mean? 這是什麼意思? This is what I was asking myself. 這就是我在問自己的問題 So, the main thing 最主要的 and maybe it sounds like a tautology or obvious is that 也許聽起來像是重言式或顯而易見的是 in functional programming 在函式編程中 you want to do everything with functions, 你會想用函式來做所有事情 so we want to express everything in our program in terms of functions. 所以我們想用函式來表達 程序中的所有內容 And a function of course is just something 當然,函式只是一個 that takes an input and gives an output. 接受輸入並給出輸出的東西 So, we want to be thinking about 所以 我們要想的是 kind of the flow of data of inputs and outputs through the program, 程序輸入和輸出的數據流的種類 instead of thinking about objects and how they interact 而不是考慮對象及其相互作用 and how they manipulate 以及它們如何操縱 or thinking about steps in a recipe like in an imperative style. 或想食譜上的步驟 比較命令式的步驟 Here we're really thinking about how we can express everything 在這,我們在考慮如何表達這一切 in terms of functions, 以函式來說 taking inputs, giving outputs. 接受輸入,提供輸出 So, for example, 舉例說 this would be a non-functional way for me to get the text 這將是一種非函式性的方式取得文字 “Hi, I'm Anjana” to appear on the screen. 屏幕上出現 “嗨,我是Anjana” I could assign a variable, I call it “name” 我可以分配一個變量 我稱之為“名稱” and have it store the text “Anjana.” 並存儲文字 “Anjana” I could have a greeting like “Hi, I'm” or “Hello, I'm”, whatever, 我可以有個招呼, 例如 “嗨,我是” 或 “你好,我是”,什麼的 and then I could log that to the console. 然後將其記錄到控制台 This is sort of an imperative style. 這是一種命令式風格 First do this, then do that, then do this other thing, 先做這,後做那,再後做這其他的 we don't have functions here, 這裡沒有函式 we're not expressing this in terms of how inputs are transformed into outputs. 我們不是在以 如何輸入會轉換為輸出 來表達這一點 So, maybe a more functional way of doing the same thing 也許是一種更實用的方法來做同樣的事情 and this is a really simple example, just for the sake of it, 這是一個非常簡單的例子 is to define a function called greet 是定義一個叫做greet的函式 which takes a parameter name 帶有參數名稱 and returns a string which adds “Hi, I'm” 並返回一個字串, 其中添加 “嗨,我是” to the beginning of that name. 到該名稱的開頭 So, for example, if I type greet, 舉例來說, 如果我輸入greet the string Anjana, 字串Anjana feeding that as input 作為輸入 then I get the output “Hi, I'm Anjana”, 然後我得到輸出 “嗨,我是Anjana” that's a more functional way expressing this in terms of functions. 這是一種從函式上 表達此函式的方法 Okay. So, another... 好,所以... maybe the main thing about functional programming 也許關於函式編程的主要問題 is to avoid side effects 就是避免副作用 and instead to use pure functions. 而是使用純函式 So, what does that mean? 那是什麼意思呢? A side effect is anything that a function might do 副作用是函式可能會做的任何事情 that isn't computing its output from the inputs you've given 沒有在用你的輸入 來計算它的輸出 and returning that output. 以及返回該輸出 So, for example, 例如 printing something to the console is not returning an output, 在控制台上打印一些內容 不是返回輸出 it's doing something else, 它在做其他事情 something that's on the side of the function 函式副面的東西 or if you have a function that uses some globally defined variable 或者如果你的函式使用一些全局定義的變量 to compute its output 來計算其輸出 that doesn't depend only on the input to that function, 這不僅僅取決於該函式的輸入 so that's not pure. 所以那不是純的 It's taking something from outside the function 它從函式外部獲取了一些東西 and involving it in some way in what the function does. 並以某種方式將其 包含在函式的功能中 So, this is just a really quick explanation of what a pure function 那只是對什麼是純函式的快速解釋 that avoids side-effects would do. 可以避免副作用就好 For more information on that 有關更多信息 there's excellent Wikipedia articles on these sorts of things, Wikipedia上有很多關於這類事情的文章 but basically the idea is that 但基本上 you want your function to do nothing 你想要你的函式什麼都不做 except take its input, use that and only that 除了接受輸入, 僅使用那個輸入來 to compute an output 計算輸出 and then return it. 然後返回 That's pure. 那才是純的 So, for example, this function here, 例如,此函式 we have this globally defined variable name 我們有這個全局定義的變量名 which gets used in the function 會在函式中使用 as you can see in the last line there, 你在這 最後一行所看到的 it gets used, so there's no input, 它被使用了,所以沒有輸入 we don't have name as an argument to this function, 我們沒有名稱作為此函式的參數 it's just reading something in from the global state. 它只是從全局狀態中 讀取一些信息 That's not pure. 那不是純的 Also, not pure because 它不純的原因是因為 the return value of this function here isn't what we care about, 而這個函式的返回值不是我們所在乎的 we care about doing something, 我們在乎做某事 changing the world in some way 以某種方式改變世界 other than the return value, 除了返回值 in this case, printing to the console. 在這種情況下, 打印至控制台 So, this is a not pure function here. 這不是一個純函式 A pure function might look like this. 一個純函式可能會長這樣 Here we have, 在這裡 the only thing that matters 對此輸出唯一重要的 to the output of this function is its input, 是它的輸入 the argument that we pass to it 我們傳遞給它的論點 and the only thing that it does is return its output. 它唯一要做的就是返回其輸出 Okay, so I've been talking for a while now about pure functions 我好像說了很多純函式 that's because this is really like a key thing at least for me, 因為至少對我而言, 這確實是一件關鍵的事情 something I've taken as one of the key parts of functional programming 一件我當成函式編程的關鍵部分 is thinking about things as purely as possible. 就是以最純粹的方式去思考問題 Another key point would be using higher-order functions. 另一個關鍵點是 使用高階函式 So, this means functions that can take as inputs other functions 因此,這在指一些可以 納其他函數為輸入的函式 or a function that can return a function as its output. 一個可以返回函式為輸出的函數 So, basically, we're treating functions kind of as objects themselves. 基本上就是將函式本身視為對象 They can be passed to other functions. 它們可以傳遞給其他函式 You can have layers of functions within functions within functions, etc., 你可以在函式中有層層的函式 and these are what's called higher-order functions, 這就是所謂的高階函式 they come up a lot in functional programming. 在函式編程中經常出現 This is a bit of a random example, 這是一個隨機的例子 but let's say we have this function at the top here, 假設我們在這有此函式 makeAdjectifier makeAdjectifier where we give it an adjective 我們給它一個形容詞 and it returns actually a function. 它實際上給回一個函式 It doesn't return a string or a number or anything like that, 它不會給回字串,數字或類似的東西 it returns us a function 它給回我們一個函式 which adds that adjective to a string that you give it. 這會將形容詞添加到 你提供的字串中 So, for example, I can use the makeAdjectifier function 例如,我可以使用makeAdjectifier函式 feed it the input “cool” 輸入 “cool” and get a function that's called coolifier. 並獲得一個稱為coolifier的函式 So, now when I pass a string to coolifier, 當我將字串傳遞給coolifier時 I get “cool” added to that string. 該字串中就會添加 “cool” 字 So, if I pass conference, I get cool conference. 如果我寫 "會議" conference), 我會得到"很棒的會議" (cool conference ) So, the idea here is that we have a higher-order function 概念就是我們有一個高階函式 which returns a function. 給回一個函式 And this kind of wrapping your head around this 大概消化一下這個概念 at least for me 至少對於我來說 is one of the key things to being able to write in a functional style 是能夠以函式風格進行寫碼的關鍵之一 because as we'll see a bit later, 因為我們之後會看到 we need these higher-order functions 我們需要這些高階函式 in order to avoid some of the tricks 為了避免一些花招 that we're used to using from other paradigms. 我們習慣於從其他範例中使用 So, learning the thing to get into that functional mindset 想融入函式性思維要學習的 for me really involved wrapping my head around this concept. 對我而言就是 儘快熟悉這個概念 Okay. 好 So, one of these things that we're going to avoid 我們要避免的其中一個東西是 that we're used to doing is iterating, 我們習慣做的是迭代 using like “for” or “while”, these sort of things. 使用像 “for” 或 “while” 之類的東西 We're used to going over lists and doing things to all the items in it. 我們習慣於遍歷列表 並對其中的所有項目執行操作 Instead, in a functional style, 以函式風格 we might use higher-order functions like Map or Reduce or Filter 我們可能會使用高階函式, 例如地圖 (Map) 或減少 (Reduce) 或過濾 (Filter) which often take as an input 通常作為輸入 not only the list that you want to do something to in some way 不僅是某種方式做某事的列表 but also a function that then you're going to apply to it. 但也是要應用的函式 In the interest of time I'm not going to go into too much detail 為了時間的關係, 我不仔細贅述 about what Map, Reduce, and Filter do, Map,Reduce和Filter的功能 but I found and also thanks to my colleague Khalid up there, 但因為我的同事Khalid, 我找到了 a really cool graphic that I think expresses Map and Reduce pretty well, 一個很酷的圖, 適當的解釋Map和Reduce maybe you guys have seen it before, 也許你們以前看過 the MapReduce Sandwich, everyone! 大家,MapReduce 三明治! So, the idea here is that let's say you have a list, 這裡的想法是, 假設你有一個列表 in this case, a bunch of vegetables. 在這種情況下,一堆蔬菜 They're whole vegetables. 未切過的,整體的蔬菜 We got some bread in there too 這裡也有麵包 and we want to transform that data in some way. 我們想以某種方式轉換數據 So, for example, let's say we want to slice that data 舉例來說, 我們想對數據進行切片 and we have a function 'slice up' or 'cut up' or 'chop' 我們有一個 “切片” 或 “切” 或 “剁” 函式 which we can apply to each item in that list. 將其應用於該列表中的每個項目 Now, usually I would do “for vegetable in sandwich ingredients,” 通常我會用 “用於三明治中的蔬菜” do all of this, 完成這些 do all this chopping, 這些剁碎啊 but in a functional style we'd use Map, 但我們會以函式性風格使用Map give it the list of ingredients and give it the function 'chop' 給它材料列表後 給 “剁” 這個函式 and I would get out a new list where everything has been chopped. 而我就會得到一個新的列表 所有材料已經被剁碎了 Then we have a Reduce function 然後我們有一個減少 (Reduce) 函式 which basically combines all of the items in a list in a certain way, 基本上將列表中的所有項目組合在一起 in this case, layering 在這種情況下,分層 to make a delicious sandwich, 來配成一個美味的三明治 and Filter let's say 以及Filter吧 could be if you hate cucumbers, 可能你討厭黃瓜 you could have a Filter function 你可以有一個過濾 (Filter) 函式 which makes sure that 確保 only things that are not cucumbers get through the filter. 只有非黃瓜的蔬菜才能通過過濾器 So, these are the ways we use these higher-order functions 這是我們使用的方式 這些高階函式 to get around the type of “for” or “while” iteration 來熟悉 “for” 或 “while” 這類型的迭代 that we're used to doing in functional programming, 在函式編程中習慣做的 instead we're going to feed functions to higher-order functions 我們將函式提供給高階函數 like Map, Reduce, and Filter 如Map,Reduce和Filter to get the sandwich that we want. 得到我們想要的三明治 And again, this is not intended to be a totally clear explanation 重申,這並不是一個完全清楚方式 of how Map, Reduce, and Filter work, 來解釋 Map,Reduce 和 Filter 的操作 but there's plenty of information on that online. 但網上很多關於這的資料 The idea is that we want to use these instead of “for.” 我們要使用這些而不是 “for” So, another thing that we want to do is 我們要做的另一件事是 we want to avoid mutating data, |avoid mutability. 我們要避免變異數據, 避免變異 Mutation in the sense I just mean changing objects in place. 變異指在某個放置更改對象 So, when we have something that's immutable, 當我們有個不可變的東西時 I'm sure a lot of you guys are familiar with the term, 我相信很多人都熟悉這個詞 it's something data that can't be changed in place. 這是數據放置無法更改的 Once we've set it it's there forever. 一旦設置好, 它將永遠存在 It's never going to change. 它永遠不會改變 So, let's take a look at an example. 我們來看個例子 Just because for me 因為對我來說 this was another thing that required a little head wrapping. 這是另一件需要 稍微更努力理解的事 So, this would be an example of mutation which is non-functional. 這是非函式突變的一個例子 We have a rooms variable which stores a list, 我們有一個房間的變量 來存儲列表 so “H1,” “H2,” and “H3,” “H1”、“H2” 和 “H3” because that's what we thought the rooms were, 因為我們認為房間是那樣 at least that's what I thought the relevant rooms were, 至少那是我以為 相關的房間所在 and then we say no no no actually it's not “H3,” it's “H4”. 後來發覺不是的 實際上不是 “H3” 而是 “H4” So, let's replace the thing at index [2] in rooms with “H4.” 所以讓我們將房間中索引[2]處 的內容替換為 “H4” And so, then we have rooms has actually changed, 因此,我們的房間實際上已經改變 we went from [“H1,” “H2,” “H3”] 我們從 [“H1”、“H2”、“H3”] to [“H1,” “H2,” “H4”]. 換成了 [“H1”、“H2”、“H4”] So, that is still stored in the variable rooms 它仍然存儲在變量 “房間” 中 but we've actually changed something in place 但實際上我們已經改變了一些放置 and this is something that functional programming avoids 而这是函式编程避免的 because this can cause a lot of problems 因為這可以引起很多問題 and this is part of the reason why we get into trouble with this 這也是為何我們特別注意 這一點的原因之一 and with these sort of object-oriented approaches, 並通過這類面向對象的方法 sometimes you can change things in a way that you didn't intend, 有時候你可以 以意想不到的方式改變事物 so that what you thought you were dealing with 你以為你在處理的 if I thought that rooms meant [“H1,” “H2,” “H3”] 如果我以為房間意味著 ["H1", "H2", "H3"] and I didn't know that somewhere else in my code 而我不知道我代碼中的其他地方 I had replaced something in the rooms array 我已更換了房間數組中的某個東西 I could run into trouble. 我可能會遇到麻煩 I could end up introducing bugs into my code 我最終可能會在代碼中引入錯誤 and having a really hard time tracking them down 並且很難追踪它們 because rooms here is the right thing, 因為這裡的房間是對的 rooms there is the wrong thing, 那裡的房間是錯的 ah! what happened? Where did this go wrong? 啊!發生了什麼事? 到底哪裡出錯了? Oh! my God! 我的天啊! You end up crying in front of your computer. 然後在電腦面前哭 No, just me. 不是啦,那只是我 So, a better way to go about things 所以更好的方法 is to think of all data as immutable, never changing. 就是將所有數據視為不變的, 永不改變 For example, 例如 with no mutation we still have our rooms which has the wrong 即使沒有變化, 我們仍然有錯誤的房間 [“H1,” “H2,” “H3”] [“H1”、“H2”、“H3”] but instead of changing it in place 但與其改變它的位置 I'm going to make a new rooms array 我要整理出一個新房間數組 using this map function 使用此Map函式 that we talked about a little bit earlier 就是我們剛才有提到的 where I'm mapping, 我要映射的地方 I'm feeding a function into this map, 我正在向地圖中添加函式 which looks at each room in the list 它會查看列表中的每個房間 and if it's “H3”, 那如果是 “H3” oops! I have a missing = sign there, 唉!我少了個 = 符號 last-minute slides, 臨時做的幻燈片就這樣... if the room is “H3” it returns “H4” instead of “H3”, 如果房間為 “H3”, 則返回 “H4” 而不是 “H3” otherwise it returns whatever the room was. 否則返回的是房間原型 Okay. Understanding this specific example is not crucial 好,了解此示例並不重要 but the point is that once I've assigned this new rooms variable, 但是關鍵是, 一旦我分配了這個新的房間變量 new rooms has the correct values I expect “H1,” “H2,” and “H4”. 新房間有正確值 應該是 “H1”、“H2” 和 “H4” But rooms is the same as it always was, 但是房間和以前一樣 it hasn't changed at all. 根本沒有改變 So, this is thinking about rooms as being immutable, 這在視房間為不變的 we're not changing it 我們不會改變它 and that's something that's really important for functional programming 這對於函式編程非常重要 because as I said, 正如我所說 it helps you avoid a lot of headaches, a lot of bugs. 它可以幫你避免很多麻煩 很多錯誤 So, how much time do I have? 我還有多少時間? Okay. Good. 好 We have a little time to talk about persistent data structures, yey! 我們有些時間聊持久化數據結構 The problem with immutability is that 不變性的問題在於 when you're treating arrays and things like that as immutable, 當你把數組和像此的事物視為不變 what you end up doing is making new copies of everything. 你最終會做的是 製作所有內容 So, if I want to change my one room in this list 如果我想在此列表中更改一個房間 I have to make a whole new array 我必須做一個全新的數組 and when you're dealing with short little things like this 當你處理像這樣的矮小事情時 maybe that's not a big deal, 也許那沒什麼大不了的 but as your objects get bigger, more complex, 但是隨著物體變大, 越來越複雜, this can give you efficiency problems 這會帶來效率問題 because if you have to copy over everything, 因為如果你要複製所有內容 even the things that didn't change, 甚至沒有改變的事情 every time you make one little adjustment 每次你進行一個小調整 and you want to make a new copy, 你想要有個新副本 a slightly different copy of your array, 數組的副本略有不同 it takes you a lot of time, 會費你很多時間 you have to go through everything in the list to copy it over, 必須仔細閱讀列表中的所有內容 才能將其複制 you end up using a lot of space 最終會佔用很多空間 that maybe once the objects start getting bigger and bigger 也許一旦物體開始變得越來越大 becomes a problem. 就成了問題 And so, one thing that's very popular in the functional world 在函式世界中非常流行的一件事 as a way of getting around these efficiency issues 解決這些效率問題的一種方法 is to use persistent data structures. 就是使用持久化數據結構 This was something introduced sort of theoretically by Phil Bagwell, 這是Phil Bagwell從理論上介紹的 he wrote a paper called Ideal Hash Trees. 他寫了一篇名為《理想哈希樹》的論文 I can put a link in the slide to that later 之後我可以在幻燈片中放一個鏈接 and then Rich Hickey who invented the language Clojure 發明語言Clojure的Rich Hickey implemented the data structures using Bagwell's ideas 使用Bagwell的想法 實現了數據結構 to make Clojure really efficient for these immutable data structures 使Clojure對於這些不變的數據結構更加有效 and for these functional operations. 以及這些函式操作 Okay. 好 So, the way persistent data structures work if I may, 持久化數據結構操作方式 if you will indulge me, 若你們縱容我 I'm going to step back to the chalkboard right here. 我就要用這黑板 We're getting retro. Yeah, it's happening. 我們走復古型了 是的,這正在發生 Okay. 好 So, if we have like an array where we had H1, H2, H3, 如果我們有一個數組, 其中有H1,H2,H3 typically what I do in a mutable world is just get rid of this 通常我會在一個可變的世界裡 所做的就是擺脫這個 and replace it with H4, 並用H4代替 but as we said we want to avoid that. 但是正如我們所說, 我們希望避免這種情況 So, instead, if I copy it over into a new array, 如果我將其複製到新數組中 I copy H1, 我複制H1 I copy H2 複制H2 and I replace, instead of copying H3 I put in H4. 然後我替換, 不是複制H3,而是放入H4 Great! 很棒! But now I have to store two arrays, 但是現在我必須存儲兩個數組 taking up a lot of time, 費了很多時間 look how long that took me to do all of that. 看看我花了多長時間來完成所有這些 Terrible. Right? 很糟吧? I know you guys feel as upset about this as I do. 我知道你們和我一樣對此感到很不滿 I can see it in your faces. 你們的表情告訴了我 What if instead we represented this array right here as a tree, 相反的,如果我們把這個數組 表示為樹 such that each leaf node of the tree 這樹的每個葉子節點 is one of the things that I'm trying to store 是我想存的東西之一 or perhaps 2 of the things or 3 or 32 or some number of the things 或許是兩個或三個 甚至32個東西之一 and if I want to change something, 如果我想改變一些東西 I don't need to replace the entire array, 我不需要把整個數組替換掉 I can just make a new node over here, like H4, 我只需要新建一個節點,像這H4 and now I can make a new tree 我就可以做一棵新樹 which instead of repeating H1 and H2 與其重複H1和H2 I can reuse those same things and just make a new node 我可以使用同樣的東西, 只建新節點 which connects them to my new element over here, 將它們連接到這個新元素 so that now I have here a data structure which contains H1, H2 and H4 所以現在我有個數據結構 裡面包含了H1,H2 和 H4 but I didn't need to make a whole new thing. 但就是不需要重新建過 I just needed to make my one little part. 我只需要改一小部分 I can reuse the old structure of the list. 及重用列表的舊結構 So, this idea, this sort of topic is called structural sharing 這種概念或主題, 稱為結構共享 because we can share parts of the old versions with the new versions, 因為我們可以與新舊版本 共享某些部分 so we have much more efficient operations for adding, 使我們有更高效率地進行添加 changing things or moving things from vectors, for example, or arrays 從矢量或數組 更改或移動事物 and this can also be done for maps, for hash maps that sort of thing 這也可以用於地圖,哈希地圖之類的事情 and it basically makes the world of functional programming bust wide open 基本上使函式編程世界展開 so that we don't have to go through these long time 所以我們不需浪費時間 and expensive space operations 和昂貴的空間運作 to update our immutable data all the time. 去一直更新我們的不變數據 So, to do this in JavaScript, 所以,要在JavaScript中做到這一點 there are a couple of libraries that are really popular. 有幾個非常受歡迎的程序庫 One which I like to use is called Mori 我特比喜歡Mori which I'll show you the link for in a little bit 一會兒把鏈結給你們看 which actually uses ClojureScript 它其實使用ClojureScript which has these type of data structures natively, 本身俱有這類數據結構 it ports them over to JavaScript, 後將它們移植到JavaScript so you can use them right from JavaScript 直接從JavaScript使用它們 and it's great. 這很棒 It has a lot of also like general functional programming helpers 它也有很多通用 函式編程的助手 like Map and Reduce and lots of other things. 例如Map和Reduce 以及許多其他東西 There's also another popular library called Immutable.js 還有一個出名的庫叫做Immutable.js which Facebook put out 是Facebook推出的 which is JavaScript through and through. 就是完完全全的JavaScript I haven't worked as much with that 本身沒什麼經驗 but I know a lot of people like that as well. 但我知道很多人也喜歡它 And yeah, so these are ways 是的,所以這些是 you can try out using these immutable data structures 你可以嘗試使用的 不變的數據結構 if that is something you feel like you can't wait to do now. 如果你覺得迫不及待了 I know. 我理解 I can just feel the excitement. Yeah, that's great. 我能感覺到你們的興奮 是的,太好了 Okay. Moving on. 好,我們繼續 If you're ready to try it out, 如果你準備好嘗試 like I said, we have Mori and Immutable.js, 如我所說, 我們有Mori和Immutable.js links there to those libraries. 那些庫的鏈結 There's also a lot of utility libraries 還有很多實用程序庫 which don't focus so much on this persistent data structure thing, 不會太注重此持久化數據結構 but instead give you a lot of helper functions like Map, Reduce, etc. 反而給你很多幫助函式 例如Map,Reduce等 So, Underscore, Lodash, for example. 例如Underscore,Lodash Today I found out that Ramda is a thing 今天我發現Ramda是一回事 because there was a talk on it the other day 因為前幾日有個關於Ramda的演講 and there are many more. 還有更多 And in fact, JavaScript has some built-in functions, 實際上,JavaScript 具有一些內置函式 like for example, arrays have a built in Map, Reduce functions. 例如,數組具有 內置的Map,Reduce函式 So, a few slides ago we saw this rooms.map, 幾張幻燈片之前, 我們看到了這 room.map that's because the array prototype has these functions Map, Reduce, etc. 這是因為數組原型具有 這些函式Map,Reduce等 So, you can even do some functional programming in pure vanilla JavaScript 你甚至可以使用純JavaScript 進行一些函式編程 without using any of these libraries. 無需使用任何程序庫 Okay. 好 So, if you are sitting there thinking, 如果你坐在那 想著 What? Huh? I didn't really get that something about immutability, 什麼? 我並沒了解不變性 side effects, pure functions. What now, huh? 副作用,純函式 現在呢? If you want to learn a bit more about all these buzzwords, 如果你想進一步了解 所有的這些流行詞 like I said, all these sexy buzzwords 就像我說的, 所有這些吸引的流行詞 that I've been throwing at you for the last 20 minutes, 也是我過去二十分鐘一直向你扔的詞 I highly recommend a nice gentle introductory article called 我極力推薦一篇不錯的介紹文章 名為 “An introduction to functional programming” “函式編程簡介” by Mary Rose Cook 以 瑪麗·羅斯·庫克(Mary Rose Cook)所寫 who is a former facilitator at The Recurse Center 之前在The Recurse Center的一位促進者 that I keep talking about. 就是我一直在提的 The link is up there, 鏈接在那 but basically this is a really nice introduction 但基本上 這是一個非常好的介紹 that kind of goes into a little bit more depth 又有一些些深度 in some of the “commandments” of functional programming 對於函式編程的一些 “戒律” that I've mentioned today. 我今天也提到的 So, if you are a little intrigued 如果你有點好奇 but not quite clear on this stuff that I've been mentioning, 但在我有提到的東西上並不清楚的 I highly recommend you check it out. 我強烈建議你看看 So, I think that's it for my talk. 我猜我演講就到這吧 We have a couple of minutes for questions, I suppose, 我們應該還有幾分鐘來回答問題吧 eight minutes by my account, 大概八分鐘吧 but first of all I just wanted to say thank you guys very much. 但首先我真的很想對你們致謝 I'm Anjana Vakil. 我是 Anjana Vakil Anjana Vakil on Twitter Twitter上也是Anjana Vakil and has link there to my GitHub. 在那有我GitHub的鏈結 So, would love to keep in touch 很想保持聯繫 if anybody else is out there also learning 如果有人也在學習 functional JavaScript as a newbie like myself, 函式性JavaScript, 如我這樣的新手 definitely reach out, 歡迎與我聯繫哦 we could stick together, 可以互相支持 but first of all I want to give a huge thanks 我想特別致謝於 to again the JSUnconf organizers, JSUnconf 主辦單位 especially the diversity sponsors. 尤其是這些多元性贊助家 I'm here on a diversity ticket myself 我也是被贊助而來的 and wouldn't have been able to come without that awesome program 沒有那麼棒的議程也應該來不了 and all of you and the sponsors who sponsored those tickets 還有所有贊助商, 贊助了這些票 and also a huge huge thank you to The Recurse Center 特別特別感謝 The Recurse Center and some of the alumni there who have helped me learn all this stuff 以及幫助我學到那麼多東西的校友 including Khalid at the back there 包括後面那位,Khalid and Sal Becker, another alum, 還有另一位校友Sal Becker who explained a lot of this stuff to me 向我解釋了很多有關這的東西 over several long caffeine-fueled conversations at The Recurse Center 在The Recurse Center 經過很多談話 and if any of you are interested in spending time 如果你們有興趣花時間 on self-directed educational programming retreat in New York City 在紐約自導教育性編程修會 definitely check out recurse.com, 一定要去看看recurse.com it's an amazing community. 是一個了不起的團體 Okay, that's it for me. Thanks. 好吧,就這樣了 謝謝 [Applause] [掌聲] Thank you very much. 非常感謝你們 Yes, _____ 是的,_____ Does anybody have any questions about functional programming? 有沒有人對函式編程有任何疑問? Don't know if I'll be able to answer them but I can try. 不曉得我是否能夠回答, 但我可以嘗試 Yeah. 是 Actually, always the professors at my faculty 其實,我系的教授們 always said that object-oriented programming 總是說面向對象編程 is better than functional programming 比函式編程好 and I was thinking that is it better 我在想那會更好 or is it you think that we should use 還是你認為我們應該使用 functional programming only on JavaScript 僅在JavaScript上進行函式編程 or also on other programming languages like C _____ 或其他編程語言 例如C _____ So, I think that's a great question 我認為這是一個很好的問題 and it kind of gets into a little bit of the, 有點進入了 what I think of as kind of the philosophy of programming paradigms. 我認為這是一種編程範例哲學 So, as I was learning about functional programming 當我在學函式編程 I started even wondering what is a programming paradigm 我甚至開始懷疑 什麼是編程範例 and why do people fight about them, 人們為何要為它們爭論 why do people say object orientation sucks, 為什麼人們都說面向對像很爛 we have to do everything functional 我們必須以函式來做 and why do people say no, functional programming sucks, 為什麼人們都 嫌棄函式編程 we need object orientation. 我們需要面向對象 And the conclusion that I came to is that 我得到的結論是 no one paradigm is better or worse than other paradigms. 沒有一個範例比其他 範例更好或更糟 They just have different advantages and disadvantages 它們只是有不同的優點和缺點 and they have different situations 和不同的情況 in which they're going to be kind of the best tool 它們將成為最佳工具 for that particular problem. 來解決那個問題 So, for example, if you just want to really quickly write up a script 例如,如果你想快速地編寫腳本 that just does something on your computer once really fast, 就在你電腦上很快地做過一次 you're probably just going to do it in an imperative style, 你可能會以命令式的方式進行操作 do this, then do that, then do the other thing. 做這個,然後做那個, 然後做另一件事 If you don't need to maintain it, 如果你不需要維護它 if you just need it to happen right there, 只需要它在那發生 imperative programming is a totally legit paradigm for that. 命令式編程是完全合理的範例 If you're trying to model real world objects 如果你要建模真實物體 and how they interact 以及它們如何互動 and how they go around and things you can do, 它們怎麼運作和你能辦到的 like if you're trying to model, I don't know, 像是要建模, 我不曉得... books in a library 圖書館的書 or classes with teachers and students 或與老師和學生一起上課 and how they all interrelate that sort of thing, 以及它們如何相互關聯 maybe thinking about it in an object-oriented way makes most sense 也許以面向對象的方式 考慮它是最合理的 because that's exactly the problem you're trying to solve, 因為那就是你想解決的問題 is modeling objects 正在建模對象 and that's why that paradigm came about. 就是這種範例的來歷 But if you're trying to avoid some of those problems 但如果你想避免其中一些問題 that I was talking about 那就是我說的 when you have maybe a situation 當你可能有些情況 that doesn't actually refer to real-world objects, 並不涉及現實物體的情況 where you're using objects just because you have to 就是因為需要才用物體的那些情況 and that's introducing all kinds of side effects and weird bugs 而這會帶來各種副作用和怪異的錯誤 that are hard to track down, 也很難追踪的 maybe you want to consider thinking about it 那可能你要再考慮 in terms of functions on your data 在數據上的函式 and things being pipelined through multiple functions 通過多種函式 傳遞東西 and undergoing various transformations, 並經歷了各種轉變 not in the sense that the data is being mutated 並不是說數據正在突變 but in the sense that we're getting new outputs 然而是根據舊的輸入 based on old inputs, 我們正在獲得新的輸出 then functional programming is probably the way to go 那麼函式編程可能就是辦法 and it has a lot of advantages such as being nicely, 而且它有很多優點, 例如 you can break things down into small functions that only do one thing. 你可以將事情分解 為只做一件事的小函式 So, if you want to change something 如果你想更改某些東西 you don't have to change an entire class structure, 你不必更改整個類的結構 you can just change the one little function 只需更改一個小函式 that does the thing you want to change. 那功能就是負責做你想改的東西 So, I think it has advantages, it has disadvantages. 我想這定有它的好壞處 I definitely wouldn't say it's better than object orientation in all cases 也不會說在所有情況下 它比面向對象更好 and I definitely wouldn't say object orientation is better in all cases either, 但我也不會說在所有情況下 面向對象是更好 it really depends on your situation. 這真的取決於你的情況 Also, very good introduction of programming philosophy. 也是很好地介紹了編程原理 I used to be a philosophy major, so that might be why. 我曾經是哲學專業的, 可能是這個原因吧 Any other questions? 還有其他問題嗎? You mentioned Map function 你提到了地圖函式 and the Map function is not working, 並且Map函式無法正常工作 so do you mix it... 那你會混合嗎... Before that, I come from object-oriented programming style 之前,我比較熟悉面向對象的編程風格 and not so much into functional. 而不是過多地投入函式 That's cool too. 那也挺酷的 The professors really just test our functions 教授只是測試我們的函式 and can avoid the concurrency 也可以避免並發 that the Map function could possibly introduce. Map函式可能會引入的功能 Non-blocking and concurrency and promises 非阻塞,並發和承諾 are all things that I do not feel qualified to talk about right here. 都是我覺得我沒資格在這裡談論的 I would love to turn that question over to the audience though. 我想把這個問題交給聽眾 Anybody want to respond? 有人要回應嗎? _____ _____ Fight fight fight. 打架,打架,打架 Just kidding. 開玩笑啦 Just kidding, just kidding. 開玩笑,我只是在開玩笑 That would be against the code of conduct, you guys. 會違反規矩噢 _____ _____ I would also guess that perhaps it's blocking 我猜想 它可能蠻妨礙這裡的談話話題 but we can discuss this later in a small room or outside. 但我們稍後可以在 外面或找個小房間討論 [Laughter] [笑聲] Thank you for the conversation starter question though. 謝謝你的開話問題 Excellent question 那是個好問題 and I would love to know the answer. 我也很想知道答案 Look forward to talking you guys more. 期待與你們有更多交流 I guess... 我猜... I guess we are done with the talks, the big talks now. 我想我們今天的演講就到此了 Thank you. 謝謝大家 Thank you. - Again. 再次,謝謝 [Applause] [掌聲]
A2 初級 中文 美國腔 編程 輸出 對象 輸入 房間 數據 使用JavaScript學習函式編程(Learning Functional Programming with JavaScript - Anjana Vakil - JSUnconf) 54 2 LONGSIAN LIANG 發佈於 2021 年 06 月 02 日 更多分享 分享 收藏 回報 影片單字