- Nemerle
-
Nemerle Семантика: мультипарадигменный, объектно-ориентированный, функциональный, императивный
Тип исполнения: компилируемый
Появился в: Автор(ы): Вроцлавский университет; Михал Москаль, Камиль Скальски, Павел Ольшта и др. [1]
Релиз: 1.0 Google Code GitHub (май 12, 2011 )
Типизация данных: Испытал влияние: Сайт: 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, которая займётся дальнейшей разработкой и поддержкой языка.[1]
Характеристика языка
Nemerle позиционируется как язык общего назначения. Он сочетает в себе несколько парадигм программирования: объектно-ориентированное программирование, императивное программирование, функциональное программирование и метапрограммирование. Из-за такого сочетания концепций, написание программ на Nemerle возможно используя разные стили: в императивном подходе код будет аналогичен коду программ C# (за исключением некоторых нюансов напр. указания типа), в функциональном подходе исходный код будет родственен языкам семейства ML (ML, OCaml, F#, Haskell), включая их особенности:
- функции высшего порядка
- cопоставление с образцом (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 next(x) { x + 1 }; def mult(x, y) { x * y } def fibbonacci(_) { | 0 => 0 | 1 => 1 | i => i + fibbonacci(i - 1) } 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 }
Основные концепции
- Типобезопасные «гигиеничные» макросы и квазицитирование c возможностью расширения синтаксиса.
- Наличие локальных функций (лексических замыканий). Функция является объектом первого класса.
- Гарантированная оптимизация хвостовой рекурсии, то есть хвостовая рекурсия всегда заменяется циклом при компиляции.
- Выведение типов. В частности, возможно выведение типов локальных переменных и выведение сигнатуры локальных функций.
- Отсутствие четкой границы между инструкцией (statement) и выражением (expression). «Everything is expression». Например, условный оператор может находиться внутри арифметического выражения. Нет необходимости в инструкции return.
- Блоки кода, упраздняющие необходимость в таких инструкциях, как break или continue.
- Алгебраические типы данных, кортежи и сопоставление с образцом.
- Упрощенный синтаксис работы со списками. Списочные литералы.
- Частичное применение операторов и функций — простая генерация обёртки некоторой функции, в которой часть параметров подставлена заранее, а часть передаётся непосредственно при вызове функции.
Особенности синтаксиса
Синтаксис Nemerle очень близок к C#, но имеет ряд характерных отличий, в том числе позаимствованных из функциональных и скриптовых языков. Вот некоторые из них:
- Язык поддерживает локальные функции (функции внутри методов и других функций). Эти функции поддерживают замыкания (в результате становится важно где и в каком порядке они объявлены).
- Наряду с обычным порядком заключения элементов программы (классов, составных операторов, тел методов) в фигурные скобки, поддерживается альтернативный вариант описания структуры программы, базирующийся на отступах, как в Python.
- В описании переменных и методов тип указывается в стиле OCaml (похоже на Pascal, но без возможности задать несколько имен переменных), в виде «переменная : тип».
- Имена могут, помимо букв, цифр и знака подчёркивания, содержать знак апострофа «'».
- Объявления локальных функций и констант начинаются с def.
- Наряду с унаследованным от C# объявлением главной функции программы в виде статического метода Main головного класса программы, поддерживается прямое размещение кода в файле, без помещения его в какой-либо класс и метод.
- Переменные объявляются с помощью модификатор mutable (а не def). Таким образом, синтаксис поощряет использование неизменяемых объектов, что соответствует идеологии функционального программирования.
- Создание экземпляра класса выполняется вызовом его конструктра - «ИмяКласса(параметры конструктора)», без необходимости указывать ключевое слово new (как это принято в C#).
- Команда подключения пространства имён using подключает все вложенные пространства имён, а также позволяет прямо подключить конкретный тип, что даёт возможность использования его статических членов (например, методов классов или констант перечислений) без квалификации имени.
- Статические классы (классы, имеющие только статические методы и поля) описываются с ключевым словом module вместо class и не требуют указания модификатора static перед каждым членом класса.
- Введены две отдельные конструкции для статического уточнения и динамического приведения типов (":" и ":>" соответственно).
- В стандартной библиотеке имеется тип «список» (list), являющийся однонаправленным связанным списком. Списки являются неизменяемыми и ведут себя во многом аналогично строкам C#. Для этого типа в языке предусмотрен специализированный синтаксис резко упрощающий работу с ним (литералы, возможность использования списка в сопоставлении с образцом).
- Введён тип «вариант» (variant) — аналог алгебраических типов в функциональных языках.
- Введён тип «кортеж» (tuple) — безымянная, незменяемая структура данных, содержащая несколько (возможно разнотипных) элементов. Для кортежей поддерживается структурное соответствие. Кортежи удобны когда требуется вернуть несколько значений из функции, свойства и просто, любого выражения.
- Конструкцию переключения switch заменила конструкция сопоставления с образцом match, обладающая большими возможностями (позаимствовано из ML-подобных языков).
- Гарантировано преобразование компилятором хвостовой рекурсии в цикл. Это позволяет описывать повторяющиеся вычисления рекурсивно, не опасаясь, что применение рекурсии приведёт к исчерпанию памяти. Поддерживается только для одной функции. Поддержка взаимно-рекурсивных функций пока что не реализована.
- Отсутствует специальный синтаксис (используемый в C#) для финализатора (конструкция «~ИмяКласса()»), как провоцирующий ошибочное понимание у программистов, знакомых с C++. Финализатор описывается как обычный виртуальный метод Finalize(), причём компилятор не обеспечивает автоматический вызов финализатора класса-родителя.
- Имеется возможность объявления значений используемых по умолчанию в параметрах и синтаксис вызова с явным указанием имён параметров в произвольном порядке.
- В стандартной библиотеке языка есть три макроса, реализующих условные операторы: if, отличающийся тем, что в нём обязательна ветвь else, when, представляющий собой «if без else», и unless, представляющий собой отрицание when, т.е. «when (! условие) выражение». Все условные операторы переписываются соответствующими макросами в оператор match.
- В параметрах, аргументах и именах переменных допускается использование специального подстановочного символа-заместителя «_». Будучи указанным в начале имени переменной или вместо него (т.е. если указан только знак подчеркивания) этот символ подавляет предупреждение компилятора о неиспользованной переменной. Использование подчеркивания вместо имени локальной переменой (например, «_ = f(a, b)») позволяет игнорировать значение вычисления (в тех же целях можно использовать стандартный макрос ignore следующим образом: «ignore(f(a,b))»). C# игнорирует их автоматически, что иногда приводит к ошибкам. Nemerle выдает предупреждение, если результат вычисления не используется в дальнейшем. Приведенный прием позволяет указать компилятору, что игнорирование результата сделано не случайно.
- Почти все языковые конструкции (кроме using, class и т.д.) определены как имеющие значение и могут быть использованы в качестве элементов выражений. Однако выражение может иметь тип void, что соответствует statement в C#.
- В языке поддерживается функциональный тип (обычный для функциональных языков). С его помощью можно по месту описать ссылку на функцию. В C# для передачи ссылок на функции используются делегаты. Nemerle также поддерживает их, но функциональный тип является более удобным, гибким и быстрым решением. Он не требует объявления отдельного типа (как делегат) и не может быть множественным (multicast).
- В языке поддерживается частичное применение функций и операторов, что позволяет создавать функции "на лету". Например, если в некоторую функцию требуется передать другую функцию (например функцию сложения), то можно частично применить оператор сложения. Выражение «_ + 2» возвращает функцию с одним целочисленным аргументом, прибавляющую к нему значение 2.
Средства метапрограммирования
Ряд языковых средств кардинальным образом отличает Nemerle от C#, Java, C++. Это макросы и замыкания, причём в виде, более характерном для Lisp или других функциональных языков, нежели для С++. Система макросов позволяет описывать на Nemerle новые синтаксические конструкции и использовать их наравне со встроенными. В действительности, большинство директивных управляющих конструкций, в том числе операторы if, when, циклы всех видов, реализованы в виде макросов стандартной библиотеки Nemerle.
Среда разработки
Кроме большого количества поддерживаемых редакторов типа emacs, vi, итд. Nemerle имеет бесплатную полноценную IDE, основанную на Visual Studio 2008 Shell, а также может интегрироваться с полноценной Visual Studio 2008, Visual Studio 2010. Основные механизмы интеграции с VS вынесены в отдельную сборку, не зависящую от VS, так что желающие могут добавить поддержку Nemerle в другие IDE.
См. также
Примечания
Ссылки
- Main Page (англ.). — домашняя страница проекта. Архивировано из первоисточника 11 февраля 2012. Проверено 10 октября 2006.
- Project Hosting on Google Code (англ.). — исходные коды проекта. Архивировано из первоисточника 11 февраля 2012. Проверено 5 февраля 2010.
- Nemerle. — статьи по Nemerle на rsdn.ru. Архивировано из первоисточника 11 февраля 2012. Проверено 10 октября 2006.
- Nemerle. — форум по Nemerle на русском языке. Архивировано из первоисточника 11 февраля 2012. Проверено 10 октября 2006.
- Nemerle. — конференция по Nemerle на английском языке. Архивировано из первоисточника 11 февраля 2012. Проверено 10 октября 2006.
- Nemerle. — конференция по Nemerle на английском языке. Архивировано из первоисточника 11 февраля 2012.
- Nemerle. — Краткий обзор языка и ссылки. Архивировано из первоисточника 11 февраля 2012. Проверено 10 октября 2006.
- Quick Guide по-русски (рус.). — Перевод "Nemerle. Quick Guide". Архивировано из первоисточника 11 февраля 2012. Проверено 1 мая 2009.
- Цикл статей о Nemerle для начинающих
Основные языки программирования (сравнение • IDE • история • хронология) Используемые
в разработкеАда • APL • Язык ассемблера • ActionScript • ABAP/4 • AutoIt • AWK • Бейсик • Си • Кобол • C++ • C# • Cω • Clarion • Clojure • ColdFusion • Common Lisp • D • dBase • Delphi • Eiffel • Erlang • Euphoria • F# • Форт • Фортран • Gambas • Go • Groovy • HAL/S • Haskell • Icon • Java • JavaScript • Limbo • Lua • Модула-3 • Object Pascal • Objective-C • OCaml • Oz • Parser • Паскаль • Компонентный Паскаль • Perl • PHP • PowerBASIC • Python • ПЛ/1 • Пролог • Ruby • Scala • Scheme • Smalltalk • SQL • PL/SQL • Tcl • Vala • Visual Basic (.NET)
Академические IEC 61131-3 Instruction List • ST • FBD • Ladder Diagram (LD) • SFC
Прочие Эзотерические Визуальные Категории:- Языки программирования по алфавиту
- Языки программирования платформы .NET
- Языки программирования семейства ML
- Объектно-ориентированные языки программирования
- Свободные компиляторы и интерпретаторы
Wikimedia Foundation. 2010.