Nemerle

Nemerle
Nemerle
Paradigm(s) multi-paradigm: metaprogramming, functional, object-oriented, imperative
Appeared in 2003
Designed by Kamil Skalski, Michał Moskal, Prof. Leszek Pacholski and Paweł Olszta at Wrocław University
Stable release 1.0.0 (May 13, 2011 (2011-05-13))
Typing discipline static, strong, inferred, nominal
Major implementations Nemerle
Influenced by C#, ML, Lisp
Platform CLI (.Net & Mono)
Usual filename extensions .n
Website http://nemerle.org

Nemerle is a general-purpose high-level statically typed programming language for the .NET (see also Mono) platform. It offers functional, object-oriented and imperative features. It has a simple C#-like syntax and a powerful metaprogramming system.

It has been named after the Archmage Nemmerle, a character in the fantasy novel A Wizard of Earthsea by Ursula K. Le Guin (spelling with a single m is a design decision).

Contents

Features

The most important feature of Nemerle is the ability to mix object oriented and functional programming styles. The top-level program structure is object oriented, while in the body of methods one can (but is not forced to) use functional style. Nemerle key features are:

  • strong type inference (the best among the languages supporting subtypes and inheritance)
  • flexible and very powerful metaprogramming subsystem (using macros)
  • full support for OOP (which will be familiar to C# / Java / C++ — programmers)
  • full support for functional programming inherited from the ML family of languages (ML, OCaml, F#, Haskell) with following features:

The metaprogramming system allows great compiler extensibility, embedding domain specific languages, partial evaluation and aspect-oriented programming, taking a high-level approach to lift as much of the burden from the programmer as possible. The language combines all CLI standard features, including parameter polymorphism, lambdas, extension methods etc. The usage of more mundane library functionality from .NET and Mono is as easy as in C#.

Type inference

def x = 1; // int
def myList = List(); // generic List[T], type T is deduced from the usage in the next line
myList.Add(x);       // compiler deduces type of T as int making myList type of List[int]

Everything is an expression

def x =
  { // similar to x = 3
    def y = 1;
    def z = 2;
    y + z   // this last statement is a block return value
  };
 
def x =
  if (DateTime.Now.DayOfWeek == DayOfWeek.Monday)  // if, using, try  are also expressions
    "Monday"
  else
    "other day";
 
def x = try { int.Parse(someString) }
        catch { | FormatException() => 0 };
 
def x = returnBlock : 
  {
    foreach (i in [1, 2, 3])
      when (i > 2)
        returnBlock(true); // exit block (x = true)
 
    false // x = false
  };

Tuples

def k = (1, "one"); // k : (int * string)
def (a, b) = k; // a = 1, b = "one"

Pattern matching

def result = match (number)
{
  | 0            => "zero"
  | 1            => "one"
  | x when x < 0 => "negative"
  | _            => "more than one"
}

Functional types and local functions

using System.Console; // classes and modules (static classes) can be put in namespaces
def next(x) { x + 1 }; // the type of x argument and other function arguments can be deduced from usage
 
def mult(x, y) { x * y };
 
def fibbonacci(i)
{
  | 0     => 0
  | 1     => 1
  | other => fibbonacci(i - 1) + fibbonacci(i - 2)
};
 
WriteLine(next(9));        // 10  similar to "Console.WriteLine(next(9));" 
WriteLine(mult(2, 2));     // 4
WriteLine(fibbonacci(10)); // 55

Variants

Variants (called data types or sum types in SML and OCaml) are forms of expressing data of several different kinds:

 variant RgbColor{
   | Red
   | Yellow
   | Green
   | Different {
       red : float;
       green : float;
       blue : float;
     }
 }

Metaprogramming

Nemerle allows to create, analyze and modify code of a program during a compilation process using a powerful macro system. Macros can be used in a form of a method call or even a new language construction. Most of the Nemerle language constructions are macros (if, for, foreach, while, using etc.).

"if" macro example:

macro @if (cond, e1, e2)
syntax ("if", "(", cond, ")", e1, Optional (";"), "else", e2)
{
  /*
    <[ ]> defines an area of quasi-quotation, the Nemerle compiler transforms a code in a such block
    to an AST tree, such transformations are somewhat similar to an Expression compiling in C#
  */
  <[
    match ($cond : bool)
    {
      | true => $e1
      | _ => $e2
    }
  ]>
}
 
// using this macro in code:
def max = if (a > b) a else b;
// during a compile time the upper line will be transformed to the following:
def max = match (a > b)
{
  | true => a
  | _    => b
}

IDE

Nemerle can be integrated into Visual Studio 2008. Also it has a completely free IDE based on Visual Studio 2008 Shell[1] (like Visual Studio Express Editions) and SharpDevelop (link to plugin source code).

Examples

Hello, World!

The traditional "Hello World!" can be implemented in a more C#-like fashion:

class Hello
{
  static Main () : void
  {
    System.Console.WriteLine ("Hello, world!");
  }
}

or more simply:

System.Console.WriteLine("Hello, world!");

Examples of macros

Macros allow generation of boilerplate code with additional static checks performed by the compiler. They reduce the amount of hand writing, make code generation safer, and enable programmatic generation of code with compiler checks, while keeping source code relatively small and readable.

String formatting

The string formatting macro simplifies variable to string manipulations using $ notation:

def s = $"The number is $i"; //insert the value of the variable i where $i is placed 
def s = $"$x + $y = $(x+y)"; // $(...) can be used to make calculations or access members

Declarative code generation

StructuralEquality, Memoize, json, and with are macros which generate code in compile time. Although some of them (StructuralEquality, Memoize) can look like C# attributes, during compile time they will be examined by the compiler and transformed to appropriate code using logic predefined by their macros.

[StructuralEquality] // Implement IEquatable[Sample] .Net interface using by element comparsion equality.
class Sample
{
   [Memoize]  // remember first evaluation result 
   public static SomeLongEvaluations() : int  
   {
       MathLib.CalculateNthPrime(10000000)
   }
 
   [DependencyProperty] // WPF dependency property
   public DependencyPropertySample { get; set; }
 
   public static Main() : void
   {
/* syntax macro "json" generates code: 
JObject.Object([("a", JValue.Number(SomeLongEvaluations())), ("b", JValue.Number(SomeLongEvaluations() + 1))])
*/
       def jObject = json { a: SomeLongEvaluations(); b: (SomeLongEvaluations() + 1)} 
// object initalization macro "<-" is development of C# curly brackets object initialization
       def k = Diagnostics.Process() <- 
       {
          StartInfo <- // can init inner objects properties without ctor call
          {
              FileName = "calc.exe";
              UseShellExecute = true;
          }   
          Exited += () => WriteLine("Calc done"); // events and delegates
       }
 
       ReadLine();
   }
}

Database accessibility

Using Nemerle macros for SQL you can write:

ExecuteReaderLoop("SELECT firstname, lastname FROM employee WHERE firstname = $myparm", dbcon,
  {
    WriteLine ($"Name: $firstname $lastname")
  });

instead of

string sql = "SELECT firstname, lastname FROM employee WHERE firstname = :a";
using (NpgsqlCommand dbcmd = new NpgsqlCommand (sql, dbcon, dbtran))
{
  dbcmd.Parameters.Add("a", myparm);
 
  using (NpgsqlReader reader = dbcmd.ExecuteReader())
  {
     while(reader.Read()) 
     {
        var firstname = reader.GetString (0);
        var lastname = reader.GetString (1);
        Console.WriteLine ("Name: {0} {1}", firstname, lastname)
     }
  }
}

and this is not just hiding some operations in a library, but additional work performed by the compiler to understand the query string, the variables used there, and the columns returned from the database. The ExecuteReaderLoop macro will generate code roughly equivalent to what you would have to type manually. Moreover, it connects to the database at compilation time to check that your SQL query really makes sense.

New language constructs

With Nemerle macros you can also introduce some new syntax into the language:

macro ReverseFor (i, begin, body)
syntax ("ford", "(", i, ";", begin, ")", body)
{
  <[ for ($i = $begin; $i >= 0; $i--) $body ]>
}

defines a macro introducing the ford (EXPR ; EXPR) EXPR syntax and can be used like

ford (i ; n) print (i);

Nemerle with ASP.NET

Nemerle can be either embedded directly into ASP.NET:

<%@ Page Language="Nemerle" %>
<script runat="server">
 
    Page_Load(_ : object, _ : EventArgs) : void {
        Message.Text = $"You last accessed this page at: $(DateTime.Now)";
    }
 
    EnterBtn_Click(_ : object, _ : EventArgs) : void {
        Message.Text = $"Hi $(Name.Text), welcome to ASP.NET!";
    }
 
</script>
 
<html>
    <body>
        <form runat="server">
            Please enter your name: <asp:TextBox ID="Name" runat="server" />
            <asp:Button OnClick="EnterBtn_Click" Text="Enter" runat="server" />
 
            <p><asp:Label ID="Message" runat="server" /></p>
        </form>
    </body>
</html>

...Or stored in a separate file and entered with a single line:

<%@ Page Language="Nemerle" Src="test.n" Inherits="Test" %>

PInvoke

Nemerle can take advantage of native platform libraries. The syntax is very similar to C#'s and other .NET languages. Here is the simplest example:

using System;
using System.Runtime.InteropServices;
 
class PlatformInvokeTest
{
    [DllImport("msvcrt.dll")]
    public extern static puts(c : string) : int;
 
    [DllImport("msvcrt.dll")]
    internal extern static _flushall() : int;
 
    public static Main() : void
    {
        _ = puts("Test");
        _ = _flushall();
    }
}

References

  1. ^ Nemerle Studio Microsoft Setup Installer can be installed after installation of Visual Studio Shell 2008 Isolated

Further reading

External links


Wikimedia Foundation. 2010.

Игры ⚽ Нужен реферат?

Look at other dictionaries:

  • Nemerle — Семантика: мультипарадигменный, объектно ориентированный, функциональный, императивный Тип исполнения: компилируемый Появился в: 0.9.3 16 мая …   Википедия

  • Nemerle — Funktionale Sprache Basisdaten Paradigmen: objektorientiert, imperativ, funktional …   Deutsch Wikipedia

  • Сравнение языков программирования — Эту статью следует викифицировать. Пожалуйста, оформите её согласно правилам оформления статей.  Условные обозначения  …   Википедия

  • List of programming languages by category — Programming language lists Alphabetical Categorical Chronological Generational This is a list of programming languages grouped by category. Some languages are listed in multiple categories. Contents …   Wikipedia

  • Liste der .NET-Sprachen — Die folgende Aufstellung enthält eine Liste von Programmiersprachen für Microsoft .NET, Mono, DotGNU oder einer kompatiblen Laufzeitumgebung. Sprache Implementierung Hersteller Ada 2005 A# (Ada for .NET) APL Dyalog.NET ASP ASP.NET: ASM to IL …   Deutsch Wikipedia

  • C++ — У этого термина существуют и другие значения, см. C. См. также: Си (язык программирования) C++ Семантика: мультипарадигмальный: объектно ориентированное, обобщённое, процедурное, метапрограммирование Тип исполнения: компилируемый Появился в …   Википедия

  • Comparison of programming languages (list comprehension) — Programming language comparisons General comparison Basic syntax Basic instructions Arrays Associative arrays String operations …   Wikipedia

  • Liste von Hallo-Welt-Programmen/Programmiersprachen — Dies ist eine Liste von Hallo Welt Programmen für gebräuchliche Programmiersprachen. Weitere Beispiele für grafische Benutzeroberflächen, Web Technologien, exotische Programmiersprachen und Textauszeichnungssprachen sind unter Liste von Hallo… …   Deutsch Wikipedia

  • Язык функционального программирования — Функциональное программирование объединяет разные подходы к определению процессов вычисления на основе достаточно строгих абстрактных понятий и методов символьной обработки данных. Сформулированная Джоном Мак Карти (1958) концепция символьной… …   Википедия

  • Алгебраический тип данных — в теории программирования любой тип, значения которого являются значениями некоторых иных типов, «обёрнутыми» конструкторами алгебраического типа. Другими словами, алгебраический тип данных имеет набор конструкторов типа, каждый из которых… …   Википедия

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”