初探F# 4.0
盡管近期所有的新聞都在關注 C# 和 Windows 10,但F#也沒有坐以待斃。隨著 Visual Studio 2015 RC 的面世,F# 4.0 也一同浮出水面。
首先要注意的第一點就是,這是一個由社區的努力所推出的項目。在全部 38 位貢獻者中,只有 4 分之 1 的人與微軟有所關聯。所有的工作都是在F#的 GitHub 網站上公開完成的,他們也希望能夠通過這個平臺獲得用戶的反饋。
這個新的發布版本對語言本身和運行時都帶來了大量的變更,也對 IDE 進行了一些改進。你可以在F#博客上找到完整的變更列表,我們在這里將著重分析幾個重點特性。
元編程的支持
自從 .NET 4.0 中引入了 LINQ 之后(譯注:此處原文有誤,LINQ 首次是在 .NET 3.5 中出現的),通過表達式樹在 .NET 中實現元編程就成為了一種非常重要的特性。而在F# 4.0 中,編寫表達式樹變得前所未有的簡單。
如果你為某個類型為 FSharp.Quotations.Expr 的參數加上 ReflectedDefinition 這個屬性,那么調用方會自動地切換到按名稱調用的方式。在之前的版本中,你必須按照下面的代碼中的前兩個表達式的方式對調用方進行標注,而現在只需按照第 3 個表達式那樣寫就可以了:
</blockquote>
Test.Expression1 ( <@ x + 1 @> ) //typed expression
Test.Expression2 ( <@@ x + 1 @@> ) //untyped expression
Test.Expression3 ( x + 1 ) //typed expression with ReflectedDefinition attribute消除了明確地對表達式進行引用的負擔之后,那些應用了元編程技術的類庫就變得容易使用多了。
改進的預處理器指令
不管你相信與否,直至目前為止,F#對預處理器指令的支持少得可憐。類似于“#if TRACE DEBUG”這樣的布爾操作直到這個版本才剛剛實現。對于F# 3 以及更早的版本來說,一種臨時方案是使用嵌套的#if 語句以模擬“and”表達式,并用重復性的代碼模擬“or”表達式。
度量單位
在進行科學應用或工程應用時,經常會因為單位的差錯而導致錯誤。舉例來說,你可能會混淆英制單位和公制單位這兩種不同的度量值。在 1999 年,正是因為這個錯誤導致了造價達 1 億 2 千 5 百萬美元的航天探測器 —— 火星氣候探測器(Mars Orbiter)的毀滅。
F#通過某種被稱為度量單位的概念消除了這種類型的 bug 的產生。將某個標量數值加上“<cm>”或“<miles/hour>”這樣的前綴,就可以將其轉換為單位度量。正如下面一行代碼所示,在單位之間進行的每種轉換都是由度量單位所表達的。
let cmPerInch : float<cm/inch> = 2.54<cm/inch>
</blockquote>F# 4 中的新功能之一是能夠在度量單位表達式中使用分數指數。舉例如下:
[<Measure>] type Jones = cm Hz^(1/2) / W
</blockquote>從具有多個泛型接口的類型繼承
如果你不熟悉F#的話,要理解這一點有些困難,而如果你熟悉F#,你就知道這一點多么令人頭疼了。在開始之前,首先想象一個表示 16 進制數字的類。在 C# 中,你在設計這個類時或許會決定讓它能夠與字符串和整數進行比較。
public class Hexidecimal : IComparable<string>, IComparable<int>
</blockquote>由于F#中類型推斷的復雜性,在之前的版本中無法表達這個類。一方面,你無法定義一個具有多個接口,并且這些接口的唯一區別只在于它們的類型參數的這種類型。另一方面,你也不能夠繼承這樣的類型。
F# 4 也沒有完全解決這個問題,但它提供了某種臨時方案。你現在要創建兩個類,讓每個類實現一個接口,并讓第二個類繼承于第一個類。這種代碼有些繁瑣,但如果你正好使用了某個基于 C# 編寫的類庫,那么在某些情況下必須使用這種方法。
在對象初始化器中使用擴展屬性
擴展屬性這一特性是 C# 使用者非常渴望得到的特性,而F#已經具備這一特性了。在這個最新版本中,能夠在對象的初始化器中使用擴展屬性了。
去除了微軟的品牌標志
F#這門語言的專屬命名空間總是以“Microsoft.FSharp”開頭的,這種傳統從 Visual Basic 7 就開始了。但隨著F#逐漸從微軟自有變成由社區驅動的項目,這種方式也顯得不那么恰當了,而它身上的微軟標記也在逐漸地淡化。
在這種情況下,為了保持F#代碼不依賴于任何提供商與平臺,在引用 FSharp.Core 運行時的命名空間、模塊和類型的時候,可以選擇忽略“Microsoft.”這一命名空間前綴。
性能改進:非結構化的比較
在默認的情況下,F#使用的是結構化的比較方式,而不是類型內置的操作符,例如 op_Equality 等。這種方式雖然能夠簡化復雜數據的比較,但也對性能造成了損害。
如果你希望選擇注重內置比較操作符的性能或是語義,現在你可以使用“打開 NonStructuralComparison”這一操作改變例如=等操作符的工作方式了。在對某個循環中的 DateTime 對象的比較進行的基礎測試中,其結果顯示性能提高了一個數量級。
腳本調試
在 VS 2015 之前,F#開發者只能選擇使用F#的互動模式,或是選擇完整地訪問調試器。有了新版本中的腳本調試特性,你可以右鍵單擊某段F#腳本,并在調試器中運行它,這種方式結合了兩種模式的優點。
智能地進行重編譯
在 VS 2013 和之前的版本中,Visual Studio 無法檢測出某個F#項目是否需要進行編譯。因此,即使某個F#中沒有任何變化,也必須進行重新編譯。而在 VS 2015 中能夠檢測到某個F#項目是否保持最新,因此開發者無需等待項目進行無意義的編譯了。
其它的新特性還包括改進的智能提示、針對 Option<T>的互操作 API、對于 WebClient 的異步工作流擴展等等。
來自: InfoQ本文由用戶 cbgd 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!