`

初窥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了呀)

最传统的"Hello,World"
using System.Console;
class Hello {
  static Main () : void {
    WriteLine ("Hello, world!");
  }
}

Nemerle语言具有与C#近似的语法,无疑这使得学习曲线大幅下降。这里有几个与C#版"Hello,World"不同的地方:

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

多范式语言

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);
        }
    }
}



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

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

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

上面的代码可以修改成
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));   
    } 
  }
}

这段程序从"//here"处结束并返回结果,而参数的累加结果正是最后输出的line_no的值.


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

强大的宏

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


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 ]>
    }
 
}


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

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


这样我们就创造了一个新的语法。奇怪的是,我将from换成in,Nemerle则会报错,文档中并未给出原因,个人觉得应该避免用关键字来定义语法。

1
1
分享到:
评论
9 楼 jonathan_zz 2009-06-25  
有些类似Scala,宏看起来比较有意思
8 楼 RednaxelaFX 2009-06-23  
night_stalker 写道
问个小白问题:这个能省略行末分号吗?
[quote=]semicolons are optional at the end of code blocks.

7 楼 night_stalker 2009-06-23  
问个小白问题:这个能省略行末分号吗?
6 楼 ray_linn 2009-06-23  
不过扩展属性和扩展事件好像是没希望了。。。。
5 楼 RednaxelaFX 2009-06-23  
去年VS2010 CTP的时候我跑到feedback论坛去提feature request,希望C# 4能支持statement lambda转换成Expression Tree,结果没下文。上个月还是再之前一个月问Eric Lippert为什么决定不实现这个功能,他说其实不是不想实现,而是在C# 4的周期内来不及了。编译器里有些遗留设计阻碍了他们干净的实现这功能,所以他们一直在重构,据说最近已经把阻碍因素重构得差不多了,所以C# 5看来还是有指望看到这功能实现出来的~
4 楼 ray_linn 2009-06-23  
我觉得目前C# 4.0已经是比较完美的一个版本了(当然我对C# 5.0里的从源代变成表达式树也是很感兴趣),是否再进一步引入动态语言的语法,不过Anders这个大天才,引领者静态语言走向新的天地,还有什么想法就不得而知了。

Microsoft成就了Anders,Anders成就了C#.
3 楼 RednaxelaFX 2009-06-23  
Anders和设计组的想法似乎是,“既然现实中我们无法不面对一些动态的状况,干脆就在语言里支持动态特性,保持代码的干净”。所以增加dynamic之后,C#仍然是完好的静态类型语言,只是多了一个称为dynamic的静态类型而已。这样,如果我们需要从C#使用JavaScript/Python/Ruby等语言写的库或者脚本,就能用正常的C#语言来使用而不必自己写一大堆显式的反射调用。正是有了这样的支持,我们才可以更好的“把动态化、函数化的部分委托给其他的语言”,对吧?
2 楼 ray_linn 2009-06-23  
我有时候在想C#是否还需要动态化?完全可以把动态化、函数化的部分委托给其他的语言,最后在C#中将所有部分集合在一起...是否更具备效率。
1 楼 RednaxelaFX 2009-06-23  
Nemerle一直在玩。把类型标记放到声明的后面对简化解析器是有好处的,不过要是在声明成员的时候能在开头用不同的关键字标识出来就更方便些,例如用var/val/fun/function之类的。现在这种语法要到声明中标识符之后看看有没有左括号才能区别是方法声明还是域声明,解析起来没比C#的容易多少。

觉得比较怨念的一个feature是它没有multi-method。JVM上的Nice语言对multi-method的支持我就挺喜欢的~

相关推荐

    nemerle:Nemerle语言。 主仓库

    Nemerle是用于.NET平台的高级静态类型编程语言。 它提供功能,面向对象和命令式功能。 它具有简单的类似于C#的语法和功能强大的元编程系统。 来自功能领域的功能包括变体,模式匹配,类型推断和参数多态性(又名...

    NemerleWeb:Nemerle Web MVVM框架

    NemerleWeb是用于.Net的Web 库。 它使用React性数据模型,该模型允许创建丰富的Internet应用程序。 ## NemerleWeb的新手? 该站点包含您需要的所有内容:教程和示例。... Nemerle.Peg已获得Nemerle许可: 。

    Compiler tools for Nemerle-开源

    RiDL是一套工具,可以简化使用Nemerle的编译器的构建。 它包括一个词法分析器生成器和一个解析器生成器。

    NUDA-开源

    NUDA(= Nemerle统一设备体系结构)是Nemerle编程语言的一组扩展,可以促进GPU编程和编写HPC应用程序。 它的主要目的是为HPC应用程序尝试可扩展的语言

    nitra:Nitra是语言工作台

    您可以使用Nitra创建或扩展通用编程语言或特定领域语言(DSL)。 目前,Nitra允许您创建动态扩展的解析器。 将来,Nitra将允许创建对编程语言的完全支持:编译器,IDE支持。 许可证— -聊天进行互动讨论-从源头构建...

    MonoDevelop-3.0.4.6

    MonoDevelop 是个适用于Linux、Mac OS和Microsoft Windows的开放源代码集成开发环境,主要用来开发Mono与.NET Framework...目前支援的语言有Python、Vala、C#、Java、BOO、Nemerle、Visual Basic .NET、CIL、C与C++。

    安卓语法高亮编辑器HighlightTextEditor.zip

    chill.lang idlang.lang nemerle.lang rpg.lang clean.lang inc_luatex.lang netrexx.lang rpl.lang clearbasic.lang informix.lang nice.lang rs.lang clipper.lang ini.lang nsis.lang ruby.lang 支持的配色...

    Nitra:Nitra公共仓库

    您可以使用Nitra创建或扩展通用编程语言或特定领域语言(DSL)。 目前,Nitra允许您创建动态扩展的解析器。 将来,Nitra将允许创建对编程语言的完全支持:编译器,IDE支持。 许可证— -聊天进行互动讨论 -设置...

    ZenSharp:ZenSharp for ReSharper是对类固醇的助记符!

    ReSharper ZenSharp插件用于定义活动模板项目的快捷方式语言。 您可以使用灵活的语言指定自己的实时模板方案。我如何得到它? 您可以通过ReSharper菜单中的Extension Manager直接安装到ReSharper 8.2…2020.3中。...

    Total Commander(TC)的CudaLister插件(32位和64位),含223个语法高亮文件,可预览大量文本文件类扩展名

    Nemerle.lcf R Markdown.lcf BibTeX.lcf OpenCL.lcf VBScript.lcf D.lcf Nim.lcf ABAP.lcf Visual dBase.lcf Visual Basic.lcf Prolog.lcf Asymptote.lcf Verilog HDL.lcf Pike.lcf MIPS Assembly.lcf...

    RecSharp:.NET的不可变记录生成器

    RecSharp RecSharp是用于.NET的不可变记录生成器不可变记录类似于F#的记录或Scala的案例类,但可以在C#中安全使用。 这是样本记录定义(您可以在sample.rcs中找到它) namespace Records { using System ;...

    LogGrok:LogGrok日志查看器

    LogGrok是具有可自定义的停靠窗口UI的多文件日志查看器。 主要特点: •支持大文件•按任意字段(包括RegEx)搜索•多个搜索结果•按任意字段过滤MSI,VB,...下载 ClickOnce安装程序在 更多信息: 提交您的反馈: :

Global site tag (gtag.js) - Google Analytics