# Functional Programming 都可以當你阿公了 Part 3 ###### tags: `fp` ## [Functional Programming & Haskell - Computerphile][video-1] 在早期他們在玩 Functional Programming 的時候, 只有很小部分的人散落在全球不同的大學。 在那個年代,你必須要寫自己的 Compiler。 直到有位耶魯大學的教授 [Paul Hadak][video-2], 提出大家好像都設計出類似的程式語言, 但是大家的程式碼都沒辦法共享, 何不共同出一套一致的語言,就是 [Haskell]。 特別注意到有一段問到函式編程語言的效能問題, 影片的回應是 函式編程語言幫我們處理了很多實作細節問題, 像是記憶體管理, 他確實是有犧牲部分的效能, 但現今的函式編程語言, 透過優良的編譯處理來提供好效能, 跟大部分程式語言比也不會太差。 順帶一提,有個非常好的優點是, 他在做平行運算時永遠是安全的, 因為函式沒有 side effects, 即便有好幾條運算同時執行也無所謂, 彼此之間不會互相影響。 亦即這種做法非常適合應用在當今多核心處理時代。 [video-1]: https://www.youtube.com/watch?v=LnX3B9oaKzw&ab_channel=Computerphile [video-2]: https://en.wikipedia.org/wiki/Paul_Hudak ## Intro 我們通常會希望花時間學習到的工具是有實際的應用用途的, 所以接下來我們就透過分析 國外公司 用什麼來介紹不同的程式語言吧。 ## Discord 與 [Elixir] ![who-use-elixir](https://preview.redd.it/5h3h3e6b33021.jpg?width=1170&format=pjpg&auto=webp&s=01e13d263e0b9a977b845c80fa97d5b23c4c7f58) [Elixir] 是一款運行在 [Erlang 虛擬機][BEAM]上的動態函式編程語言。 他的設計目的是為了打造出分布式高容錯的系統, 並且著重支援併發運算。 Discord 很常發布文章分享關於 [Elixir] 的文章, 在 [Discord 自己的部落格][discord-1], 以及 [Elixir 官方部落格][discord-2]都有其蹤跡, 並且對於 [Elixir] 社群有著超高的貢獻度。 Discord 在非常早期就導入 [Elixir] 並作為他們的基礎架構至今。 並且最近透過結合 [Rust], 將同時在線人數提升到 [1千1百萬][discord-3]。 關聯閱讀:[GenStage] [GenStage]: https://www.youtube.com/watch?v=aZuY5-2lwW4&t=2s&ab_channel=ElixirLondon [BEAM]: https://en.wikipedia.org/wiki/BEAM_(Erlang_virtual_machine) [discord-1]: https://discord.com/blog/how-discord-scaled-elixir-to-5-000-000-concurrent-users [discord-2]: https://elixir-lang.org/blog/2020/10/08/real-time-communication-at-scale-with-elixir-at-discord/ [discord-3]: https://discord.com/blog/using-rust-to-scale-elixir-for-11-million-concurrent-users ### 其他使用 [Elixir] 的公司像是: - [Bleacher Report](https://dev.bleacherreport.com/diving-into-distributed-tracing-ce9638025576) - [Pinterest](https://venturebeat.com/dev/pinterest-elixir/) - [Moz](https://moz.com/devblog/moz-analytics-db-free) ### Elixir 範例 https://leetcode.com/problems/add-two-numbers/ ```elixir defmodule Solution do def add_two_numbers(nil, nil, 0), do: nil def add_two_numbers(nil, nil, val), do: %ListNode{ val: val } def add_two_numbers(l1, nil, val) do %ListNode { val: rem(l1.val + val, 10), next: add_two_numbers(l1.next, nil, floor((l1.val + val) / 10)) } end def add_two_numbers(nil, l2, val) do %ListNode { val: rem(l2.val + val, 10), next: add_two_numbers(nil, l2.next, floor((l2.val + val) / 10)) } end def add_two_numbers(l1, l2, val) do %ListNode { val: rem(l1.val + l2.val + val, 10), next: add_two_numbers(l1.next, l2.next, floor((l1.val + l2.val + val) / 10)) } end @spec add_two_numbers(l1 :: ListNode.t | nil, l2 :: ListNode.t | nil) :: ListNode.t | nil def add_two_numbers(l1, l2, val \\ 0) end ``` ## 太多了 與 [Clojure] ### 公司列表 https://clojure.org/community/companies ### Stackoverflow Survey https://survey.stackoverflow.co/2022/#section-salary-salary-and-experience-by-language ### Clojure 範例 https://github.com/tainvecs/sentence-splitter ## Facebook 與 [Haskell] [Haskell] 是一種靜態強型別的純函式編程語言, 並著重於簡單跟正確性,被廣泛應用於學術領域。 #### [Sigma] Sigma 是 Facebook 用來擋垃圾訊息的系統, 他的主要工作是用來識別惡意動作, 像是垃圾訊息,網路釣魚,張貼惡意連結等。 並會將檢測到的壞內容自動刪除, 因此不會出現在你的 Facebook Posts 裏面。 特別挑出這個領域涉及: - 資料搜索 - 資料處理 - 資料分析 這類需求比較少出現在規模較小的產業跟廠商, 通常會需要這個的廠商都具有相當的規模, 資料量通常都不會小。 [Sigma]: https://engineering.fb.com/2015/06/26/security/fighting-spam-with-haskell/ ### [Haxl] 一個 Haskell 套件 方便獲取遠端資料像是資料庫或是服務。 [Haxl]:https://github.com/facebook/Haxl ## WhatsApp 與 [Erlang] ![global-messenger-usage](https://www.messengerpeople.com/wp-content/uploads/2022/10/statistic-messenger-apps-top-by-country-en-2019-09-1024x576-1.png) 基於函式編程天生適合平行運算這個特性, 它非常適合被應用在即時通訊領域。 ### [waraft](https://github.com/WhatsApp/waraft) ## Google 與 [Lisp] Lisp 是最老的函式編程語言, 他有獨特的語法跟強大的 macro 系統, 多用於 AI 跟 計算機代數。 https://www.itasoftware.com/ https://opensource.google/documentation/reference/thirdparty/lisp ## Twitter 與 [Scala] ### [Effective_Scala] Twitter 自己出的 Scala 教程 [Effective_Scala]: https://twitter.github.io/effectivescala/ ### [twitter-server] 目前正在線上運行的大部分 Twitter 的 Server 模板。 [twitter-server]: https://github.com/twitter/twitter-server ## Microsoft 與 [F#] F# 是一款運行在 .NET 環境上的強型別函式編程語言, 適合用在資料處理跟科學運算。 F# 著重型別安全,常被應用在金融應用程式。 ## 一些常見語言導入的 FP 特色 ## Java / C# https://www.scaler.com/topics/java/functional-programming-in-java/ https://ondro.inginea.eu/index.php/new-features-in-java-versions-since-java-8/ - Lambda Expressions - Functional Interfaces - Effectively Final Variables - Stream API - Optional - Method References - Interface Default and Static Methods - Collection factory - Pattern Matching - Record type ## Python https://docs.python.org/3/howto/functional.html - Lambda Expressions - Itertools - Operator - Functools ## PHP https://leanpub.com/functional-php/read - First Class Function - higher-order functions - Closures - Currying and Partial Application ## Ruby https://womanonrails.com/functional-programming-ruby - Blocks - Proc object - Lambdas - Closures - Lisp lists ## 課程 - [Martin Fowler 講 FP](https://martinfowler.com/articles/collection-pipeline/) - [Uncle Bob 講 FP](https://cleancoders.com/episode/clean-code-episode-58) ## 總結函式編程特性 - Pure functions (no side-effects) - Immutability - Referential transparency - Memoization - Idempotence - Higher-order functions - Currying - Recursion - Lazy evaluation ## 結語 最終,要選什麼程式語言取決於你的個人目標跟喜好。 也許多嘗試幾種不同的程式語言可以幫助你更了解自己。 [Haskell]: https://www.haskell.org/ [Erlang]: https://www.erlang.org/ [Scala]: https://www.scala-lang.org/ [Elixir]: https://elixir-lang.org/ [Rust]: https://www.rust-lang.org/ [F#]: https://dotnet.microsoft.com/en-us/languages/fsharp [Clojure]: https://clojure.org/index [Lisp]: https://lisp-lang.org/