BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

初探F# 4.0

| 作者 Jonathan Allen 关注 553 他的粉丝 ,译者 邵思华 关注 3 他的粉丝 发布于 2015年5月4日. 估计阅读时间: 7 分钟 | 如何结合区块链技术,帮助企业降本增效?让我们深度了解几个成功的案例。

尽管近期所有的新闻都在关注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个表达式那样写就可以了:

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>

F# 4中的新功能之一是能够在度量单位表达式中使用分数指数。举例如下:

[<Measure>] type Jones = cm Hz^(1/2) / W

从具有多个泛型接口的类型继承

如果你不熟悉F#的话,要理解这一点有些困难,而如果你熟悉F#,你就知道这一点多么令人头疼了。在开始之前,首先想象一个表示16进制数字的类。在C#中,你在设计这个类时或许会决定让它能够与字符串和整数进行比较。

public class Hexidecimal : IComparable<string>, IComparable<int>

由于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的异步工作流扩展等等。

查看英文原文:Our First Look at F# 4.0

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

《初探F# 4.0》的说法正确? by 李 巨添

英文原文的正确性值得怀疑,DateTime是结构,当然是使用结构的比较方式。是类,但是使用结构的比较方式的,只有record。没头没尾的,冒出一句,F#类型使用结构比较方式,产生太大的误导了。

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

1 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT