Nemerle

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 12:01, 2 июня 2016.
Nemerle
Nemerle Logo.png
Парадигма мультипарадигменный, объектно-ориентированный, функциональный, императивный
Спроектировано Вроцлавский университет; Михал Москаль, Камиль Скальски, Павел Ольшта и др.
Разработчики JetBrains
Первый   появившийся 2003
Стабильная версия 1.0 Google Code GitHub / 5 декабря 2011
Печать дисциплины статическая
Портал: http://nemerle.org/About/
Под влиянием
C#, ML, OCaml, Haskell, Лисп

Nemerle — гибридный язык высокого уровня со статической типизацией,вобравший в себя возможности функционального и объектно-ориентированного программирования, для платформ .NET и Mono (язык компилируется в CIL и является CLS-совместимым).Особенностью языка является развитая система метапрограммирования.

История

Разработкой языка Nemerle начали заниматься в 2003 году в университете Вроцлава (Польша). Команда разработчиков состояла из трёх человек, аспирантов Вроцлавского университета. Михал Москаль — лидер команды и автор системы вывода типов, Камиль Скальски — разработчик системы макросов и расширяемого парсера, и Павел Ольшта — автор кодогенератора и реализации механизма сопоставления с образцом.

Название происходит от имени мага Nemmerle из «Волшебника Земноморья» Урсулы Ле Гуин.

Язык изначально проектировался под платформу .NET. 12 марта 2010 года была выпущена первая бета-версия компилятора языка, поддерживающая работу приложений под управлением .NET 3.5. Язык, его реализация и документация выпускаются под свободной BSD-подобной лицензией, допускающей свободное использование их в любых целях.

Первый релиз (версия 1.0) комплекта ПО для программирования на Nemerle выпущен 13 мая 2011 года, на текущий момент самой свежей версией является 1.0.0.9832, работающая на платформе .NET 3.5 — 4.0. В комплект, доступный для свободного скачивания, входит инсталлируемый компилятор языка и набор библиотек для встраивания в Microsoft Visual Studio 2008, отдельный компилятор (для работы без Visual Studio), экспериментальная версия ПО, интегрируемого с Visual Studio 2010, а также исходные коды. Текущая версия компилятора поддерживает включение в проект кода на C# 4.0, при условии неиспользования небезопасного кода.

С июня 2012 года команда разработчиков Nemerle слилась с компанией JetBrains, которая займётся дальнейшей разработкой и поддержкой языка.

Характеристика языка

Nemerle позиционируется как язык общего назначения. Он содержит в себе следующие парадигмы программирования: объектно-ориентированное программирование, императивное программирование, функциональное программирование и метапрограммирование. Из-за такого сочетания концепций, написание программ на Nemerle возможно используя разные стили: в императивном подходе код будет аналогичен коду программ C# (за исключением некоторых нюансов напр. указания типа), в функциональном подходе исходный код будет родственен языкам семейства ML (ML, OCaml, F#, Haskell), включая их особенности:

  • функции высшего порядка
  • сопоставление с образцом (pattern matching)
  • алгебраические типы
  • локальные функции
  • кортежи и анонимные типы
  • частичное применение

Вдобавок к императивным и функциональным парадигмам, Nemerle обладает мощной системой макросов, которые предоставляют пользователю возможность добавлять новые конструкции в язык и описывать решение задач в декларативном стиле с помощью создания собственных предметно-ориентированных языков программирования (DSL).

Особенности

Характерной особенностью Nemerle, как и всех языков, типизированных по Хиндли — Милнеру является мощная система вывода типов.

Вывод типов

def x = 1; // int
def myList = List(); // generic List[T], T должен выводиться из дальнейшего использования
myList.Add(x);       // благодаря этой строке компилятор определяет тип myList как List[int]

Все является выражением

def x =
  { // эквивалент x = 3
    def y = 1;
    def z = 2;
    y + z  // последнее выражение в блоке является значением блока
  }

def x =
  if (DateTime.Now.DayOfWeek == DayOfWeek.Monday) // if, using, try  - тоже являются выражениями
    "Monday"
  else
    "other day";

def x = try
{
  Int32.Parse(someString)
}
catch
{
  | FormatException() => 0;
}

Кортежи

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

Сопоставление с образцом

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

Сопоставление с привязкой к переменным:

def check (o : object) {
  match (o) 
  {
    | i is int    => $"An int: $i"
    | s is string => $"A string: $(s.ToUpper())"
    | _           => "Object of another type"
  }
}

Сопоставление у кортежей:

match (tuple) 
{
  | ( 42, _ ) => "42 on first position"
  | ( _, 42 ) => "42 on second position"
  | ( x, y )  => $"( $x, $y )"
}

Сопоставление по Regexp:

using Nemerle.Text;
regexp match (str) {
  | "a+.*"                          => printf ("a\n");
  | @"(?<num : int>\d+)-\w+"        => printf ("%d\n", num + 3);
  | "(?<name>(Ala|Kasia))? ma kota" =>
     match (name) 
     {
       | Some (n) => printf ("%s\n", n)
       | None     => printf ("noname?\n")
     }

  | _                               => printf ("default\n");
}

Функциональные типы и локальные функции

def next(x) { x + 1 };

def mult(x, y) { x * y }

def fibbonacci(_)
{
  | 0     => 0
  | 1     => 1
  | i => fibbonacci(i - 1) + fibbonacci(i - 2)
}

Console.WriteLine(next(9));        // 10
Console.WriteLine(mult(2, 2));     // 4
Console.WriteLine(fibbonacci(10)); // 55

Метапрограммирование

Nemerle позволяет создавать, анализировать и модифицировать код программы во время компиляции с помощью макросов. Макросы могут быть использованы в виде вызова метода либо в виде новых конструкций языка. Большая часть конструкций в языке реализована с помощью макросов (if, for, foreach, while, using и т. д.).

Пример макроса «if»:

macro @if (cond, e1, e2)
syntax ("if", "(", cond, ")", e1, Optional (";"), "else", e2)
{
  /*
    <[ ]> // <[ ]> определяет области квазицитирования, код внутри них преобразуется в AST Немерле,
          аналогично преобразованию кода в Expression компилятором C#
  */
  <[
    match ($cond : bool)
    {
      | true => $e1
      | _ => $e2
    }
  ]>
}

// Вышеприведённый макрос вводит в язык конструкцию if,
def max = if (a > b) a else b;
// которая при компиляции раскрывается в
def max = match (a > b)
{
  | true => a
  | _    => b
}

Средства метапрограммирования

Ряд языковых средств кардинальным образом отличает Nemerle от C#, Java, C++. Это макросы и замыкания, причём в виде, более характерном для Lisp или других функциональных языков, нежели для С++. Система макросов позволяет описывать на Nemerle новые синтаксические конструкции и использовать их наравне со встроенными. В действительности, большинство директивных управляющих конструкций, в том числе операторы if, when, циклы всех видов, реализованы в виде макросов стандартной библиотеки Nemerle.

Среда разработки

Кроме большого количества поддерживаемых редакторов типа emacs, vi, итд. Nemerle имеет бесплатную полноценную IDE, основанную на Visual Studio 2008 Shell, а также может интегрироваться с полноценной Visual Studio 2008, Visual Studio 2010, Visual Studio 2015. Основные механизмы интеграции с VS вынесены в отдельную сборку, не зависящую от VS, так что желающие могут добавить поддержку Nemerle в другие IDE.

Примеры

Hello, World!

Реализация традиционного "Hello World!" на C#:

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

или проще:

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

Nemerle with ASP.NET

Nemerle может быть встроен непосредственно в 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>

... Или храниться в отдельном файле и добавляться одной строкой:

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

Ссылки