Комментарии 19
Спасибо )
0
Не могли бы вы привести пару примеров задач, которые «через монады» решаются проще, чем методами традиционного ООП?
+2
Пара примеров есть в статье: это построение списков и описание асинхронного процесса вычисления.
Первый можно назвать микро достижением, так как изменения затрагивают только тело метода.
Второй уже серьезно влияет на архитектуру приложения — монады позволяют комбинировать существующие асинхронные методы в новые асинхронные методы, разделяя описание процесса вычисления от самого вычисления. Плюсом является то, что асинхронный код выглядит предельно «синхронно» и императивно. Архитектура приложения, которое ориентировано на использование callback'ов, отличается от такой, где используются монады.
Используя монаду State можно через код неявно протаскивать IoC-контейнер (макро достижение). Через монаду Maybe организовать хотелку C#-программистов оператор "?." (микро достижение).
Simon Peyton Jones написал потрясающую статью про реализацию STM в Haskell через монады — Beautiful concurrency.
Через монады так же реализован Parsec в Haskell — библиотека для удобного описания парсера, когда описание парсера в языке Haskell (то есть его исходный код) максимально приближено к форме БН. Хотя мне больше нравиться подход Nemerle: парсер описывается макросом, который в свою очередь при компиляции генерирует код для разбора.
Про другие применения монад можно почитать в статье Евгения Кирпичева Монады
Первый можно назвать микро достижением, так как изменения затрагивают только тело метода.
Второй уже серьезно влияет на архитектуру приложения — монады позволяют комбинировать существующие асинхронные методы в новые асинхронные методы, разделяя описание процесса вычисления от самого вычисления. Плюсом является то, что асинхронный код выглядит предельно «синхронно» и императивно. Архитектура приложения, которое ориентировано на использование callback'ов, отличается от такой, где используются монады.
Используя монаду State можно через код неявно протаскивать IoC-контейнер (макро достижение). Через монаду Maybe организовать хотелку C#-программистов оператор "?." (микро достижение).
Simon Peyton Jones написал потрясающую статью про реализацию STM в Haskell через монады — Beautiful concurrency.
Через монады так же реализован Parsec в Haskell — библиотека для удобного описания парсера, когда описание парсера в языке Haskell (то есть его исходный код) максимально приближено к форме БН. Хотя мне больше нравиться подход Nemerle: парсер описывается макросом, который в свою очередь при компиляции генерирует код для разбора.
Про другие применения монад можно почитать в статье Евгения Кирпичева Монады
+2
Я бы использовал Nemerle, если бы это был синтаксический суперсет от C#.
Типо языкового расширения…
А так поменяли тип и имя параметра местами в описании функций, выкинули return, другие косметические изменения ради изменений, но не пользы…
Типо языкового расширения…
А так поменяли тип и имя параметра местами в описании функций, выкинули return, другие косметические изменения ради изменений, но не пользы…
+1
На самом деле такой синтаксис более продуман, но это не так важно, как возможность использовать преимущества макросов (например, PEG и Computation expressions).
Скоро будет релиз, в котором будет конвертер из C# в Nemerle, а так же возможность компилятором Nemerle компилировать C# файлы. То есть берем проект на C#, а новый функционал пишем уже на Nemerle)
Скоро будет релиз, в котором будет конвертер из C# в Nemerle, а так же возможность компилятором Nemerle компилировать C# файлы. То есть берем проект на C#, а новый функционал пишем уже на Nemerle)
0
Возможно новый функционал и продуман, но не базовый.
Базовый функционал надо писать «по-новому».
1) Поменять местами тип и название параметра в описании методов, плюс влепить между ними двоеточие. Разделять запятой, а не точкой с запятой.
3) Заменить угольные скобки на квадратные в описании генериков. Это массив или доступ по индексу?
4) Тип результата функции писать в конце метода, опять через двоеточие. Кроме того, void все еще есть :)
5) Лямбду через минус, а не через знак равно.
Вы хотите сказать, что этим косметическим изменениям есть объяснение, кроме как — мы не хотим, чтобы все было как в C, а хотим чуть-чуть из Pascal?
Базовый функционал надо писать «по-новому».
1) Поменять местами тип и название параметра в описании методов, плюс влепить между ними двоеточие. Разделять запятой, а не точкой с запятой.
3) Заменить угольные скобки на квадратные в описании генериков. Это массив или доступ по индексу?
4) Тип результата функции писать в конце метода, опять через двоеточие. Кроме того, void все еще есть :)
5) Лямбду через минус, а не через знак равно.
Вы хотите сказать, что этим косметическим изменениям есть объяснение, кроме как — мы не хотим, чтобы все было как в C, а хотим чуть-чуть из Pascal?
0
Конечно есть они более логичны и последовательны.
1. В случае generic-метода у нас вначале идет объявление параметра, а затем его использование:
Объявление переменной с указанием типа или с использованием вывода типа выглядит однородно:
2. Ну в C# тоже запятой параметры разделяются.
3. Я не знаю почему, кажется разумной причины нет, но я как то читал, что вроде это устраняет неоднозначности и упрощает парсер языка.
4. Уже в первом пункте раскрыл.
5. Лямбда через знак равно, через минус функциональный тип описывается, например
1. В случае generic-метода у нас вначале идет объявление параметра, а затем его использование:
// Nemerle
public Wrap[T](a : T) : List[T] { ... }
// C#
public List<T> Wrap<T>(T a) { ... }
Объявление переменной с указанием типа или с использованием вывода типа выглядит однородно:
// Nemerle
def a : string = "...";
def a = "...";
// C#
string a = "...";
var a = "...";
2. Ну в C# тоже запятой параметры разделяются.
3. Я не знаю почему, кажется разумной причины нет, но я как то читал, что вроде это устраняет неоднозначности и упрощает парсер языка.
4. Уже в первом пункте раскрыл.
5. Лямбда через знак равно, через минус функциональный тип описывается, например
def a : int -> string = x => x.ToString();
+1
Вот реально чего не хватает в C#, это такого:
И чтобы эта трансформация вызывалась компилятором до codegen…
class MyClass
{
[MyTransform]
public int Property { get; set;}
}
abstract class PropertyTransformAttribute<T>: Attribute
{
public string PropetyName { get; private set;}
public delegate void Setter(object self, ref T oldValue, T newValue);
public delegate T Getter(object self, T oldValue);
public virtual Expression<Setter> TransformSetter(Setter setter) { return setter; }
public virtual Expression<Getter> TransformGetter(Getter getter) { return getter; }
}
class MyTransformAttribute: TransformAttribute<int>
{
public override Expression<Setter> TransformSetter(Setter setter)
{
return (sender, ref oldValue, newValue) =>
{
if (oldValue == newValue) return;
oldValue = newValue;
((MyClass)sender).RaisePropertyChanged(PropertyName);
}
}
}
И чтобы эта трансформация вызывалась компилятором до codegen…
0
А разве все эти AOP фреймворки типа postsharp не этим занимаются?
+1
Это можно будет делать, компилятор Nemerle будет понимать и .cs файлы и .n файлы, внутри .cs можно будет использовать макроатрибуты (макросы, которые выглядят как атрибуты, но переписывают код на этапе компиляции.
0
> Скоро будет релиз, в котором будет конвертер из C# в Nemerle, а так же возможность компилятором Nemerle компилировать C# файлы. То есть берем проект на C#, а новый функционал пишем уже на Nemerle)
Уже есть. В последних инсталляторах уже есть поддержка компиляции C#-файлов. Сейчас уже основные глюки выловлены, так что можно пользоваться (хотя, конечно, какие-то ошибки будут, наверно).
Уже есть. В последних инсталляторах уже есть поддержка компиляции C#-файлов. Сейчас уже основные глюки выловлены, так что можно пользоваться (хотя, конечно, какие-то ошибки будут, наверно).
0
«но, в отличие от C#, эти языки поддерживают концепцию более высокого уровня, которая позволяет реализовать асинхронные вычисления в стиле async/await в виде библиотеки, а не на уровне языка.»
А что мешает, собственно, в C# это реализовать в виде библиотеки?
А что мешает, собственно, в C# это реализовать в виде библиотеки?
0
Не будет поддержки со стороны языка. В ООП стиле можно писать и на C, но отсутствие поддержки со стороны языка делает это дело сложным. Тоже самое и тут.
0
> А что мешает, собственно, в C# это реализовать в виде библиотеки?
Отсутствие возможности расширять синтаксис. Без сокрытия деталей реализации код будет ужасен и никто не захочет писать такой код.
Для поддержки подобного в C# нужно менять компилятор. Собственно в C# 5.0 и будет введен синтаксис для подержи асинхронного программирования. Но это будет конкретная реализация которая будет гвоздями прибита к языку. В случае Nemerle реализация — это макрос. Его можно подключить в виде библиотеки, а чтобы использовать в конкретном файле проекта нужно еще открыть с помощью using.
Отсутствие возможности расширять синтаксис. Без сокрытия деталей реализации код будет ужасен и никто не захочет писать такой код.
Для поддержки подобного в C# нужно менять компилятор. Собственно в C# 5.0 и будет введен синтаксис для подержи асинхронного программирования. Но это будет конкретная реализация которая будет гвоздями прибита к языку. В случае Nemerle реализация — это макрос. Его можно подключить в виде библиотеки, а чтобы использовать в конкретном файле проекта нужно еще открыть с помощью using.
0
> Имя этой концепции — монада.
В тред врывается Haskell-программист!
В тред врывается Haskell-программист!
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Асинхронное программирование и Computation Expressions