scala 宏
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中的功能,包括:
Scala2.10版马上就要发布了,Scala开发团队号召人们试用最新的milestone发行版并提供反馈意见。你可以从这里下载最新版本。
scala 宏的更多相关文章
- 了解Scala 宏
前情回顾 了解Scala反射介绍了反射的基本概念以及运行时反射的用法, 同时简单的介绍了一下编译原理知识, 其中我感觉最为绕的地方, 就属泛型的几种使用方式了. 而最抽象的概念, 就是对于符号和抽象树 ...
- 一篇入门 — Scala 宏
前情回顾 上一节, 我简单的说了一下反射的基本概念以及运行时反射的用法, 同时简单的介绍了一下编译原理知识, 其中我感觉最为绕的地方, 就属泛型的几种使用方式了. 而最抽象的概念, 就是对于符号和抽象 ...
- 了解Scala反射
本篇文章主要让大家理解什么是Scala的反射, 以及反射的分类, 反射的一些术语概念和一些简单的反射例子. 什么是反射 我们知道, Scala是基于JVM的语言, Scala编译器会将Scala代码编 ...
- [转] Scala 中的异步事件处理
在任何并发性应用程序中,异步事件处理都至关重要.无论事件的来源是什么(不同的计算任务.I/O 操作或与外部系统的交互),您的代码都必须跟踪事件,协调为响应它们而执行的操作.应用程序可以采用两种基本方法 ...
- 神奇的Scala Macro之旅(一)- 什么时候用宏
在Lisp语言中,macro是一个神器,可以“动态的生成代码”,然后被执行,这种方式给到Lisp无限的表达能力.除Lisp之外,很少有语言支持Macro这个特性,我记得 GWT之中曾经有一个类似的Ge ...
- Scala.js v0.1 发布,在浏览器直接运行 Scala
今天我们发布了 Scala.js 的首个版本,这个项目是在今年六月份的时候宣布的. 第一个版本支持的特性: 支持所有 Scala 特性,包括宏,不过有一些 语义上的区别 可非常好的跟 JavaScri ...
- Scala Error: error while loading Suite, Scala signature Suite has wrong version expected: 5.0 found: 4.1 in Suite.class
准备给scala项目引入单元测试 <dependency> <groupId>org.scalatest</groupId> <artifactId>s ...
- Scala语言初识
scala是一种集面向对象特性和函数式特性于一身并可运行在JVM上的强类型静态语言.因为可以运行在JVM上,并在设计时借鉴于大量的java语言特性,故可以和java互动并可以调用java相关类库,这让 ...
- Scala 的 Web 框架 Lift 开始 3.0 版本开发
Scala 的 Web 框架 Lift 开始 3.0 版本开发 http://demo.liftweb.net/ http://liftweb.net/download Lift 框架在不断的成长和改 ...
随机推荐
- 解析xml并且导入mysql
https://www.zhihu.com/question/28139319 解析超过500G的xml 写入mysql,如何尽快写入? 解析超过500G的xml 写入mysql,如何尽快写入? 现在 ...
- 1、启动oracle的步骤
1.启动oracle的步骤 Linux下启动oracle分为以下两步: 1.1.启动lsnrctl监听. 1.2.启动数据库实例. 2.启动oracle监听 首先登陆服务器,切换到oracle用户. ...
- web前端面试题总结
HTML Doctype作用? 严格模式与混杂模式如何区分?它们有何意义? (1).<!DOCTYPE> 声明位于文档中的最前面,处于 <html> 标签之前.告知浏览器的解析 ...
- CSS下拉列表错误纠正
上一篇关于CSS制作下来列表的错误纠正. 在上一篇中,用CSS只做了下拉列表,但是鼠标不放在导航栏上的时候,下拉列表也是出来的.具体错误就是 div ul{ list-style:none; max- ...
- Freemarker中日期时间格式出错
今天遇到一个奇怪的问题.同事访问我电脑发布的程序页面,freemarker日期格式报错.而其他电脑访问则没有问题. 先贴出错误信息. FreeMarker template error The str ...
- Mysql notes
1. 数据库操作 database management create database sampleDatabase; --创建数据库sampleDatabase show databases; - ...
- Javascript 知识点整理
1.十进制和十六进制相互转换 /* 十六进制转十进制 */ var test = FF; var x = parseInt(test ,16); //方法一 x = parseInt('0x'+tes ...
- DataTable转换为Json字符串的三种方法
//第一种:使用StringBuilder public string DataTableToJson(DataTable table) { var JsonString = new StringB ...
- 【java基础】成员变量和局部变量02
成员变量和局部变量(2) 成员变量的初始化和内存中的运行机制 当系统加载类或者创建类的实例的时候,系统会自动为成员变量分配内存空间,并自动指定初始值. package object; ...
- asp 使用TreeView控件
这段代码为了使用 TreeNodeCheckChanged 事件,会有回刷新的效果: 不喜欢的可查看改进版,利用js控制选择操作,无界面刷新, “http://www.cnblogs.com/GoCi ...