翻譯連載 | JavaScript 輕量級函數語言程式設計-第1章:為什麼使用函數語言程式設計?|《你不知道的JS》姊妹篇

iKcamp發表於2017-08-22

關於譯者:這是一個流淌著滬江血液的純粹工程:認真,是 HTML 最堅實的樑柱;分享,是 CSS 裡最閃耀的一瞥;總結,是 JavaScript 中最嚴謹的邏輯。經過捶打磨練,成就了本書的中文版。本書包含了函數語言程式設計之精髓,希望可以幫助大家在學習函數語言程式設計的道路上走的更順暢。比心。

譯者團隊(排名不分先後):阿希bluekenbrucechamcfanlifedailkyoko-dfl3velilinsLittlePineappleMatildaJin冬青pobusamaCherry蘿蔔vavd317vivaxy萌萌zhouyao

第 1 章:為什麼使用函數語言程式設計?

函數語言程式設計人員: 沒有任何一個函數語言程式設計者會把變數命名為 x,函式命名為 f,模組程式碼命名為“zygohistomorphic prepromorphism”。

James Iry ‏@jamesiry 5/13/15

twitter.com/jamesiry/st…

函數語言程式設計(FP),不是一個新的概念,它幾乎貫穿了整個程式設計史。我不確定這麼說是否合理,但是很確定的一點是:直到最近幾年,函數語言程式設計才成為整個開發界的主流觀念。所以我覺得函數語言程式設計領域更像學者的領域。

然而一切都在變。不只是從程式語言的角度,一些庫和框架都對函數語言程式設計的興趣空前高漲。你很可能也在讀相關內容,因為你終於意識到函數語言程式設計是不容忽視的東西。或者你跟我一樣,已經嘗試很多次去學函數語言程式設計,但卻很難理解所有的術語或數學符號。

無論你出於何目的翻閱本書,歡迎加入我們!

置信度

我有一個非常簡單的前提,這是我作為軟體開發老師(JavaScript)所做的一切基礎:你不能信任的程式碼是你不明白的程式碼。此外,對你不信任或不明白的程式碼,你將不能確定這些程式碼是否符合你的業務場景。程式碼執行時也只能祈求好運。

信任是什麼意思?信任是指你通過讀程式碼,不僅是跑程式碼,就能理解這段程式碼能幹什麼事,而不只是停留在它可能是幹什麼的層面。也許我們不應該總傾向於通過執行測試程式,來驗證程式的正確性。我並不是說測試不好,而是說我們應該對程式碼瞭如指掌,這樣我們在執行測試程式碼之前就會知道它肯定能跑通。

通過讀程式碼就能對我們的程式更有信心,我相信函數語言程式設計技術的基礎構成,是本著這種心態設計的。理解函數語言程式設計並在程式中用心實踐的人,得益於函數語言程式設計已經被證實的原則,能夠寫出可讀性高和可驗證的程式碼,來達到他們想要的目的。

我希望你能通過理解輕量級函數語言程式設計的原則,對你編寫的程式碼更有信心,並且能在之後的路上越走越好。

交流渠道

函數語言程式設計為何如此重要?為了回答這個問題,我們退一萬步先來討論一下程式設計本身的重要性。

我認為程式碼不是電腦中的一堆指令,這麼說你可能感到很奇怪。事實上,程式碼能指示電腦執行就是一個意外的驚喜。

我深信程式碼的主要作用是方便人與人交流。

根據以往經驗你可能知道,有時候花很多時間“程式設計”其實只是讀現有的程式碼。我們的大部分時間其實都是在維護別人的程式碼(或自己的老程式碼),只有少部分時間是在敲新程式碼。

你知道研究過這個話題的專家給出了怎樣的資料嗎?我們在維護程式碼過程中 70% 的時間花在了閱讀和理解程式碼上。 也難怪全球程式設計師每天的平均程式碼行數是 5 行。我們一天花七個半小時用來讀程式碼,然後找出這 5 行程式碼應該寫在哪裡。

我想我們應該更多的關注一下程式碼的可讀性。可能的話,不妨多花點時間在可讀性上。順便提一句,可讀性並不意味著最少的程式碼量,對程式碼的熟悉程度也會影響程式碼的可讀性(這一點也是被證實過的)。

因此,如果我們要花費更多的時間來關注程式碼的可讀性和可理解性,那麼函數語言程式設計為我們提供了一種非常方便的模式。函數語言程式設計的原則是完善的,經過了深入的研究和審查,並且可以被驗證。

如果我們使用函數語言程式設計原則,我相信我們將寫出更容易理解的程式碼。一旦我們知道這些原則,它們將在程式碼中被識別和熟悉,這意味著當我們讀取一段程式碼時,我們將花費更少的時間來進行定位。我們的重點將在於如何組建所有已知的“樂高片段”,而不是這些“樂高片段”是什麼意思。

函數語言程式設計是編寫可讀程式碼的最有效工具之一(可能還有其他)。這就是為什麼函數語言程式設計如此重要。

可讀性曲線

很重要的是,我先花點時間來講述一種多年來讓我感到困惑和沮喪的現象,在寫本書時該問題尤為尖銳。

這也可能是許多開發人員會遇到的問題。親愛的讀者,當你讀這篇文章的時候,你可能會發現自己也會遇到同樣的狀況。但是要振作起來,堅持下去,陡峭的學習曲線總會過去。

翻譯連載 | JavaScript 輕量級函數語言程式設計-第1章:為什麼使用函數語言程式設計?|《你不知道的JS》姊妹篇

我們將在下一章更深入的討論這個問題。但是你可能寫過一些命令式的程式碼,像 if 語句和 for 迴圈這樣的語句。這些語句旨在精確地指導計算機如何完成一件事情。宣告式程式碼,以及我們努力遵循函數語言程式設計原則所寫出的程式碼,更專注於描述最終的結果。

還有個殘酷的問題擺在眼前,我在寫本書時花費了很多時間在此問題上:我需要花費更多的精力和編寫更多的程式碼來提高程式碼的可讀性,儘量減少乃至消除可能會引入程式錯誤的程式碼部分。

如果你期望用函數語言程式設計重構過的程式碼能夠立刻變得更美觀、優雅、智慧和簡潔的話,這個有點不太現實,這個變化是需要一個過程的。

函數語言程式設計以另一種方式來思考程式碼應該如何組織才能使資料流更加明顯,並能讓讀者很快理解你的思想。這種努力是非常值得的,然而過程很艱辛,你可能需要花很多時間基於函數語言程式設計來調整程式碼直到程式碼可讀性變得好一些。

另外,我的經驗是,轉換為宣告式的程式碼之前,大約需要做六次嘗試。對我來說,編寫符合函數語言程式設計的程式碼更像是一個過程,而不是從一個範例到另一個範例的二進位制轉換。

我也會經常對寫過的程式碼進行重構。就是說,寫完一段程式碼,過幾個小時或一天再看會有不一樣的感覺。通常,重構之前的程式碼是比較混亂不堪,所以需要反覆調整。

函數語言程式設計的過程並沒有讓我在藝術的畫布上筆下生輝,讓觀眾拍案叫好。相反,程式設計的過程很艱辛且歷歷在目,感覺像坐在一輛不靠譜的馬車穿過一片雜草叢生的灌木樹林。

我並不是試圖打消你的激情,而是真切希望你也能夠在程式設計的道路上披荊斬棘。過後我終於看到可讀性曲線向上延伸,所有付出都是值得的,我相信你也會有同樣的感受。

接受

我們要系統的學習函數語言程式設計,探索發現最基本的原則,我相信規範的函數語言程式設計程式設計者會遵循這些原則並把它們作為開發的框架。但在大多數情況下,我們大都選擇避開晦澀的術語或數學符號,否則很容易使學習者受挫。

我覺得一項技術你怎麼稱呼它不重要,重要的是理解它是什麼並且它是怎麼工作的。這並不是說共享術語不重要,它無疑可以簡化經驗豐富的專業人士之間的交流。但對學習者來說,它有點分散人的注意力。

所以我希望這本書能更多地關注基本概念而不是花哨的術語。這並不是說沒有術語,肯定會有。但不要太沉迷於華麗的詞藻,追尋其背後的含義,這正是本書的目的。

我把這種欠缺正式實踐的程式設計思想稱為“輕量級函數語言程式設計”,因為我認為真正的函數語言程式設計的形式主義在於, 因為我認為如果你還不習慣函數語言程式設計主張的思想,你可能很難用它。這不僅僅只是猜測,而是我的親身經歷。即使在傳教函數語言程式設計過程和完成這本書之後,我仍然可以說,函數語言程式設計中術語和符號的形式化對於我來說是非常非常困難的。我已經再三嘗試,發現大部分都是很難掌握的。

我知道很多函數語言程式設計程式設計者會認為形式主義本身有助於學習。但我認為這是一個坑,當你試圖用形式主義獲得某種安慰時,你就會踩坑。但如果碰巧你有數學背景,甚至還有一些 CS 經驗,這些問題對你來說就可能駕輕就熟。但是我們中的一些人不具備這些條件,不管我們怎麼努力,形式主義總是阻礙我們前進。

因此,這本書介紹了一些我認為函數語言程式設計會涉及到的概念,雖然不能直接讓你受益但可以幫你逐步理解函數語言程式設計整個過程。

你不需要它

如果你規劃一個專案花了很長時間,那麼別人一定會告訴你“YAGNI” —— “你不需要它”。這個原則主要來自極限程式設計,強調構建特性的高風險和成本,這個風險和成本源自於專案本身是否需要。

有時我們考慮到將來可能會用到一個功能,並且認為現在構建它能夠使得構建其他應用時更容易,後來意識到我們猜錯了,原來這個功能並不需要,或者需要的完全是另外一套。另外一種情形是我們預估的功能是正確的,但構建得太早的話,相當於佔用了開發現有功能的時間。有點像賠了夫人又折兵。

YAGNI 挑戰,告訴我們:即使有的功能在某種情況下是反直覺的,我們也常常應該推遲構建,直到當前需要這個功能。我們傾向於誇大一個功能未來重構成本的心理估計,但往往這個重構是在將來需要時才會做。

上述情況對函數語言程式設計也同樣適用,不過我還是要先敲個警鐘: 本書包含了大量你想去嘗試的有趣的開發模式,但這不意味著你的程式碼一定要使用這些模式。

我與很多函數語言程式設計開發人員的不同之處在於:你掌握了函數語言程式設計並不意味著你一定得用它。此外,解決問題的方法很多,即使你掌握了更精煉的方法,能對維護和可擴充套件性更"經得起未來的考驗",但更輕量的函數語言程式設計模式可能更適合該場景。

一般來說,我建議你在程式碼中尋求平衡,並且當你掌握函數語言程式設計的訣竅時,在應用的過程中也應保持謹慎。在決定某個模式或抽象概念是否能使得部分程式碼可讀性提高,或是否只是引入更智慧的庫時,YAGNI 的原則同樣適用。

提醒一句,一些未曾用過的擴充套件點不僅浪費精力,而且可能妨礙你的工作。

Jeremy D. Miller @jeremydmiller 2/20/15

twitter.com/jeremydmill…

記住,你編寫的每一行程式碼之後都要有人來維護,這個人可能是你的團隊成員,也可能是未來的你。如果程式碼寫的太過複雜,那麼無論誰來維護都會對你炫技式的故作聰明的做法倍感壓力。

最好的程式碼是可讀性高的程式碼,因為它在正確的(理想主義)和必然的(正確的)之間尋求到了恰到好處的平衡。

資源

我撰寫這篇文章的過程參考了許多不同的資源。我相信你也會從中受益,所以我想花點時間把它們列出來。

書籍推薦

一些你務必要閱讀的函數語言程式設計 / JavaScript 書籍:

部落格和站點

一些其他作者和相關內容供查閱:

一些庫

本書中的程式碼段不使用庫。我們發現的每一個操作,將派生出如何在獨立的、普通的 JavaScript 中實現它。然而,當你開始使用函數語言程式設計構建更多的真正程式碼時,你很快就會使用現有庫中所提供的更可靠高效的通用功能。

順便說一下,你要確保檢查你所使用的庫函式的文件,以確保你知道它們是如何工作的。它與本文中構建的程式碼有許多相似之處,但毫無疑問即便跟最流行的庫相比還是會存在一些差異。

下面是一些流行的 JavaScript 版本的函數語言程式設計庫,可以開啟你的探索之路:

附錄 C 展示了用到了本書中一些示例的庫。

總結

這就是 JavaScript 輕量級函數語言程式設計。我們的目標是學會與程式碼交流,而不是在符號或術語的大山下被壓的喘不過氣。希望這本書能開啟你的旅程!

** 【上一章】翻譯連載 |《JavaScript 輕量級函數語言程式設計》- 引言&前言 ** ** 【下一章】翻譯連載 |《JavaScript 輕量級函數語言程式設計》- 第 2 章:函式基礎 **

翻譯連載 | JavaScript 輕量級函數語言程式設計-第1章:為什麼使用函數語言程式設計?|《你不知道的JS》姊妹篇

翻譯連載 | JavaScript 輕量級函數語言程式設計-第1章:為什麼使用函數語言程式設計?|《你不知道的JS》姊妹篇

iKcamp原創新書《移動Web前端高效開發實戰》已在亞馬遜、京東、噹噹開售。


翻譯連載 | JavaScript 輕量級函數語言程式設計-第1章:為什麼使用函數語言程式設計?|《你不知道的JS》姊妹篇

2019年,iKcamp原創新書《Koa與Node.js開發實戰》已在京東、天貓、亞馬遜、噹噹開售啦!

相關文章