初窥Nemerle语言

Nemerle是Microsoft的研究项目之一,由 Wrocław 大学的Kamil Skalski、Michał Moskal、Prof. Leszek Pacholski、Paweł Olszt等人发明.

Nemerle是一种多范型的语言(面向对象和函数式),完全支持编译器宏(后来更多的是Lisp的变种,而不是C++),以及许多其他的东西。Nemerla与VS2010里发布的F#不同,后者是纯函数式语言。

Nemerle提供了与C#近似的语法和强大的元编程系统。有关meta-program可以参考:http://en.wikipedia.org/wiki/Metaprogramming

你可以在http://nemerle.org/Main_Page下载它的最新发布,在发布包中还带有与visual studio的集成的IDE,可以很方便地学习Nemerle语言,最新版本是0.9.7(莫大鼓舞,快发布正式release了呀)

[b]最传统的"Hello,World"[/b]
[code]
using System.Console;
class Hello {
static Main () : void {
WriteLine ("Hello, world!");
}
}
[/code]
Nemerle语言具有与C#近似的语法,无疑这使得学习曲线大幅下降。这里有几个与C#版"Hello,World"不同的地方:

1. void等返回类型都写到了右边的冒号后面
2. 在使用using的时候,引用的不单可以是命名空间(namespace),还可以引用类的成员,这样使得我们的WriteLine()函数都可以直接的使用。

[b]多范式语言[/b]

[code]
using System;
using System.Console;
using Nemerle.Utility;
using System.IO;
module Program
{
class LineCounter
{
public static Main():Void
{
def sr=StreamReader(@"c:\test.rb"); // (1)
mutable line_no = 0; // (2)
mutable line = sr.ReadLine ();
while (line != null) {
WriteLine (line);
line_no = line_no + 1;
line = sr.ReadLine ();
};
WriteLine ("Line count: {0}", line_no);
}
}
}

[/code]

这里和C#不同的地方,首先我们通过关键字def定义了一个值sr,我们并没有声明它的类型,编译器会根据上下文自动赋予类型,我们称之为类型推断(Type Inference)。而且new关键字也不需要了。后面的方法与C#完全一样,不再赘述。

在(2)的地方,我们用mutable(即:可变的)声明了一个值line_no,它很像C#里的变量,必须初始化才能使用,并且还可以改变它的值。它与(1)处的"@"C:\test.rb"不同,后者是一个不可变的值。

我们前面提过Nemerle是种多范式的语言,所以我们可以在需要的地方采用函数式编程,其他地方采用面向对象编程,无疑更具备灵活性。

上面的代码可以修改成
[code]
using System;
using System.Console;
using Nemerle.Utility;
using System.IO;
module Program
{
class FunctionalLineCounter
{
public static Main () : void
{
def sr = System.IO.StreamReader (@"C:\test.rb");
def read_lines (line_no : int) : int
{
def line = sr.ReadLine ();
if (line == null)
line_no //here
else {
System.Console.WriteLine (line);
read_lines (line_no + 1)
}
};
System.Console.WriteLine ("Line count: {0}", read_lines (0));
}
}
}
[/code]
这段程序从"//here"处结束并返回结果,而参数的累加结果正是最后输出的line_no的值.


文本文件有多少行,read_lines()函数就要执行几次,像使用while循环一样,只不过稍微换了一种思路。这时候可能您会考虑到使用递归而影响效率的问题,事实是当一个函数主体在调用另一个函数后执行完毕,没有创建任何新的堆栈,这被称作尾端调用(Tail Call),所以这段代码和while循环在效率上一样的。Nemerle尤其注重将循环写成递归的深入的理解.

[b]强大的宏[/b]

使用 Nemerle 宏(macros)可以产生新的语法。在Nemerler IDE中,添加一个macro project,并在你的程序里引用这个macro project.

[code]

using Nemerle.Compiler;
namespace Macro
{
macro forp (i, n , m , body) //(1)
syntax("forpermutation","(",i,"from", n,"to",m,")",body) //(2)
{
<[ for ($i = $n; $i <= $m; $i++) $body ]>
}

}
[/code]

在(1)处,我们定义了一个宏 forp,带有四个参数,参数默认类型是Expr,即表达式。
接下来,我们通过syntax定义了调用这个宏的语法,然后在<[...]>里定义宏的内容。

这个宏可以这样被调用
[code]
mutable i=0;
forpermutation(i from 3 to 4) printf("%d\r\n",i);
[/code]

这样我们就创造了一个新的语法。奇怪的是,我将from换成in,Nemerle则会报错,文档中并未给出原因,个人觉得应该避免用关键字来定义语法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值