Nemerle Deep Dive Что такое Nemerle? Nemerle – это статически-типизированный, мультипарадигмный язык программирования общего назначения для платформы CLI (.Net и Mono) Ядро языка Типы Позаимствованы из C# Позаимствованы из ML Выражения – позаимствованы из ML Операторы – позаимствованы из C Макросы – позаимствованы из Lisp Синтаксические различия using System; namespace MyNamespace { class Test<T> { public T GetResult(T value) { // ... return value; } } static class Program { static void Main(string[] args) { var result = new Test<int>().GetResult(42); Console.WriteLine(result); } } } C# Синтаксические различия using System; namespace MyNamespace { class Test<T> { public T GetResult(T value) { // ... return value; } } static class Program { static void Main(string[] args) { var result = new Test<int>().GetResult(42); Console.WriteLine(result); } } } C# Синтаксические различия using System; namespace MyNamespace { class Test[T] { public GetResult(value : T) : T { // ... value } } module Program { Main(args : array[string]) : void { def result = Test().GetResult(42); Console.WriteLine(result); } } } Nemerle Синтаксические различия using System; namespace MyNamespace { class Test[T] // Квадратные скобки вместо угловых { public GetResult(value : T) : T // типы после «:» { Nemerle // ... value // Не нужно использовать return } } module Program // вместо статический классов используются модули { Main(args : array[string]) : void // массив объявляется через ключевое слово array { def result = Test().GetResult(42); // не нужно указывать параметры типов и new Console.WriteLine(result); } } } Синтаксические различия #pragma indent using System; namespace MyNamespace class Test[T] public GetResult(value : T) : T // ... value module Program Main(args : array[string]) : void def result = Test().GetResult(42); Console.WriteLine(result); Nemerle Вывод типов Nemerle поддерживает локальный вывод типов. Выводятся наиболее конкретный общий, не обобщенный, тип. Типы выводятся из инициализации или использования. Параметры типов так же выводятся и обычно их не приходится указывать явно. Минималистичное ядро выражений Оператор match (switch на стероидах) Блок выражений Именованный блок (return на стеройдах) Локальные функции Связывание def Переменные mutable Обработка исключений throw, try/catch/finally Операторы: + - * / % ^ & | < > <= >= == () ~ = Вызов функций/методов/индексаторов Приведение типов «:» - уточнение и «:>» - приведение Литералы: числовые, строк, списков, массивов, символов. checked и unchecked Доступ к члену (obj.member) Все остальные конструкции языка – макросы. Другие операторы и выражения В стандартную библиотеку Nemerle входит множество макросов реализующих аналоги операторов или выражений C# или не имеющих аналогов в C#. Код всех макросов доступен публично. Обычно макросы предоставляют ряд возможностей выходящих за рамки возможностей предоставляемых аналогичными операторами/выражениями C#. Вы можете начать писать на Nemerle как на C# и постепенно осваивать продвинутые возможности. Поддержка функционального программирования Функции как первоклассные значения Лямбды Частичное применение Алгебраические типы Сопоставление с образцом Вывод типов Макросы Что это? С чем едят? Зачем они нужны? Как сочетаются с IDE и прочими технологиями? Сложности разработки, отладки, сопровождения. Развенчание мифов. Макросы: Что это? Макрос Nemerle – это метапрограмма (функция) позволяющая изменять или дополнять программу путем манипуляции ее AST. Виды макросов: Макро-атрибут. Макрос уровня выражения. Макросы могут быть синтаксическими, операторами или не синтаксическими. Макросы: Зачем они нужны? Создание встроенных DSL-ей (языков предметной области). Расширение языка. Автоматизация программирования. Контроль за кодом. Почему макросы, а не: Генерация кода во время исполнения (Expression tree, Sytem.Reflection.Emit, StringBuilder + csc.exe)? PostSharp или другой постпроцессор? Генерация кода внешними утилитами (в виде текста). Например, с помощью Т4? Препроцессоры вроде OCaml4p? Использовать DSL-и на основе имеющихся возможностей языка? Обходиться возможностями ООП или ФП? Макросы: Как сочетаются с IDE и прочими технологиями? IDE Дизайнеры (форм, WPF, Web, …) Внешние кодогенераторы (например, T4) Макросы: Сложности Как разрешаются конфликты между макросами? Взаимодействие с компонентными технологиями. Откладка: Отладка кода макроса. Отладка кода генерируемого макросом. Сопровождение, совместимость с предыдущими версиями. Ограничения и проблемы макросов в Nemerle 1.0. Ограничения расширения синтаксиса. Сложность введения нестандартного синтаксиса. Невозможность определения порядка раскрытия макросов работающих на одной стадии. Сложность написания нетривиальных макросов (которым требуется информация о типах). Не до конца продуманный API компилятора. Сложность создания внешних DSL-ей. Привязанность компилятора к платформе на которой он собран (SRE). Низкая скорость работы компилятора. Что ждать после выхода Nemerle 1.0? Поддержку VS 2010. Перевод Nemerle на сменяемые бэкэнды (CCI). Nemerle 2.0. Что будет в Nemerle 2.0? Поддержка сменяемых бэкэндов (CCI Metadata, Mono Cesil, F# AbstractIL, IKVM). Возможно реализация бэкнда для Java и LLVM. Крос-компиляция для любых версий платформ .net и Mono (Compact Framwork, SilverLight...). Новая макро-система основанная на PEG/TDOP. Почти неограниченная расширяемость синтаксиса. Возможность создавать внешние DSL-и. Перевод парсера Nemerle полностью на макросы. Что еще будет в Nemerle 2.0? Ускорится компиляция. Улучшится поддержка IDE. Nemerle станет фрэймворком для создания языков программирования, внешних DSL-й и средств рефакторинга к ним. Компилятор станет многопоточным. AST станет неизменяемым, а его изменение будет прождать создание новой версии. Макросы станут преимущественно «чистыми», а изменение дерева типов будет выделено в отдельные стадии компиляции и будет четко контролироваться. Примеры практического использования макросов Прикладные макро-библиотеки DSL-и Фрэймворки Расширения языка (мелкие полезняшки) Прикладные макро-библиотеки ComputationExpressions yield внутри выражения Асинхронное программирование другие применения Nemerle.Xml - XML-литералы Nemerle.Peg - быстрый и гибкий генератор парсеров шаговой доступности Nemerle.WUI.Reactive Nemerle on Rails Расширения языка Автоматизация реализации зависимых свойств в WPF Record - автоматизация создания конструкторов Автоматизация паттернов проектирования ООП (Abstract factory, Aggregate, Proxy, Singleton) late - позднее связывание Surroundwith - создание аналогов using и lock в мгновение ока Memoize $-строки assertions Расширения языка List сomprehension regexp match StructuralEquality LexicographicCompareTo StructuralHashCode Nemerle