DSL与函数式编程

一直看到这个英文缩写,但是不知道它具体是啥东西,google几次都讲的非程序层面的意思,找到一篇还不错的介绍文章,转载过来...

出自:http://mzhou.me/?p=95219

什么是DSL?

DSL即领域编程语言,它是用于解决特定领域问题的语言。与GPPL(通用目的编程语言)相比,DSL针对的目标是特定的领域。其实DSL并不是什么高深的东西,SQL、正则表达式、CSS等等都是一种DSL。对于前端工程师来说jQuery就是一种DSL。

DSL可以分为两种:内部DSL、外部DSL。外部DSL是自我包含的语言,它们有自己特定语法、解析器和词法分析器等等,它往往是一种小型的编程语言,甚至不会像GPPL那样需要源文件。与之相对的则是内部DSL。内部DSL其实更像是种别称,它代表一类特别API及使用模式[1]。jQuery就是一种内部DSL,而CSS则是一种外部DSL。

$(".selector").text("display text")
.append("<div>children</div>")
.show();

使用DSL的好处就是:我们可以更关注做什么(What)而不是怎么做(How)!
jQuery是一门用于解决多种浏览器上javascript 执行兼容性的DSL,它提供了一组API用于Web前端开发的通用功能:DOM、AJAX、Event等等。众所周知,浏览器的兼容性是前端开发中最难解决的问题,而使用jQuery可以避免多数bad parts,只使用Good parts。这样我们在开发时就可以更关注做什么(What),而不用管底层的浏览器js是怎么做(how)的。

函数式编程

编程语言的进化史是这样的:

  1. 打孔机,机器语言(记得操作系统课上老师展示过…)
  2. 汇编语言:最底层的操作都通过代码来指定
  3. 面向过程语言:Picasal、C
  4. 面向对象语言:C++
  5. 虚拟机时代(垃圾收集、类型安全):Java、C#
  6. 动态语言:Python、Ruby

扯的有点远了,我想说的是:编程语言越来越抽象了…

在数学中函数的抽象定义是元素(输入)与元素(输出)之间的对应数学关系。例如:y=f(x)定义了x与y之间的数学关系,函数计算完成之后x的值不会改变,并返回一个输出y。

在编程语言中为了重复利用一些特定操作,于是产生了函数。函数被定义为:根据输入计算得到输出的一批程序指令。函数计算完成之后输入可能会改变,并返回一个输出或不返回。

编程语言中的函数与数学函数最大的区别在于:函数是有状态的,它可以修改外部变量或输入变量。而数学函数没有状态、没有变量。并且程序语言的函数除了计算值之外还可以做些额外的操作。这些操作可以是:打印日志、调整显示GUI等等。

函数式编程的定义是:将计算等同于数学函数的编程范式。“函数式编程”中的函数是数学函数而不是一般程序语言中的函数。

函数式编程与一般的命令式编程的区别:

//命令式编程:
function Counter(_i) {
    var i = _i || 0;
    this.add = function(j) {
        i = i+j;
    }
}
//函数式编程:
function Counter(_i) {
    var i = _i || 0;
    this.add = function(j) {
        return new Counter(i+j);
    }
}

两者的区别在于函数式编程的add方法并没有修改i变量,也就是Counter没有可变的状态。这赋予了函数式编程最大的优点:线程安全。虽然前端的javascript开发并没有涉及到多线程的情况,不过随着HTML5的普及,WebWorker的出现也会使的javascript渐渐出现多线程并行问题。

当然函数式编程的优点并不只在于线程安全这一个,而且更在于它在某些情况下的结构清晰,例如:修改给所有数组中的值加1。

//命令式编程:
function add(array) {
    for (var i=0,length=array.length;i&lt;length;i++)
        array[i]++;
}
//函数式编程:
function add(n) { return n+1; } //不修改输入变量
_(array).map(add);

两端段代码,相比之下后者的结构更加清晰,因为它相比命令式编程更进一步抽象了。函数式编程达到了和DSL一样的目的:我们可以更关注做什么(what)而不是怎么做(how),提供更清晰的代码结构。除了例子中map之外,还有延迟计算、Memorization等等这些都是函数式编程中的Good parts。

之前那段代码中用到了一个javascript库就是understandcore.js,这个库提供了在js中实现函数式编程的功能。当然做到完全的使用函数式编程是不可能的!

  1. 因为我们总会遇到需要在函数中做其他操作的情况,例如打印日志;
  2. 还有性能问题,第一个例子中函数式编程明显在性能上有很大劣势;

所以“函数式编程”也需要在适当的时候使用才能发挥作用,不能滥用!

参考:

[1].http://blog.zhaojie.me/2010/04/trends-and-future-directions-in-programming-languages-by-anders-2-declarative-programming-and-dsl.html

[2].http://news.csdn.net/a/20100311/217407.html

[3].http://en.wikipedia.org/wiki/Functional_programmin

posted @ 2011-08-30 10:40  三桂  阅读(2158)  评论(0编辑  收藏