• <acronym id="eyrpt"></acronym>
    <track id="eyrpt"></track>
    <p id="eyrpt"></p>

      <table id="eyrpt"><ruby id="eyrpt"></ruby></table>
      <table id="eyrpt"></table>

    1. 當前位置:首頁 > 短網址資訊 > 正文內容

      編程語言的動靜之爭:Clojure太靈活,我們該如何駕馭它?

      作者|FT12短網址
      編輯|短鏈接
      編程語言的圣戰,除了語言種類之分,也有動靜門派之別。我們寫著靜態語言往往想著動態語言的靈活,寫著動態語言又容易想著靜態語言的穩定和可靠。常聽到有人說,Clojure 確實優美,但動態語言實在駕馭不了,怎么辦?

      注:本文整理自 Morgan Stanley VP 何婧譽在 QCon 2017 北京站上的演講,原題為:《屬兔的處子——喜歡 Clojure,但怕動態語言太靈活怎么辦》。

      寫在前面

      古話說的好,靜若處子,動若脫兔。這個我覺得非常適合形容動靜態語言的區別,靜態語言因為類型系統的關系,一直給人的是很穩定、很可靠,但是可靠到一定程度就變成了死板,會變成一個牢獄或者困住業務上所需的靈活性,因此常常需要很多層抽象,很多層膠水代碼,代碼就開始變得非常的晦澀,非常的難懂,而動態語言則完全是相反的。

      常聽到有人說,Clojure 確實優美,但動態語言實在駕馭不了??!沒有類型的幫助,在涉及到復雜的數據結構之后很容易失去對現有程序的理解,易讀性也會急速下降,而這也確實是 Clojure 作為動態語言所造成的問題。但是部分解決這個問題的辦法總是有的。core.typed 和 core.spec 兩個核心庫就可以幫助我們緩解動態語言太過野性框不住的問題,而本次演講的任務就是向大家介紹這兩個庫,以及這兩個庫解決這一問題的不同角度。

      靜態語言 VS 動態語言

      靜態語言因為類型系統的關系,一直給人的是很穩定、很可靠,但是可靠到一定程度就變成了死板,會變成一個牢獄或者困住業務上所需的靈活性,因此常常需要很多層抽象,很多層膠水代碼,代碼就開始變得非常的晦澀,非常的難懂。動態語言則完全是相反的,所有東西都是從類型上來講,以函數為例,靈活性已經足夠了,但是通常我們寫著寫著就忘記數據長什么樣子了,你可能今天寫了一個函數說,輸入一個函數的數據,然后過了一個星期之后,我已經完全忘記這個數據是什么東西了,因為生產環境里面,類型系統在沒有編譯器的幫助下,基本上都是一次性的,這個問題對于用戶來說有相當大的困擾。

      一直以來,這兩派之間沒有爭出特別的高低,靜態語言笑動態語言做不出大系統,動態語言笑靜態語言寫的太慢、廢話太多,今天這個主題當然不可能解決這個紛爭,但是希望通過 Clojure 這個語言可以給大家一些不太為人知的思路。馬上就有人來問了,我寫 Clojure 就是為了逃避這樣的內容來寫系統,這樣靈活多好用啊,我想寫什么就寫什么,快速原型靠的就是這個,我非常同意這一點。

      簡單示例


      在 Clojure 里面有一個 json,因為動態語言的關系相當的簡單,完全沒有廢話。這個函數我覺得哪怕是不寫 Clojure 的,這個也是應該很能讀的懂的。首先有一個 Java 的 Reader,是 FileReader,這個 Reader 被傳遞到了這個 json 的函數里面,讀出來文件內容,讀到 Map 里面,但是讀完之后,你知道數據長什么樣嗎?不知道,下次換一個 json 文件,同樣的函數可以同樣讀,但是你不知道讀出來是什么東西。講到這里就已經有一點難度在里面了。

      現在看一下,我現在讀完了要處理,我處理之后,我寫任意一個函數,如果說你不看這個函數寫的什么東西,你知道它處理完成之后長什么樣嗎?不知道,你知道他希望這個 json 數據是什么樣的形狀嗎?不知道。我現在看了代碼之后,可以給你講,它里面會有會有 Age、Name、Job、Address。


      看一下 Age,它需要能夠使用 Int,那應該是個整數,但是要看代碼才知道,再下面還是簡單,那你們覺得 Name 的值是什么東西?完全沒有使用到,它是一個 String,它是不是姓和名放在一起了?還是放在一個 Vector 里面,可能姓和名是分開的,就是說不知道,要看代碼才知道。


      你看到代碼之后覺得,原來是這樣,它應該是一個 Vector,或者是 List,姓和名是分開放,因為它這系,它用空格來 Join 一下,這個是一個很淺顯的例子,就已經說明了 Clojure 的動態靈活性非常強,但是也造成對數據的解釋性標記不是很清楚。

      前文是一個很淺顯的例子,現在來看一個更具體的。為了這個主題我想了好幾天,覺得還是寫一個很小的項目來展示一下要講的東西。那寫什么東西呢?我又想了好幾天,在此先謝謝鏈家。因為是這樣的,既然要來北京,就要關注一下房價。我到網上去看二手房信息,但一頁頁翻過去很累,我不可能手寫一個總結,于是就寫點程序抓取。當然這里不是真的寫了一個爬蟲,只是抓幾個頁面做做樣子,沒有讓鏈家服務受到傷害,請鳥哥放心。

      命名空間做的基本上就是通過一個庫把 html 讀進來之后,進行一些簡單的操作,把整理好的數據寫到一個 EDN 文件里邊。比如說第一條你可以看到這個小區 1150 萬,三臥室兩個客廳,一個廚房兩個衛生間,包括面積之類的東西。再看這個數據轉換的函數,它收到一個參數是 Page,但這個 Page 長什么樣完全不知道。我是通過庫讀進來的,讀進來之后,并不知道它長什么樣子,現在看這個代碼也很難知道,它到底會返回一個什么樣的類型,什么樣的數據,如果將來需要擴展的話,或者將來我要給另外一個人用,或者幫助另外的一個人去做一些擴展,做一些維護很難搞定。

      這就是前文說的 Clojure 作為一個動態語言的弊端——太靈活。這個弊端導致經常會忘記函數的參數是什么樣子,而且這個是小項目,項目一大,那就更麻煩??赡苡腥藭f的,文檔不就是做這個事情的嗎?文檔跟測試,沒有緊密的聯合在一起,文檔本身的代碼是剝離的,而相對代碼本身是沒有限制的。比如說很多代碼上面會寫,但是其實代碼里面并沒有,它可能起到的效果某種程度上也是挺有限的。

      Core.typed

      Core.typed 是一個類型系統。它和其他語言的類型系統還是有點不一樣的地方,不同點在于它不是語言的一部分,而是一個即查即用的庫。Lisp 的靈活性導致它能夠作為一個庫直接插進去,而不是要作為一個語言核心。因為它有宏,通過宏可以把一個很大的類型系統直接插進去,而且這個類型系統比一般的系統要靈活很多,主要體現在這幾個方面:

      • 第一,它可以給已經寫好的,沒有標注過的,或者說是用的庫里面沒有標注過的函數直接加上類型;

      • 第二,不需要把所有函數全部加上類型,你不想要的話,就不需要;

      • 第三,你即使加上了也不一定要進行類型檢查,所以它是一個選擇性非常強的東西。它是為了能夠和 Clojure 這樣的語言進行協作。

      那我們現在看一下它支持什么東西:

      OptionType,現在很流行,這個流行的語言現在都有這個結構。

      Ordered Intersection Type 這個我不多講了,這個就是說一個函數,比如有兩種參數形式,這兩種參數類型可能又不一樣,你再進行類型檢查的時候,它會把這個參數從上到下有序的來進行一個匹配。unionType,寫過 Haskell 人都知道,這個很簡單,比如說整數,或者說是字符串,把它 union 一下,那就表示這個類型里面的東西可以是字符串,也可以是函數。

      Identity 是很簡單的函數,它會給你一模一樣的東西,那它的類型是什么呢?它這個函數的類型是什么東西呢?讓 Core.type 來幫我看一下。這個基本上可以看到前面有個 all,在這里對所有的 X 能取得的類型它返回的是一個 X,就是 Polymorphism 最簡單的一個體現了。Occurrence Typing 這個東西見到的比較少,它是什么呢?它是通過檢查代碼里面寫的控制流,比如像 if,或者像 switch,它能夠進行類型推導。

      舉個例子,首先把這個 Form 綁到 A 這個名字上面,值就是 1,但是我把它標注成了 any,就是說這個 A,就算只是 1,然后再返回 A,這里大家覺得會返回什么東西?如果是檢查一個類型,它最后返回的是 A,它是什么類型?Any,因為我已經標過了,我說 A 是 Any,所以它就相信 A 是 Any,但是如果我這么寫,這個會返回什么東西?你可以看到它現在還是返回的是 A,這個 A 或者這個也是 A,那其他情況返回的是 Nil,那他現在覺得這個東西是什么呢?還是不是 Any,因為你現在有了控制流在這邊,代碼里已經寫過了,所以它知道你只可能是 number,或者是 string,要不然就是 nil,所以最后 A 是 union string/number/nil。這個東西功能上是非常強大的,這個也是我強推的一個東西,這個你真正用起來就知道方便。

      最后一個就是宏也會被展開之后再推導類型,宏跟大家剛剛知道的 switch 有點像,就是已經很直接了當的,告訴大家這個宏是可以展開之后判斷類型。我做的 Demo 的 types Demo,就是把剛剛鏈家那個小項目加了類型系統,我現在是把它所制造的結果定義類型,但它其實是什么呢?是一個 Map。

      Core.spec 總結

      • 通過一個庫給動態語言加上類型系統——即插即用

      • 可以給已經寫好的函數或者是用的無類型庫標注類型

      • 可以選擇性地加上類型

      • 加上了類型也并非一定要 type check

      • 支持 Option Type,Ordered Intersection Types, Union Types

      • 支持 Heterogenous Maps 和 Sequentials

      • 支持 Polymorphism (All, Context Bounds),Higher-Kinds

      • 支持 Occurrence Typing?。ㄍㄟ^檢查 control flow 進行類型推導)

      • 宏也會被展開后再推導類型

      Core.spec

      我本人很喜歡寫這個,我覺得給函數加上類型非常過癮,但是有問題,那有別的辦法嗎?有的,Core.spec,現在這個東西是 Clojure 核心,在很盡力地推廣。在方法上或者在函數上,加上先限條件,功能要強大一點,強大在什么地方呢?

      比方說生產環境,Runtime 不會受到影響,它的性能不會受到影響。因為如果你一天到晚在檢驗,它的性能上是會受到影響的,所以缺省驗證是關閉掉的,如果你覺得某些東西可能重要性比較大,你要加上去也是可以的。spec 非常靈活,它可以把那種正則方式的 rule 給寫起來,就是比如某個 list,我覺得里面開頭至少有一個字符串,然后后面跟著的至少是 0 個的整數等等,你就可以用正則里面的加號,星號直接定義這個 rule。并且所有只有一個參數的 predicate 的函數統統可以跟它進行無縫對接,不需要另外語法把它轉換成 spec。這里面有很多種的驗證方式,那么多的驗證的方式可能現在沒有時間講,就不講了,總體來說就是可以把數據套在一個很靈活的模子里。

      Core.spec 總結

      • Runtime 性能基本不會受到影響(缺省 spec 驗證關閉)

      • Map 的類型應該就是 key 及其對應的值的類型!(keys)

      • Sequence 可以多方面限制(cat, alt, regex style matching, coll-of)

      • 只有一個參數的返回 boolean 值的函數通通都自動成為 predicate

      • 各種驗證方式,滿足你的需求 (conform, explain, valid?)

      • multi-spec 支持更復雜的數據結構

      Core.type vs Core.spec

      寫在最后

      core.typed 和 core.spec 你推薦哪個?

      我的腦子喜歡 core.spec,因為有前景。我的內心喜歡 core.typed,因為給東西加類型寫起來真得很過癮。



      掃描二維碼推送至手機訪問。

      版權聲明:本文由短鏈接發布,如需轉載請注明出處。

      本文鏈接:http://www.virginiabusinesslawupdate.com/article_493.html

      分享給朋友:

      相關文章

      那個賣了房子去大理的姑娘,4個月以后又回來了……

      一、那個賣了房子去大理的姑娘,4個月以后又回來了……也許,我們每個人的內心深處都有一個夢:到一個安靜美好的小地方,開一家小店,就這么慢悠悠地晃過這一生……不過,你真的確定這些是你想要的嗎?1我一個女文青朋友年前賣了蘇州的房子,去云南大理追求...

      揭秘淘寶漏洞,灰色收益每月30000+

      揭秘淘寶漏洞,灰色收益每月30000+

      本文和大家談談如何利用七天無理由退貨、運費險兩大游戲規則之間的漏洞,實現日賺千元,分享本文的目的僅作揭露,請勿模仿操作。在淘寶網運費險規則中,買家的保費根據賠付金額按5%收取,比如保費0.5元、0.6元,對應的保額是10元、12元。這樣在收...

      校園貸后又現整容貸,校園金融到底怎么了?

      繼校園貸引發的悲劇被媒體大肆報道后,整容貸又被推到輿論的風口浪尖。FT12短網址的小編奉勸各位愛美的同學,還是要量力而為呀!近年來,在互聯網金融的強勢推動下,我國的消費貸款迎來爆發式的增長。數據顯示,2008年到2016年,我國消費性貸款余...

      為什么 Chrome 會悄悄對一些奇怪的地址發起 DNS 請求?

      國外有網友注意到,電腦有的時候會做一些奇怪的 DNS 請求,請求的地址像是隨機的網址一樣,懷疑是有惡意軟件。 但后來發現,這些請求是 Chrome 發起的,并且不論 Windows 還是 Mac 上都能發現。類似上圖的地址,注意其中幾個報錯...

      FT12短網址:解析ESLint 的成功之道

      FT12短網址:解析ESLint 的成功之道

      前言本文源自于網絡,FT12短網址僅做轉載,對此文無所有權。難以置信,我在 2013 年 6 月構思開發了 ESLint,7 月第一次對外發布。熟悉的讀者可能還記得,ESLint 最初主要設計目標是運行時加載的檢查工具(linter)。在工...

      FT12短網址 | MySQL阿里實踐經典案例之參數調優最佳實踐

      FT12短網址 | MySQL阿里實踐經典案例之參數調優最佳實踐

      寫在前面的話最近,不少RDS用戶在后臺咨詢,如何調優RDS MySQL的參數。長假天兒,學習天兒。本期,我們特別邀請到阿里云資深RDS專家玄慚撰文解答:哪一些參數不能修改,比如短網址的api里面的參數都是不能改的那一些參數可以修改這些提供修...

      發表評論

      訪客

      ◎歡迎參與討論,請在這里發表您的看法和觀點。
      一本色综合网久久
    2. <acronym id="eyrpt"></acronym>
      <track id="eyrpt"></track>
      <p id="eyrpt"></p>

        <table id="eyrpt"><ruby id="eyrpt"></ruby></table>
        <table id="eyrpt"></table>