利用C++、scala等语言的运算符重载功能定制领域特定语言(DSL,Domain-Specific Language )

news/2024/7/3 13:51:41 标签: 语言, scala, c++, d语言, 正则表达式, actionscript

http://hi.baidu.com/atry/blog/item/c4bc96ef7a1ac7e8cf1b3ef4.html

 

领域特定语言(DSL,Domain-Specific Language )是近年来的热门话题。关于DSL,有一个趋势就是在通用语言中集成DSL。

很多年以前,我们如果要在通用语言中使用DSL,通常需要用字符串,比如作数据库访问,就要拼接一串SQL语句。缺点有很多:a) 不自然,特殊字符需要转义;b) 容易留下SQL注入的漏洞;c) 缺乏语法检查,拼错了一个单词还要到运行时才能知道出错,调试起来麻烦。

不 过现在是二十一世纪了。许多语言都内置了一些DSL。比如JavaScript、ActionScript等ECMAScript语言中的新特性E4X, 可以方便的使用XML和XPath。再比如说C# 3.0中的LINQ表达式,可以写SQL查询。这是一个很好的现象,不过本文所讲的则是“定制”DSL,可以不仅仅用上语言本身提供的DSL,还能创建自 己的DSL.

这可以靠运算符重载实现。我最早接触运算符重载是C++,这个特性原本并未打算用来设计DSL,只是希望简化一些日常操作的 代码,比如字符串连接。不过现在是二十一世纪了。终于出现了一群变态程序员把这个特性的潜力挖掘了出来。boost中的许多库都用运算符重载实现了 DSL,比如Boost.Xpressive(实现了正则表达式)、Boost.Spirit(实现了BNF范式)、Boost.Phoenix(实现了 匿名函数声明或者说Lambda表达式)。我自己也用运算符重载实现过static_lambda,可以把一个匿名函数变成一个静态类型的类,用到模板参 数里面。

根据我用过的经验,这个技术是有用的,Boost.Xpressive和Boost.Spirit都很实用。

不过用C++运算符重载实现的DSL还是有很多致命问题的:
1. C++98的模板缺少可变数量的模板参数这个特性。
2. C++98的左值右值引用的匹配有严重缺陷。
3. C++编译速度太慢。
4. C++不支持重载空格。

前两个问题是C++98的问题,再过几年如果C++0x普及了就解决了。
第三个问题是老大难问题,估计等到太阳变成红色巨星的时候都未必能解决。不过C++倒是有其继承者D语言,编译速度奇快无比,用来定制DSL倒是不错,只不过现在用D语言做应用开发又缺乏相应的库、IDE啥的,因而D语言开发的项目很罕见。
第四个问题会导致DSL的语法不能很干净,比如正则表达式里面就得加入 << ,看着有点乱。这个问题运算符重载解决不了,因为运算符重载原本就没打算还有这么变态的功能。

不 过C++本来定位就是有高级特性的底层语言,我们做应用开发的,大多数情况还是用更上层的语言,比如Java、C#、Ruby啥的,来连连数据库、画画网 页。C++的死活于我何相干?我关心的是应用,关心怎么在我现在的Java项目中用上内嵌的XML、SQL之类的东西。Java写SQL用的 PreparedStatement很恶心的一点就在于我要去数问号,设一个参数还得去数数那是第几个问号,很让人吐血。

所以这里我要推荐的是scala,兼容Java字节码,也可以生成兼容.net的cli,能无缝集成到现有系统。这个scala里面就有一个数据库连接的库,可以内嵌SQL语句到代码中:
object foo extends Application {

import scala.dbc._
import scala.dbc.Syntax._
import syntax.Statement._

val db = database("jdbc:postgresql://localhost/test","myUserName","")

val res = db.executeStatement {
select fields ("name" of characterVarying(50)) from "person"
}

for(val i <- res;
val f <- i.fields) {
Console.println(f.content.sqlString)
} }
这里面的SQL语句并非语言原生支持,而是依靠库实现的,所以很牛叉。
不过只要搞清楚实现,就知道其实一点都不牛叉,因为scala的语法里面可以省略访问成员用的“.”以及函数调用的括号,所以实际上上面那一句
select fields ("name" of characterVarying(50)) from "person"
等价于
select.fields("name" of characterVarying(50)).from("person");
这只不过就是一段函数调用而已。

虽 然这个SQL语法scala只用了一些小把戏就实现了,不过scala是个强类型的语言,运算符重载、自动推断类型等特性它都有,而且又没有C++那样的 缺陷,确实很容易实现任何DSL。此外Java社区争论了很多年的closure它早就有了,还有一大堆函数式编程的,算是Haskell和Java的混 合体吧,既可以干Java干的日常工作,又有小朋友们不会用的牛叉的高级特性。所以,scala是个很好玩的东西,而且比较实用,应该会有前途,值得关注。

 


http://www.niftyadmin.cn/n/1605012.html

相关文章

刷脸支付机会是留给敢迈出第一步的人

从支付宝推出余额宝、花呗等功能大幅培养用户理财习惯&#xff0c;到微信支付通过微信红包打通朋友圈&#xff0c;微信支付和支付宝的擂台之战从未平息&#xff0c;面对10亿交易笔数到20亿的跨越&#xff0c;较量已经从扫码支付延伸至了各式各样的甚至难啃的场景&#xff0c;比…

让你刷剧一直爽,CDN原理是什么丨技术前沿

鼠年春节&#xff0c;一个特别的春节。受疫情影响&#xff0c;假期比往年长了一些。这么长时间宅在家中&#xff0c;想必大家除了睡觉&#xff0c;花费时间最多的就是“刷剧”了。今天讲的技术主题就和“刷剧”有关&#xff0c;它是CDN。我们通过观察CDN的技术来看CDN的产业发展…

微信青蛙和会员让消费者看得见优惠

双面屏的设计可以及时地建立收银员于消费者的沟通关系。通过背屏&#xff0c;收银员可以把许多智慧营销的内容及时地推送到前屏&#xff0c;提高商户的复购率以及店铺管理效率&#xff0c;比如选择推送商户公众号的二维码&#xff0c;消费者可以在支付时直接完成关注&#xff0…

“云旅游”之外最值得期待的是什么?云原生直播来啦!

“云蹦迪”、“云旅游”、“云聚会”近来成了娱乐生活的热门&#xff0c;“云”的概念随处可见。作为云计算领域的热门话题&#xff0c;怎么能不来聊聊“云原生”呢&#xff01;Gartner预测&#xff0c;到2022年&#xff0c;全球有75%的企业将会使用基于云原生的容器技术构建它…

WebDSL:DSL设计案例

http://www.kuqin.com/system-analysis/20080704/10385.html Eelco Visser是荷兰Delft University of Technology大学的副教授&#xff0c;他讲授的课程是“程序变换和自动生成&#xff08;Program Transformation & Generation&#xff09;”。 他刚刚完成了一篇题为《W…

刷脸设备引进越来越多的人喜欢靠脸消费

刷脸支付已经成为今年比较热门的一个话题了&#xff0c;随便刷个新闻、微博或各大网络平台等都不免会看到有关刷脸支付的消息。感觉不了解刷脸支付就好像与这个时代脱离轨道了似的。那么今天就来给大家讲一讲刷脸支付对于消费者和商家各具有优势它比扫码支付更加安全便捷。 据…

物可视仪表盘模板,让大屏开发瞬时可达

大屏开发是门艺术&#xff0c;技术和审美缺一不可&#xff01;但在现实生活中&#xff0c;这两者却往往像鱼与熊掌&#xff0c;难以兼得。对于开发人员来说&#xff0c;功能实现驾轻就熟&#xff0c;但在样式设计、图表布局、色彩搭配上&#xff0c;耗费大量精力也未必尽如人意…

刷脸优惠政策置顶此时不入局更待何时

现在&#xff0c;刷脸支付随着支付宝跟微信两大巨头的疯狂热推&#xff0c;让很多人开始发现了新的机遇方向标。但同时&#xff0c;也出现了很多不一样的声音。最多的&#xff0c;还是跟我担心聚合支付时一样&#xff0c;安全支付的安全问题再次被摆在了眼前。 然后几年过去&a…