Hack:用於HHVM的一種新程式語言

rokety發表於2014-03-21

想急切嘗試Hack?傳送門:http://hacklang.org/

今天我們發行了Hack,一門能夠在HHVM上與PHP無縫互動的程式語言。Hack的靜態型別兼顧及協調了PHP的快速開發週期。同時增加了在其他現代程式語言中常見的許多功能。

我們已經在Facebook上部署了Hack,並且取得了巨大的成功。在過去的幾年裡,藉助自家開發的一些重構工具,我們幾乎將有的PHP程式碼遷移到了Hack上。

我們也很自豪地向外釋出一個開源版本的Hack,作為我們的 HHVM runtime 平臺的一部分,它現在同時支援Hack和PHP。

【補充資訊】:HipHop for PHP是一系列PHP指令碼語言的程式碼轉換器的集合,它包含HPHPc、HPHPi、HPHPd以及HHVM,這四個指令碼引擎各有所不同,但是他們共用相同的執行時期(Runtime)及工具集(Toolset)。HipHop是由Facebook所建立,他們用它來節省伺服器的資源。HipHop 由 C++ 和 C 語言所編寫,釋出時程式碼量已高達60萬行,它以自由軟體釋出,採用PHP許可證3.01版。摘自維基百科

動機

每一個PHP程式設計師對於每天棘手又笨重的任務都很熟悉。上面的程式碼是一個常見​​錯誤,其中一個方法可能意外地被一個空的物件所呼叫,從而導致難以發現的錯誤,直到執行時報錯。另一個例子是一個複雜的API,雖然開發者對於它的語義有直觀的理解,但仍需花時間在文件中查詢方法名。

在Facebook這樣的規模——成千上萬的工程師每天要釋出兩次新程式碼——這樣的開發速度變慢將更成問題。在沒有Hack之前,我們有一個能夠快速反饋回溯的簡單語言——但我們如何能減輕各種各樣的上述問題?早期的錯誤檢測和快速迭代是否能共存,同時還能保證在PHP上投入的精力有所回報?是否能夠改善程式碼分析和幫助審查使開發者更具生產力,就像有了一個自動化完成工具?

傳統上,動態型別語言允許快速開發,但會犧牲及早發現錯誤並迅速審查程式碼的能力,特別是在大的程式碼庫。相反,靜態型別語言提供更多的安全網,但往往增加快速迭代的成本。我們相信必須有一個平衡點。

因此,Hack就誕生了。我們相信,它提供了最好的動態型別和靜態型別語言各有的特性,而且,它也適合各種規模的專案。

Hack語言

Hack和PHP有著很深的根源。實際上,許多PHP檔案已經是合法的Hack檔案。我們有意識地選擇放棄那些與靜態語言不相容的少數便捷但將被被棄用的功能和特性。(例如:可變變數和extract()函式)。我們已經增加了許多新的特性,且這些特效能夠使開發者們更具生產力。

我們新增的最主要的特性是支援靜態型別。我們已經開發了一個系統來標註函式簽名和類成員的型別資訊,我們的型別檢查演算法(“型別檢查器”)能夠推斷出來。型別檢查是增量的,這樣,即使在同一個檔案中的一些程式碼可以轉換為Hack,而其他部分保持動態型別。從技術上講,Hack是一個“漸增型別”語言:動態型別程式碼和靜態型別程式碼無縫地互動。

在Hack的型別系統中,我們引入了幾個特性,例如泛型、可空型別、型別別名,和型別引數約束。這些新的語言特性是不顯眼的,所以你寫的Hack程式碼將仍然看起來像是使用動態語言的PHP程式設計師所編寫的。

然而,Hack增加了額外的特性,超越靜態型別檢查,包括集合,lambda表示式和執行時強制約束返回型別和引數型別。
集合提供了一個替代PHP陣列的簡潔的,型別安全的資料結構。我們設計它專門與靜態型別和泛型一起工作。集合API提供了許多經典的高階功能,如map()和filter()用於適應函數語言程式設計風格。

Lambda表示式給出一個簡潔的語法來建立閉包。雖然PHP也有閉包,但它要求程式設計師顯示地宣告它們所要使用到的外部變數。使用Hack的lambda表示式,它會自動推斷出這些用途,節省您不必要的工作。Lambda表示式使你能夠更方便地充分利用集合的API。

執行時強制約束返回型別和引數型別(包括標量型別,如int和string)提供更高的安全性,勝過靜態的程式碼審查,同時型別標註也會逐漸加入到程式碼庫中。執行時強制約束幫助程式設計師發現和診斷某些型別的問題更加容易,並且為了優化,它可以幫助HHVM的JIT生產更高效的程式碼更加安全,通過對型別標註的信任。

即時型別檢查

在開發過程中,一個PHP程式設計師通常會來來回回快速地在原始碼和瀏覽器之間切換。工程師們可以進行儘可能地快速迭代,測試和調優實驗,直到程式碼執行完美。

傳統上,一種型別的檢測器會破壞這種反饋環,因為它需要時間去分析原始碼。我們不想減緩PHP的工作流程,所以我們想出了一個新的方法來協調型別安全的即時反饋。

我們的解決方案是將型別檢查器構建為監視檔案系統的本地伺服器。伺服器在記憶體中儲存有關原始碼的所有資訊,並且當磁碟上的檔案改變時會進行自動更新。這種做法已見成效:型別檢查器通常執行在不到200毫秒,很少需要超過一秒鐘,因此很容易整合到開發流程,而不會引入明顯的延遲。

程式碼遷移

Hack的型別安全和重構隨著在程式碼庫的增加會帶來更多的好處。需要明確可能對於一些程式碼很難完整地遷移到Hack上,對於我們更重要的是在增量引入Hack程式碼時,能夠直接與現有的PHP程式碼共存。

遷移過程的其餘事項,如新增型別註釋,並使用新的語言特性,可以在程式碼庫中適當的修改。例如一個型別標註能夠在一個函式上新增,而另一個函式沒有,即使在同一個檔案中。如果一個函式的引數或者類的成員屬性沒有明確的型別標註,型別檢查器會認為它的型別是動態的,並且它不檢查該值的型別。

在Facebook,我們發現,我們的工程師們讚賞Hack,以至於他們開始自願遷移大部分自己的程式碼。在我們的程式碼庫有著數百萬行的程式碼,我們也希望能夠將一些工作自動化地執行,所以我們開發和使用了幾個程式碼修改工具來幫助遷移過程(這些工具已經作為Hack的一部分發布)。

別擔心,你的PHP是安全的!

HHVM仍然是一個PHP執行平臺,我們打算繼續保持這種方式。事實上,我們正努力達到PHP-5的標準。其中HHVM的首要任務是能夠執行未經修改的PHP 5的原始碼,不僅是為了社群,也因為我們依賴許多第三方PHP底層庫。

HHVM現在是一個能同時執行PHP和Hack的平臺,所以你可以逐漸體驗Hack所帶來的新特性。

感受Hack的趣味!

我們很高興能夠開源Hack,和自動轉換程式碼庫的工具。這僅僅是第一步,我們致力於繼續發展此軟體,使我們自己的工程師和更廣泛的社群能夠更加容易地進行開發。Hack的價值不侷限於大專案:擁有型別資訊,非常棒的錯誤提示,以及快速地反饋等特性,小的程式碼庫也能享受到Hack的好處。

下個月,我們將在Menlo Park的Facebook校園舉辦Hack Developer Day來介紹Hack,我們希望在那裡能看到你或者線上上。

我們很想聽聽您對我們工作的反饋,並歡迎大家加入HHVM和Hack社群。

致謝

在這裡有許多人對Hack的開發貢獻了一份力量。

Hack核心團隊由 Joel Beales、Eugene Letuchy、Gabriel Levi、Joel Marcey、Erik Meijer、Alok Menghrajani、Bryan O’Sullivan、Drew Paroski、James Pearce、Joel Pobar 和 Joshua Van Dyke Watzman組成。

特別感謝我們的社群早期採用者提供寶貴的反饋意見:James Miller、Simon Welsh、Nils Adermann、Fabien Potencier 和 Alexander Mols。

Hack主要是用OCaml語言編寫開發的。我們也同樣感謝Gallium團隊發展了OCaml語言,和Ocsigen團隊(CNRS – University of Paris Diderot – INRIA)開發的js_of_ocaml。

當然,感謝每一位幫助過Hack發展的人。這份名單無法在博文中詳細列出,但是你知道你所貢獻的一切。

相關文章