写点什么

Scala 语言将加入宏指令

  • 2013-01-22
  • 本文字数:1580 字

    阅读完需:约 5 分钟

Scala 开发团队正在将实验版宏指令加入到即将发行的 2.10 版中。Scala 宏指令提供了编译时元编程的高级形式。 Scala 宏网站描述道:

“宏指令显著简化了代码分析和代码生成,这使得它们成为处理大量现实用例的一种可选工具。传统上涉及编写和维护样板的场合可用宏以简单且易维护的方式实现。因此我们认为宏对于 Scala 编程语言是一项非常有价值的资产。”

Scala 的宏指令允许开发者创建方法时以语法树转化的形式实现。这些是标准方法的定义,其在编译期间被显式地转换。举一个简单的例子,如 assert 方法:

复制代码
import scala.reflect.makro.Context
import language.experimental.macros
object Asserts {
def assert(cond: Boolean, msg: Any) = macro Asserts.assertImpl
def raise(msg: Any) = throw new AssertionError(msg)
def assertImpl(c: Context)(cond: c.Expr[Boolean], msg: c.Expr[Any]): c.Expr[Unit] =
if(assertionsEnabled) c.reify(if(!cond.splice) raise(msg.splice))
else c.reify(())
}

assert 宏就像代码中的一个普通的方法。该实现使用 macro 方法委托成为编译器扩展。该编译器扩展是方法 assertImpl。assertImpl 使用当前编译的上下文作为参数,而参数传给 assert 作为语法树(Expr)。这些语法树接下来被用作产生一个新的语法树并被插入至 assert 宏方法被调用的位置。

对于 assert 宏来说,调用 assert 的方法 assert(x != null, “X is null”) 会给 cond 变量填充 x != null 的语法树而给 msg 变量填充"X is null"的语法树。对 reify 的调用会产生一个 if(x != null) Asserts.raise(“X is null”) 的或者 () 的新语法树。这个语法树会替代原始的 assert(x != null, “X is null”) 调用。

reify 和自清洁宏系统的更多细节可参考自清洁宏建议

有些人怀疑添加宏的效果,在一份题为《 Scala Macros: “Oh God Why?”》博客中, Jay Kreps 评论道:

“这也是我对于 Scala 宏指令的看法(Oh God Why?)。并不是因为宏指令或者这项提议有什么坏处,问题在于这真的是最重要的事情吗?”

Kreps 接下来列举了一系列更重要的事情,包括编译速度、IDE 支持、文档和编译文件大小。

支持 Kreps 观点的大有人在。Ivan Todoroski 在一封给 Scala 邮件列表的信中写到:

“在搜索问题的时候,Scala 宏指令看起来只是一个低级别的、hacking 风格的解决方案。它们在编写时太复杂,不太像 Scala 的风格,调试也麻烦,而且可能不过是为 Scala 的‘太多高深莫测的魔法’的形象增添了一笔。”

对此,Scala 的发明者 Martin Odersky 回复说:

“宏的设计初衷和 Scala 语言的其他一般设计一样,都是为了使事情简单化。我们已经实现通过宏替换代码,希望其他功能也能这样实现。比如说,有一种强推在某种情况下消除 atomic { implicit transaction => … }中的隐含参数和许多其他相关情形。有了宏,这类问题就微不足道了。”

围绕着 Scala 宏的讨论已经逐渐偃旗息鼓,社区成员们正在等着看最终的实现。最终发布的版本始终没有放弃在宏指令方面的冒险。许多社区内基于宏的项目已经逐渐生根发芽,包括:

Macrocosm ——测试宏指令实际用例的库。

Expecty ——Groovy 的 Spock 框架中的断言语句在 Scala 中的适应性改编。

Slick ——引进类似 LINQ 的数据库操作的尝试。Slick 能转化 Scala 语法为数据库查询。

ScalaMock ——Scala 的模拟对象测试库。

2.10.0-M4 发布说明里可以找到其他一系列 Scala2.10 中的功能,包括:

字符串插值

Futures 和 Promises

Value 类

动态类型

隐式类

Scala2.10 版马上就要发布了,Scala 开发团队号召人们试用最新的 milestone 发行版并提供反馈意见。你可以从这里下载最新版本


感谢杨赛对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2013-01-22 03:533385
用户头像

发布了 21 篇内容, 共 77429 次阅读, 收获喜欢 1 次。

关注

评论

发布
暂无评论
发现更多内容

腾讯云TDSQL数据库信创演进与实践

腾讯云数据库

tdsql 国产数据库

forEach、map和for循环

编程江湖

大前端

在线JSON转Schema工具

入门小站

工具

旺链科技团建图鉴 | 认真工作,肆意生活~

旺链科技

区块链 企业文化 团建

java开发之SSM开发框架的快速理解

@零度

ssm JAVA开发

一文解析Apache Avro数据

华为云开发者联盟

序列化 flink sql Apache Avro 反序列 Avro

从人工到智能!百度AI开发者大会分论坛,探寻国球乒乓背后的AI之路

百度大脑

人工智能

Iog4j2漏洞相关技术分析

极光GPTBots-极光推送

移动办公时代,数智化平台如何赋能企业管理升级?

BeeWorks

新年将至,惊喜来袭

云计算运维

消息队列存储消息数据设计

张靖

#架构实战营

这几个IDE是Node.js 开发人员需要知道的

@零度

node.js 前端开发

尚硅谷年终盘点|你好,2022;再见,2021

编程江湖

2022年新年祝福

TDSQL PostgreSQL如何快速定位阻塞SQL

腾讯云数据库

tdsql 国产数据库

WireShark好学吗?我来手把手教你学WireShark抓包及常用协议分析

学神来啦

网络安全 Wireshark 渗透测试 kali kali Linux

洞见科技携手阿里云,以“隐私计算+云”推动场景应用大规模落地

阿里云弹性计算

阿里云 数据安全 隐私计算

Dubbo为什么要用Go重写?

捉虫大师

Go dubbo

Linux之find exec

入门小站

☕【难点攻克技术系列】「海量数据计算系列」如何使用BitMap在海量数据中对相应的进行去重、查找和排序

码界西柚

BitMap bitmaps bitset 12月日更

大数据开发之Hive如何提高查询效率

@零度

大数据 hive

【签约计划第二季】百位签约创作者名单公布

InfoQ写作社区官方

签约计划第二季 热门活动

尚硅谷喜获央广网2021年度公信力教育品牌

编程江湖

教育

性能工具之常见压力工具是否能模拟前端?

zuozewei

前端 浏览器 性能分析 测试工具 12月日更

强强联袂!腾讯云TDSQL与国双战略签约,锚定国产数据库巨大市场

腾讯云数据库

tdsql 国产数据库

常用的echo和cat,这次让我折在了特殊字符丢失问题上

华为云开发者联盟

Linux cat echo 特殊字符 定向

强强联袂!腾讯云TDSQL与国双战略签约,锚定国产数据库巨大市场

腾讯云数据库

tdsql 国产数据库

尚硅谷年终盘点 | 你好,2022;再见,2021

@零度

尚硅谷喜获央广网2021年度公信力教育品牌

@零度

取代Maven?maven-mvnd持续霸榜 GitHub Trending,性能提升300%

沉默王二

maven

MongoDB按需物化视图介绍

MongoDB中文社区

mongodb

Greenplum内核源码分析-分布式事务(一)

王凤刚(ginobiliwang)

源码分析 分布式事务 greenplum

Scala语言将加入宏指令_Scala_Josh Suereth_InfoQ精选文章