stringtranslate.com

Немерле

Nemerle — это универсальный , высокоуровневый , статически типизированный язык программирования , разработанный для платформ, использующих Common Language Infrastructure ( .NET / Mono ). Он предлагает функциональные , объектно-ориентированные , аспектно-ориентированные , рефлексивные и императивные возможности. Он имеет простой синтаксис, подобный C# , и мощную систему метапрограммирования .

В июне 2012 года основные разработчики Nemerle были наняты чешской компанией по разработке программного обеспечения JetBrains . Команда сосредоточилась на разработке Nitra, фреймворка для реализации существующих и новых языков программирования. [2] [3] [4] Как язык Nemerle, так и Nitra, по-видимому, были заброшены или прекращены JetBrains; Nitra не обновлялась его первоначальными создателями с 2017 года, и Nemerle теперь полностью поддерживается Russian Software Development Network, независимо от JetBrains, хотя никаких крупных обновлений пока не было выпущено, и разработка продвигается очень медленно. Ни Nemerle, ни Nitra не упоминались и не упоминались JetBrains в течение многих лет.

Немерле назван в честь архимага Неммерле, персонажа фэнтезийного романа «Волшебник Земноморья» Урсулы К. Ле Гуин .

Функции

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

Система метапрограммирования обеспечивает большую расширяемость компилятора , встраивание доменно-специфичных языков , частичное вычисление и аспектно-ориентированное программирование , используя высокоуровневый подход для максимального снятия нагрузки с программистов. Язык объединяет все стандартные функции Common Language Infrastructure (CLI), включая параметрический полиморфизм , лямбды , методы расширения и т. д. Доступ к библиотекам, включенным в платформы .NET или Mono, так же прост, как и в C#.

Вывод типа

def x = 1 ; // int def myList = List (); // generic List[T], тип T выводится из использования в следующей строке myList . Add ( x ); // компилятор выводит тип T как int, делая 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 int.Parse ( someString ) catch { | FormatException ( ) => 0 } ;           def x = returnBlock : { foreach ( i in [ 1 , 2 , 3 ]) when ( i > 2 ) returnBlock ( true ); // выход из блока (x = true)                   ложь // x = ложь };  

Кортежи

def k = ( 1 , "один" ); // k : (целое * строка) def ( a , b ) = k ; // a = 1, b = "один"          

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

def result = match ( number ) { | 0 => "ноль" | 1 => "один" | x когда x < 0 => "отрицательно" | _ => "больше одного" }                        
Другие примеры сопоставления с образцом

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

def check ( o : object ) { match ( o ) { | i is int => $"An int: $i " | s is string => $"A string: $ ( s .T oUpper ()) " | _ => "Объект другого типа" } }                          

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

match ( tuple ) { | ( 42 , _ ) => "42 на первой позиции" | ( _ , 42 ) => "42 на второй позиции" | ( x , y ) => $"( $x , $y )" }                       

Соответствие регулярному выражению:

с использованием Nemerle . Текст ; регулярное выражение match ( str ) { | "a+.*" => printf ( "a\n" ); | @"(?<num: int>\d+)-\w+" => printf ( "%d\n" , num + 3 ); | "(?<name>(Ala|Kasia))? ma kota" => match ( name ) { | Некоторые ( n ) => printf ( "%s\n" , n ) | Нет => printf ( "noname?\n" ) }                                  | _ => printf ( "по умолчанию\n" ); }   

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

using System.Console ; // классы и модули (статические классы) можно поместить в пространства имен def next ( x ) { x + 1 } ; // тип аргумента x и других аргументов функции можно вывести из использования         def mult ( x , y ) { x * y };       def fibonacci ( i ) { | 0 => 0 | 1 => 1 | other => fibonacci ( i - 1 ) + fibonacci ( i - 2 ) };                   WriteLine ( next ( 9 )); // 10 аналогично "Console.WriteLine(next(9));" WriteLine ( mult ( 2 , 2 )); // 4 WriteLine ( fibonacci ( 10 )); // 55    

Варианты

Варианты (называемые типами данных или типами сумм в SML и OCaml) представляют собой формы выражения данных нескольких различных видов:

 вариант RgbColor { | Красный | Желтый | Зеленый | Разные { красный : плавающий ; зеленый : плавающий ; синий : плавающий ; } }                      

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

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

Пример макроса " if ":

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

Синтаксис без скобок

Подобно синтаксису без скобок, позже добавленному в Scala , Nemerle позволяет программисту опционально использовать чувствительный к пробелам синтаксис, основанный на правиле «вне игры» , аналогично Python .

Следующий фрагмент в фигурных скобках:

с использованием System.Console ; [Qux] класс FooBar { public static Main (): void { WriteLine ( "Привет" ) }          static Foo ( x : int ): void { if ( x == 3 ) { def y = x * 42 ; Foo ( x ) } else { [x] . Map ( fun ( x ) { x * 2 }) } }                                статический бар (): int { def foo = 2 + 7 * 13 ; foo } }             

можно переписать так:

с использованием System.Console ; [Qux]  \ class FooBar public static Main (): void WriteLine ( "Привет" )       static Foo ( x : int ): void if ( x == 3 ) def y = x * 42 ; Foo ( x ) else [x] . Map ( fun ( x ) { x * 2 })                           статический Bar (): int def foo = 2 + 7 * 13 foo           

В частности, невозможно разбить выражения или альтернативные предложения в совпадениях, занимающих несколько строк, без использования обратной косой черты \:

// Это не скомпилируется ...статический Bar (): int def foo = 2 + 7 * 13 foo             совпадение ( s ) | "a" | "aa" => 1 | "b" | "bb" => 2 | _ => 0 // Но это будет:                  статический Bar (): int def foo = 2 \ + 7 \ * 13 foo              совпадение ( s ) | "a" \ | "aa" => 1 | "b" \ | "bb" => 2 | _ => 0                   

Чтобы активировать этот синтаксис, пользователь должен добавить #pragma indentв начало файла или использовать опцию компилятора -i.

ИДЕ

Nemerle можно интегрировать в интегрированную среду разработки (IDE) Visual Studio 2008. Также имеется полностью бесплатная IDE на основе Visual Studio 2008 Shell [5] (например, Visual Studio Express Editions ) и SharpDevelop (ссылка на исходный код плагина).

Nemerle также можно интегрировать в Visual Studio (до 2017 года) с помощью надстроек и расширений. [6]

Примеры

Привет, мир!

Традиционную программу Hello World! можно реализовать в стиле, более похожем на C#:

class Hello { static Main () : void { System.Console.WriteLine ( " Привет , мир! " ) ; } }          

или проще:

System.Console.WriteLine ( " Привет, мир ! " ) ;

Примеры макросов

Макросы позволяют генерировать шаблонный код с дополнительными статическими проверками, выполняемыми компилятором. Они уменьшают объем кода, который должен быть написан вручную, делают генерацию кода более безопасной и позволяют программам генерировать код с проверками компилятора, сохраняя при этом исходный код относительно небольшим и читаемым.

Форматирование строки

Макрос форматирования строк упрощает манипуляции с переменными в строках с помощью обозначения $:

def s = $"Число равно $i " ; //вставить значение переменной i, где находится $i def s = $" $x + $y = $ ( x + y ) " ; // $(...) можно использовать для выполнения вычислений или доступа к членам        

Декларативная генерация кода

StructuralEquality , Memoize , json и with — это макросы, которые генерируют код во время компиляции. Хотя некоторые из них ( StructuralEquality , Memoize ) могут выглядеть как атрибуты C#, во время компиляции они будут проверены компилятором и преобразованы в соответствующий код с использованием логики, предопределенной их макросами.

[StructuralEquality] // Реализуем интерфейс IEquatable[Sample].Net, используя равенство сравнения элементов. class Sample { [Memoize] // запоминаем результат первой оценки public static SomeLongEvaluations () : int { MathLib . CalculateNthPrime ( 10000000 ) }              [DependencyProperty] // Свойство зависимости WPF public DependencyPropertySample { get ; set ; } public static Main () : void { /* макрос синтаксиса "json" генерирует код: JObject.Object([("a", JValue.Number(SomeLongEvaluations())), ("b", JValue.Number(SomeLongEvaluations() + 1))]) */ def jObject = json { a : SomeLongEvaluations (); b : ( SomeLongEvaluations () + 1 )} // макрос инициализации объекта "<-" является развитием инициализации объекта фигурными скобками C# def k = Diagnostics . Process () <- { StartInfo <- // можно инициализировать свойства внутренних объектов без вызова конструктора { FileName = "calc.exe" ; UseShellExecute = true ; } Exited += () => WriteLine ( "Calc done" ); // события и делегаты }                                                     ReadLine (); } } 

Доступность базы данных

Используя макросы Nemerle для SQL вы можете написать:

ExecuteReaderLoop ( "SELECT имя, фамилия ИЗ сотрудника, где имя = $myparm" , dbcon , { WriteLine ( $"Имя: $firstname $lastname " ) });      

вместо

string sql = "SELECT имя, фамилия FROM employee WHERE имя = :a" ; using ( NpgsqlCommand dbcmd = new NpgsqlCommand ( sql , dbcon , dbtran )) { dbcmd . Параметры . Добавить ( "a" , myparm );              using ( NpgsqlReader reader = dbcmd . ExecuteReader ()) { while ( reader . Read ()) { var firstname = reader . GetString ( 0 ); var lastname = reader . GetString ( 1 ); Console . WriteLine ( "Имя: {0} {1}" , firstname , lastname ) } } }                        

и это не просто сокрытие некоторых операций в библиотеке, а дополнительная работа, выполняемая компилятором для понимания строки запроса, используемых там переменных и столбцов, возвращаемых из базы данных. Макрос ExecuteReaderLoop сгенерирует код, примерно эквивалентный тому, что вам пришлось бы набирать вручную. Более того, он подключается к базе данных во время компиляции, чтобы проверить, что ваш SQL-запрос действительно имеет смысл.

Новые языковые конструкции

С помощью макросов Nemerle вы также можете ввести в язык новый синтаксис:

макрос ReverseFor ( i , begin , body ) синтаксис ( "ford" , "(" , i , ";" , begin , ")" , body ) { <[ for ( $i = $begin ; $i >= 0 ; $i --) $body ]> }                     

определяет макрос, представляющий синтаксис EXPR ford (EXPR ; EXPR) и может использоваться как

форд (я ; н) печать (я);

Nemerle с ASP.NET

Nemerle можно встроить непосредственно в ASP.NET :

<%@ Язык страницы = "Nemerle" %> <script runat= "server" >     Page_Load ( _ : object , _ : EventArgs ) : void { Message . Text = $"Вы последний раз посещали эту страницу: $(DateTime.Now)" ; }             EnterBtn_Click ( _ : object , _ : EventArgs ) : void { Message . Text = $"Привет, $(Name.Text), добро пожаловать в ASP.NET!" ; }            </скрипт><html> <body> <form runat= "server" > Введите свое имя : <asp:TextBox ID= "Name" runat= "server" /> <asp:Button OnClick= "EnterBtn_Click" Text= "Enter" runat= "server" />                 <p><asp:Label ID= "Сообщение" runat= "сервер" /></p> </form> </body> </html>     

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

<%@ Язык страницы = "Nemerle" Источник = "test.n" Наследует = "Test" %>     

PInvoke

Nemerle может использовать собственные библиотеки платформы. Синтаксис очень похож на C# и другие языки .NET. Вот простейший пример:

с использованием System ; с использованием System.Runtime.InteropServices ;  class PlatformInvokeTest { [DllImport("msvcrt.dll")] public extern static puts ( c : string ) : int ;           [DllImport("msvcrt.dll")] внутренний внешний статический _flushall () : int ;       public static Main () : void { _ = puts ( "Тест" ); _ = _flushall (); } }            

Ссылки

  1. ^ Немерле 1.2.507.0
  2. ^ "Twitter / orangy: Мы решили взять Nemerle". Twitter.com . Получено 2013-09-05 .
  3. ^ "Блог JetBrains .NET Tools » JetBrains и Nemerle". Blogs.jetbrains.com. 2012-06-27 . Получено 2013-09-05 .
  4. ^ "Google Дискуссионная группа" . Проверено 5 сентября 2013 г.
  5. ^ Nemerle Studio Microsoft Setup Installer можно установить после установки Visual Studio Shell 2008 Isolated
  6. ^ Надстройка Visual Studio 2010

Дальнейшее чтение

Внешние ссылки