初探微軟多范型語言Nemerle
Nemerle是微軟的研究項目之一,由 Wrocław 大學(xué)的Kamil Skalski、Michał Moskal、Prof. Leszek Pacholski、Paweł Olszt等人發(fā)明.
Nemerle是一種多范型語言(面向?qū)ο蠛秃瘮?shù)式),完全支持編譯器宏(后來更多的是Lisp的變種,而不是C++),以及許多其他的東西。Nemerla與VS2010里發(fā)布的F#不同,后者是純函數(shù)式語言。
Nemerle提供了與C#近似的語法和強大的元編程系統(tǒng)。有關(guān)meta-program可以參考:http://en.wikipedia.org/wiki/Metaprogramming
你可以在http://nemerle.org/Main_Page下載它的***發(fā)布,在發(fā)布包中還帶有與visual studio的集成的IDE,可以很方便地學(xué)習(xí)Nemerle這種多范型語言,***版本是0.9.7。
最傳統(tǒng)的"Hello,World"
- using System.Console;
- class Hello {
- static Main () : void {
- WriteLine ("Hello, world!");
- }
- }
Nemerle語言具有與C#近似的語法,無疑這使得學(xué)習(xí)曲線大幅下降。這里有幾個與C#版"Hello,World"不同的地方:
1. void等返回類型都寫到了右邊的冒號后面
2. 在使用using的時候,引用的不單可以是命名空間(namespace),還可以引用類的成員,這樣使得我們的WriteLine()函數(shù)都可以直接的使用。
多范型語言
- 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#不同的地方,首先我們通過關(guān)鍵字def定義了一個值sr,我們并沒有聲明它的類型,編譯器會根據(jù)上下文自動賦予類型,我們稱之為類型推斷(Type Inference)。而且new關(guān)鍵字也不需要了。后面的方法與C#完全一樣,不再贅述。
在(2)的地方,我們用mutable(即:可變的)聲明了一個值line_no,它很像C#里的變量,必須初始化才能使用,并且還可以改變它的值。它與(1)處的"@"C:\test.rb"不同,后者是一個不可變的值。
我們前面提過Nemerle是種多范型的語言,所以我們可以在需要的地方采用函數(shù)式編程,其他地方采用面向?qū)ο缶幊蹋瑹o疑更具備靈活性。
上面的代碼可以修改成
- 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));
- }
- }
- }
這段程序從"http://here"處結(jié)束并返回結(jié)果,而參數(shù)的累加結(jié)果正是***輸出的line_no的值.
文本文件有多少行,read_lines()函數(shù)就要執(zhí)行幾次,像使用while循環(huán)一樣,只不過稍微換了一種思路。這時候可能您會考慮到使用遞歸而影響效率的問題,事實是當(dāng)一個函數(shù)主體在調(diào)用另一個函數(shù)后執(zhí)行完畢,沒有創(chuàng)建任何新的堆棧,這被稱作尾端調(diào)用(Tail Call),所以這段代碼和while循環(huán)在效率上一樣的。Nemerle尤其注重將循環(huán)寫成遞歸的深入的理解.
強大的宏
使用 Nemerle 宏(macros)可以產(chǎn)生新的語法。在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,帶有四個參數(shù),參數(shù)默認(rèn)類型是Expr,即表達(dá)式。 接下來,我們通過syntax定義了調(diào)用這個宏的語法,然后在<[...]>里定義宏的內(nèi)容。
這個宏可以這樣被調(diào)用
- mutable i=0;
- forpermutation(i from 3 to 4) printf("%d\r\n",i);
這樣我們就創(chuàng)造了一個新的語法。奇怪的是,我將from換成in,Nemerle則會報錯,文檔中并未給出原因,個人覺得應(yīng)該避免用關(guān)鍵字來定義語法。
【編輯推薦】