Entry tags:
NEMERLE и поток сознания
Сначала я хотел просто написать, что майский конкурс по ФП закончился, и желающие могут посмотреть, что мы там устроили. А если что-то из увиденного понравится, то и проголосовать.
Но потом я подумал, что это хороший повод рассказать о языке программирования Nemerle, с которым я игрался в последнее время. Опыт у меня с ним пока не большой, потому структурировано написать не выйдет. Под катом некторый набор сведений о Nemerle в перемешку с моим потоком сознания относительно функционального программирования и программирования вообще.
Мне нравится программировать. Я испытываю удовольствие, когда получается красивый и лаконичный код, а так же удовлетворение, когда результаты моих трудов приносят реальную пользу другим людям. Я не могу сказать, насколько программирование творческая профессия, но верю, что первычны мысль и знания, а не нажимание кнопочек. Язык - это средство выражения мысли, при этом неважно, про естественный язык мы говорим или нет. Идеально выразить мысль нельзя, но надо к этому стремится. И уж точно, нельзя запирать мысль в рамки конкретного языка. Ведь из того, что в языке нет какого-то слова совершенно не следует, что объект, который мы хотим описать не существует.
Спасибо мне! Сыграл в КО! Однако с языками программирования часто не прокатывает. Осилил %langname% и все, хватит, отвалите. Мне труп страуса нашептал, что у меня в руках ИНСТРУМЕНТ ВЫСОКОГО УРОВНЯ, а потом, прищурившись, добавил: "Полный по Тьюрингу, даааа". Ну теперь вообще ахуеть. Я даже слушать вас не хочу: жаба тормозит, сишка хуже ассемблера, додиез не знаю, зачем придумали, когда у них жаба есть, objc - это просто яблочная илитка, на лиспе искуственный интелект так и не зделали, лямбда-исчисление? исчисление что? Шли бы вы отсюда со своими историями. А потом человеку изменяет сознание и он начинает находить свои любимые костыли даже там, где их никогда и не было. Паттерн ПРИСПОСОБЛЕНЕЦ во все поля.
Я вспоминаю, как начав программировать на C#, испытывал физическую необходимость ОСВОБОДИТЬ ПАМЯТЬ и руками устроить связанный список. Потом-то оно уже проще идет. Знакомые вещи определяются сразу, а новые расширяют кругозор. Интересно узнавать новый язык, задаваясь вопросом: "А как я вообще раньше без этого жил?" Как будто собирается некий пазл, образуя целостную картину, а не "Вот тебе походный ножик. Теперь иди - строй дом".
Казалось бы, причем здесь Nemerle? Просто это язык программирования, который, на мой взгляд, заслуживает внимания.
Nemerle - ЯП общего назначения. Я не знаю, что такое общее назначение. Я так мало знаю о программировании микроконтроллеров и о программировании для суперкомьютеров и еще куче областей , что у меня с парнями, работающими в тех сферах, разная специальность. Я понимаю, что хороший программист должен найти себя в любой области, но у нас _настолько_ разные приоритеты, что придется сильно ломать себя. Я пишу средней толстоты эторпрайз (базворды прилагаются), потому для меня важны:
- Надежность. Ведь ничего падать не должно, а если упадет - перезапуститься. Конечно же, все логировать-логировать и алертить. И желательно все это задублировать.
- Прозрачность. Ведь вон та функция "ОТПРАВИТЬ ДЕНЬГИ НА ПЕЧАТЬ", должна отправлять деньги на печать всегда, а не только в состоянии суперпозиции ста тысяч "Если".
- Читаемость. Ну мы же все знаем, что самодокументируемый код - это миф, не так ли? Правда, мы так же знаем, что документирование всего и вся с последующей актуализацией - тот еще кошмар. Потому лучше писать кратко и информативно.
- Тестируемость. Необходимо проверить исправность каждой детальки еще до момента, когда конструктор будет собран. Мы же не хотим ОТПРАВИТЬ ЯЧЕЙКУ НА БОЕВОЕ ДЕЖУРСТВО, ЧТОБЫ ОНА ТАМ ПРОСТО СИГНАЛ РИСОВАЛА ТАБУРЕТОЧКОЙ, так?
- Совместимость. Хаскель исключительно хорош для новых проектов? А если не новых? Вместо библиотек даете возможность их написать? ВЕРНИТЕ НА МЕСТО МОИ ЛЮБИМЫЕ ВЕЛИКИ! БЫЫЫСТРААА!
Nemerle - статически типизуеммый язык программирования под .NET (есть реализация для Mono, но она вроде сломана) со всеми вытекающими. Язык поддерживает ООП в самом распространенном варианте ее реализации с одиночным наследованием, знакомый по Java и C#. Есть:
- Шаблоны (generics)
- Интерфесы
- Методы расширения
- Частичные (partial) классы
- Модификаторы доступа (internal, protected и тд)
- Весь набор, привычный C# программисту. )
Я не вижу смысла, останавливаться на ООП, потому как все достаточно стандартно. Идем далее. Nemerle реализует концепции функционального программирования:
- Нормальные кортежи
- Алгебраические типы данных
- Иммутабельность из коробки
- Паттерн матчинг
- Функции высшего порядка
- Частичное применение
- Вывод типов
- Замыкания
- Перегрузка и определение операторов с возможностью задания приоритета и ассоциативности
- Итераторы
- List comprehensions (не знаю, как переводится)
- Монады (нет, ввод-вывод не в монаде)
- Computation expressions (опять не знаю устоявшегося перевода)
- Опционально двухмерный синтаксис (синтаксис на отступах) через #pragma indent
- Опционально может в ленивость
- Оптимизация хвостовых вызовов
- События и делегаты (я думаю, эти вещи в этом блоке смотрятся лучше)
Вообщем-то весь джентльменский набор, необходимый, чтобы назвать язык функциональным. Стоит отметить, что Nemerle разрешает перегрузку функций (в отличии, например, от F#) и вывод типов спокойно разруливает, какую именно следует вызвать. Мне нравится, но наверное хаскелисты негодуют. Правда, Nemerle требует, чтобы на высшем уровне, то есть в классах и модулях (модуль является обычными статическим классом, для методов которого по умолчанию выставлен модификатор public) необходимо явно аннотировать типы. Я не думаю, что кому-то станет плохо от подобного требования, поскольку даже в Haskell, где система типов способна сама все выводить, аннотации типов все равно приводятся, поскольку по типам можно судить о природе процесса, выполняемого функцией. Еще одной особенностью является возможность "открыть" статических класс, импортировав его содержимое в текущее пространство имен. Может мелочь, но меня всегда раздражали все эти Console.WriteLine.
То есть, на первый взгляд, Nemele ничего особенно не представляет. К тому же разработчики старались не сломать мозг своей потенциальной аудитории, потому сделали синтаксис языка по возможности идентичным C#. Разработчики Scala, как я понимаю, пошли тем же путем. А вот ML-подобный синтаксис с непривычки может очень сильно напугать. Проверено. Язык задумывался, как замена C#, то есть каким C# должен был бы быть. И вы знаете, я согласен. Этих возможностей вполне хватает, чтобы комфортно программировать. F# как раз на этой позиции и находится, то есть со вкусом и без изъебств.
Теперь переходим к Nemerle непосредственно, к тому, что делает язык в большой степени уникальным, - макросам. У меня с макросами всегда были проблемы, сначало звучало страшно, потом было непонятно, где и как и применять. Похоже, это не только моя проблема. Иногда, я думаю, что после изобретения LISP'а, значительная часть развития языков программирования является размышлением на тему "Нужны ли макросы? Какими они должны быть тогда?" LISP'еры хоть и не изобрели искустевеный интелект, но очень многое дали миру: gc, графические интерфейсы и конечно макросы. Мне кажется, Ритчи с Томпсоном догадывались, что всего не предусмотришь, потому запили макры. Сишка используется до сих пор, многие даже испытывают к ней теплые чувства. А более другие люди решили, что макры не нужны, а теперь гордятся тьюринг-полным ТЕМПЛЕЙТО-ДОБРОМ. В Скалочку вот добавляют макросы, а я не видел, чтобы кто-то писал, мол Мартин Одерский не особо рубит в языках программирования.
Так с макросами какие проблемы? Во-первых, сразу начинается нытье, мол развалите весь синтаксис со всей семантикой, превратив язык в непонятную ёбу. Я так же ныл (может еще заною, кто его знает). Но это возврат к разговору о возможности прострелить себе ногу. Меня подзаебали эти разговоры, я решил для себя, что прострелить ногу можно везде и всегда. Мутабельность - прострелил. Энергичность - прострелил. Ленивость - иди чини ноги. Иммутабельность - не прочитал книгу по иммутабельным структурам данных? пиздуй в больницу чинить ноги. И так всегда, не бывает серебрянной пули, как не бывает языков общего назначения, как нет искуственого интеллекта. Именно поэтому, программисты существуют, существуют как профессия, как специалисты, а не просто прослойка между креслом и монитором. Хотя надо отдавать себе отчет в собственных возможностях. Это вам не придти и перевести все критические бизнес-процессы на Хаскель из-за того, что кто-то научился Фибоначи считать. И я не один такой, создатель Лифта такой же точки зрения придерживается. То есть в любом случае некоторый опыт необходим.
Во-вторых, макросы сложные. В Nemerle не сложные, то есть при написании макросов используется тот же самый Nemerle и его возможности, никакого специального DSL не требуется. Держим в уме знание, что макрос - функция с типом List[PExpr] -> PExpr, выполняемая во время компиляции, и все будет хорошо. Макросы гигиеничны, то есть при совпадении имен переменной из макроса и контекста, в котором макрос разворачивается, имя из макроса будет автоматически переименовано, хотя это поведение можно отключать, тогда значение будет связано с ближайшим именем в контексте. Таким образом, кстати, работает макра regex match, которую я использовал в своем решении.
Макросы бывают разными
- Макросы выражения: можно сделать printf("%d%f", x, y), который будет на этапе компиляции проверять соответствие количества параметров и их типов строке форматирования; многие компоненты языка такие как if else, while, for и другие реализованы через такие макросы
- Макросы-операторы: собственно через них реализует переопределение и создание новых операторов. Можно задавать приоритет и ассоциативность. Например, с их помощь в Nemerle сделаны pipe-операторы |> и <|
- Мета-атрибуты - видимо, так называются из-за сходства в записили с атрибутами C#. Позволяют изменить класс, метод, свойство и так далее. Для меня самый впечатляющим примером использования является макрос PegGrammar, который по заданной PEG грамматике создает класс-парсер ее разбирающий. Мой игрушечный пример можно увидеть тут. Если игрушки вам не по душе, то можно глянуть на серьезное использование для разбора грамматики C#.
- Лексические макросы: к сожалению, я еще не успел с этим разобраться, но похоже, макра конструирования XML, напоминающая синтаксис для работы с XML в Scala, относится именно к этой категории.
Мне очень хочется, рассказать о макросах Nemerle, кратко и содержательно, чтобы вы могли испытать то же ВАУ, которое испытываю я. Но, по всей видимости, пока в моем мозгу все по полочкам не разложится, я не смогу внятно излагать. Главное, что я хочу донести, что макросы в Nemerle - это очень гибкое средство, которое красиво и лаконично ложится на язык. Синтаксис языка во много сделан на макросах, кодогенерация требующая в C# сторонных тулзовин отлично реализуется, многие хорошие фичи, которые приходят в C#, как новые элементы языка, делаются на макросах. Я думаю, так ожидаемые Type Providers из F# 3.0 делаются на макросах на ура. То есть я пока не вижу, где заканчиваются возможности, но четко представляю, как применять эти вещи в работе: будь-то автоматическая имплементация всяких IDataErrorInfo с INotifyChanged или как присахарить и обезопасить работу с каким-нибудь SqlCommand. При этом я без проблем, могу использовать существующий C# код, могу использовать в C# проектах код на Nemerle (пока не тестировал). Я считаю, что Nemerle - более удобный и качественный инструмент для решения мох задач.
Надесь, было хоть чуть-чуть интересно. Но если вы внезапно дочитали до сюда и считаете все вышенаписаное бредом идиота , хотя бы начинайте псить. Мне приятно будет)
Update: Как-то получилось, что обсуждение велось параллельно в двух местах: тут и еще одна ветка обсуждения.
Но потом я подумал, что это хороший повод рассказать о языке программирования Nemerle, с которым я игрался в последнее время. Опыт у меня с ним пока не большой, потому структурировано написать не выйдет. Под катом некторый набор сведений о Nemerle в перемешку с моим потоком сознания относительно функционального программирования и программирования вообще.
Мне нравится программировать. Я испытываю удовольствие, когда получается красивый и лаконичный код, а так же удовлетворение, когда результаты моих трудов приносят реальную пользу другим людям. Я не могу сказать, насколько программирование творческая профессия, но верю, что первычны мысль и знания, а не нажимание кнопочек. Язык - это средство выражения мысли, при этом неважно, про естественный язык мы говорим или нет. Идеально выразить мысль нельзя, но надо к этому стремится. И уж точно, нельзя запирать мысль в рамки конкретного языка. Ведь из того, что в языке нет какого-то слова совершенно не следует, что объект, который мы хотим описать не существует.
Спасибо мне! Сыграл в КО! Однако с языками программирования часто не прокатывает. Осилил %langname% и все, хватит, отвалите. Мне труп страуса нашептал, что у меня в руках ИНСТРУМЕНТ ВЫСОКОГО УРОВНЯ, а потом, прищурившись, добавил: "Полный по Тьюрингу, даааа". Ну теперь вообще ахуеть. Я даже слушать вас не хочу: жаба тормозит, сишка хуже ассемблера, додиез не знаю, зачем придумали, когда у них жаба есть, objc - это просто яблочная илитка, на лиспе искуственный интелект так и не зделали, лямбда-исчисление? исчисление что? Шли бы вы отсюда со своими историями. А потом человеку изменяет сознание и он начинает находить свои любимые костыли даже там, где их никогда и не было. Паттерн ПРИСПОСОБЛЕНЕЦ во все поля.
Я вспоминаю, как начав программировать на C#, испытывал физическую необходимость ОСВОБОДИТЬ ПАМЯТЬ и руками устроить связанный список. Потом-то оно уже проще идет. Знакомые вещи определяются сразу, а новые расширяют кругозор. Интересно узнавать новый язык, задаваясь вопросом: "А как я вообще раньше без этого жил?" Как будто собирается некий пазл, образуя целостную картину, а не "Вот тебе походный ножик. Теперь иди - строй дом".
Казалось бы, причем здесь Nemerle? Просто это язык программирования, который, на мой взгляд, заслуживает внимания.
- Надежность. Ведь ничего падать не должно, а если упадет - перезапуститься. Конечно же, все логировать-логировать и алертить. И желательно все это задублировать.
- Прозрачность. Ведь вон та функция "ОТПРАВИТЬ ДЕНЬГИ НА ПЕЧАТЬ", должна отправлять деньги на печать всегда, а не только в состоянии суперпозиции ста тысяч "Если".
- Читаемость. Ну мы же все знаем, что самодокументируемый код - это миф, не так ли? Правда, мы так же знаем, что документирование всего и вся с последующей актуализацией - тот еще кошмар. Потому лучше писать кратко и информативно.
- Тестируемость. Необходимо проверить исправность каждой детальки еще до момента, когда конструктор будет собран. Мы же не хотим ОТПРАВИТЬ ЯЧЕЙКУ НА БОЕВОЕ ДЕЖУРСТВО, ЧТОБЫ ОНА ТАМ ПРОСТО СИГНАЛ РИСОВАЛА ТАБУРЕТОЧКОЙ, так?
- Совместимость. Хаскель исключительно хорош для новых проектов? А если не новых? Вместо библиотек даете возможность их написать? ВЕРНИТЕ НА МЕСТО МОИ ЛЮБИМЫЕ ВЕЛИКИ! БЫЫЫСТРААА!
Nemerle - статически типизуеммый язык программирования под .NET (есть реализация для Mono, но она вроде сломана) со всеми вытекающими. Язык поддерживает ООП в самом распространенном варианте ее реализации с одиночным наследованием, знакомый по Java и C#. Есть:
- Шаблоны (generics)
- Интерфесы
- Методы расширения
- Частичные (partial) классы
- Модификаторы доступа (internal, protected и тд)
- Весь набор, привычный C# программисту. )
Я не вижу смысла, останавливаться на ООП, потому как все достаточно стандартно. Идем далее. Nemerle реализует концепции функционального программирования:
- Нормальные кортежи
- Алгебраические типы данных
- Иммутабельность из коробки
- Паттерн матчинг
- Функции высшего порядка
- Частичное применение
- Вывод типов
- Замыкания
- Перегрузка и определение операторов с возможностью задания приоритета и ассоциативности
- Итераторы
- List comprehensions (не знаю, как переводится)
- Монады (нет, ввод-вывод не в монаде)
- Computation expressions (опять не знаю устоявшегося перевода)
- Опционально двухмерный синтаксис (синтаксис на отступах) через #pragma indent
- Опционально может в ленивость
- Оптимизация хвостовых вызовов
- События и делегаты (я думаю, эти вещи в этом блоке смотрятся лучше)
Вообщем-то весь джентльменский набор, необходимый, чтобы назвать язык функциональным. Стоит отметить, что Nemerle разрешает перегрузку функций (в отличии, например, от F#) и вывод типов спокойно разруливает, какую именно следует вызвать. Мне нравится, но наверное хаскелисты негодуют. Правда, Nemerle требует, чтобы на высшем уровне, то есть в классах и модулях (модуль является обычными статическим классом, для методов которого по умолчанию выставлен модификатор public) необходимо явно аннотировать типы. Я не думаю, что кому-то станет плохо от подобного требования, поскольку даже в Haskell, где система типов способна сама все выводить, аннотации типов все равно приводятся, поскольку по типам можно судить о природе процесса, выполняемого функцией. Еще одной особенностью является возможность "открыть" статических класс, импортировав его содержимое в текущее пространство имен. Может мелочь, но меня всегда раздражали все эти Console.WriteLine.
То есть, на первый взгляд, Nemele ничего особенно не представляет. К тому же разработчики старались не сломать мозг своей потенциальной аудитории, потому сделали синтаксис языка по возможности идентичным C#. Разработчики Scala, как я понимаю, пошли тем же путем. А вот ML-подобный синтаксис с непривычки может очень сильно напугать. Проверено. Язык задумывался, как замена C#, то есть каким C# должен был бы быть. И вы знаете, я согласен. Этих возможностей вполне хватает, чтобы комфортно программировать. F# как раз на этой позиции и находится, то есть со вкусом и без изъебств.
Теперь переходим к Nemerle непосредственно, к тому, что делает язык в большой степени уникальным, - макросам. У меня с макросами всегда были проблемы, сначало звучало страшно, потом было непонятно, где и как и применять. Похоже, это не только моя проблема. Иногда, я думаю, что после изобретения LISP'а, значительная часть развития языков программирования является размышлением на тему "Нужны ли макросы? Какими они должны быть тогда?" LISP'еры хоть и не изобрели искустевеный интелект, но очень многое дали миру: gc, графические интерфейсы и конечно макросы. Мне кажется, Ритчи с Томпсоном догадывались, что всего не предусмотришь, потому запили макры. Сишка используется до сих пор, многие даже испытывают к ней теплые чувства. А более другие люди решили, что макры не нужны, а теперь гордятся тьюринг-полным ТЕМПЛЕЙТО-ДОБРОМ. В Скалочку вот добавляют макросы, а я не видел, чтобы кто-то писал, мол Мартин Одерский не особо рубит в языках программирования.
Так с макросами какие проблемы? Во-первых, сразу начинается нытье, мол развалите весь синтаксис со всей семантикой, превратив язык в непонятную ёбу. Я так же ныл (может еще заною, кто его знает). Но это возврат к разговору о возможности прострелить себе ногу. Меня подзаебали эти разговоры, я решил для себя, что прострелить ногу можно везде и всегда. Мутабельность - прострелил. Энергичность - прострелил. Ленивость - иди чини ноги. Иммутабельность - не прочитал книгу по иммутабельным структурам данных? пиздуй в больницу чинить ноги. И так всегда, не бывает серебрянной пули, как не бывает языков общего назначения, как нет искуственого интеллекта. Именно поэтому, программисты существуют, существуют как профессия, как специалисты, а не просто прослойка между креслом и монитором. Хотя надо отдавать себе отчет в собственных возможностях. Это вам не придти и перевести все критические бизнес-процессы на Хаскель из-за того, что кто-то научился Фибоначи считать. И я не один такой, создатель Лифта такой же точки зрения придерживается. То есть в любом случае некоторый опыт необходим.
Во-вторых, макросы сложные. В Nemerle не сложные, то есть при написании макросов используется тот же самый Nemerle и его возможности, никакого специального DSL не требуется. Держим в уме знание, что макрос - функция с типом List[PExpr] -> PExpr, выполняемая во время компиляции, и все будет хорошо. Макросы гигиеничны, то есть при совпадении имен переменной из макроса и контекста, в котором макрос разворачивается, имя из макроса будет автоматически переименовано, хотя это поведение можно отключать, тогда значение будет связано с ближайшим именем в контексте. Таким образом, кстати, работает макра regex match, которую я использовал в своем решении.
Макросы бывают разными
- Макросы выражения: можно сделать printf("%d%f", x, y), который будет на этапе компиляции проверять соответствие количества параметров и их типов строке форматирования; многие компоненты языка такие как if else, while, for и другие реализованы через такие макросы
- Макросы-операторы: собственно через них реализует переопределение и создание новых операторов. Можно задавать приоритет и ассоциативность. Например, с их помощь в Nemerle сделаны pipe-операторы |> и <|
- Мета-атрибуты - видимо, так называются из-за сходства в записили с атрибутами C#. Позволяют изменить класс, метод, свойство и так далее. Для меня самый впечатляющим примером использования является макрос PegGrammar, который по заданной PEG грамматике создает класс-парсер ее разбирающий. Мой игрушечный пример можно увидеть тут. Если игрушки вам не по душе, то можно глянуть на серьезное использование для разбора грамматики C#.
- Лексические макросы: к сожалению, я еще не успел с этим разобраться, но похоже, макра конструирования XML, напоминающая синтаксис для работы с XML в Scala, относится именно к этой категории.
Мне очень хочется, рассказать о макросах Nemerle, кратко и содержательно, чтобы вы могли испытать то же ВАУ, которое испытываю я. Но, по всей видимости, пока в моем мозгу все по полочкам не разложится, я не смогу внятно излагать. Главное, что я хочу донести, что макросы в Nemerle - это очень гибкое средство, которое красиво и лаконично ложится на язык. Синтаксис языка во много сделан на макросах, кодогенерация требующая в C# сторонных тулзовин отлично реализуется, многие хорошие фичи, которые приходят в C#, как новые элементы языка, делаются на макросах. Я думаю, так ожидаемые Type Providers из F# 3.0 делаются на макросах на ура. То есть я пока не вижу, где заканчиваются возможности, но четко представляю, как применять эти вещи в работе: будь-то автоматическая имплементация всяких IDataErrorInfo с INotifyChanged или как присахарить и обезопасить работу с каким-нибудь SqlCommand. При этом я без проблем, могу использовать существующий C# код, могу использовать в C# проектах код на Nemerle (пока не тестировал). Я считаю, что Nemerle - более удобный и качественный инструмент для решения мох задач.
Надесь, было хоть чуть-чуть интересно. Но если вы внезапно дочитали до сюда и считаете все вышенаписаное бредом идиота , хотя бы начинайте псить. Мне приятно будет)
Update: Как-то получилось, что обсуждение велось параллельно в двух местах: тут и еще одна ветка обсуждения.
no subject
Нормальный порядок вычислений (normal reduction order) снижает потребность в макросах на порядки. Не говоря уж про зависимые типы данных, в которых вообще проекции Футамуры самозарождаются как бы ниоткуда (и пример с printf является чуть ли не классическим, пусть в чуть более простом варианте).
no subject
>Нормальный порядок вычислений (normal reduction order) снижает потребность в макросах на порядки
Как нормальный порядок вычислений снижает потребность в макросах?
Не говоря уж про зависимые типы данных
Вы про Хаскель? Там уже сделали зависимые типы? А можно пример? И printf из ниоткуда?
no subject
>Как нормальный порядок вычислений снижает потребность в макросах?
Нормально так снижает, на порядки. Даже можно сказать, замечательно снижает, ибо на порядки.
Простой пример. if в лиспе - специальная форма. В обычных языках программирования он встроен потому, что иначе нельзя. В Хаскеле этот оператор встроен потому, что чуть удобней.
Вот аналог if на Хаскеле:
ifThenElse :: Bool -> a -> a -> a
ifThenElse True th el = th
ifThenElse False th el = el
Теперь вместо "if c then aaa x else bbb y" вы можете писать ifThenElse c (aaa x) (bbb y) и никто не отличит вашу программу от использующую встроенные if. Это будет работать даже с вводом-выводом, ибо этот ввод-вывод не будет выполняться до тех пор, пока от него не потребуют результата.
И далее там всякое интересное. Tying the knot, и тп.
Это не даёт преимуществ оптимизирующих макросов, но и так неплохо, ибо производительность программиста растёт. Вместе с прагмой RULES может дать ещё и выигрыш по скорости.
Насчёт printf. Хаскель не умеет анализировать значения. Но может анализировать типы.
Пусть за меня говорит Олег: http://okmij.org/ftp/typed-formatting/index.html
no subject
no subject
no subject
зато здесь
switch...casepattern matching является специальной формойno subject
http://en.wikipedia.org/wiki/Church_encoding
Сравнение с образцом введено потому, что... удобней! Для алгебраического типа данных можно ввести кодирование функциями, которое будет выполнять "сравнение с образцом". В этом случае case превращается в простое применение функций.
type Bool' a = a -> a -> a -- решил дать параметр, поскольку со скрытием возникают проблемы.
true, false :: Bool' a
true th el = th
false th el = el
a &&. b = a b false
a ||. b = a true b
ifThenElse :: Bool' a -> a -> a
ifThenElse c th el = c th el
no subject
вот покажите реализацию функции, которая, например, вернёт true этого Bool', если x < 5, а в противном случае - false, тогда отстану. А то пока не очевидно, что можно совсем-совсем обойтись.
no subject
Попробуйте прочитать про кодирование Чёрча и написать сами. Это не сложно.
Числа:
data Nat = Zero | Succ Nat
Предикат:
less :: Nat -> Nat -> Bool
less Zero (Succ n) = True
less Zero Zero = False
less (Succ a) (Succ b) = less a b
less (Succ n) Zero = False
five = Succ (Succ (Succ (Succ (Succ Zero))))
less5 a = less a five
Я, с вашего позволения, займусь практическим применением Хаскеля. Это более полезно "для одного из обоих нас".
no subject
no subject
Сравниваю, чтобы показать выразительность ленивых вычислений. Там, где в Хаскеле обходятся одними функциями высших порядков (функция when :: Monad m => Bool -> m a -> m (), bracket :: Monad m => m h -> (h -> m a) -> (h -> m r) -> m r, использовать bracket openFile hClose thingsToWrite), в Лиспе требуются дополнительные выразительные средства.
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(Anonymous) - 2012-05-15 15:09 (UTC) - Expand(no subject)
(Anonymous) - 2012-05-15 15:12 (UTC) - Expandno subject
do_something(x) if condition
Такое насколько легко запилить на ленивых функциях?
Пример с if хрестоматийный, но сильно далеко в этом направлении не уедешь. Макросы же дают свободу в синтаксисе, а ленивость - не очень-то. Вот если бы в хаскеле не было do-нотации, можно ли ее добавить чисто ленивостью? Макросами можно. XML-литералы насколько легко добавить в хаскель одной ленивостью? В язык с макросами легко. Манипуляции с типами функций можно сделать одной ленивостью? Макросами можно. И т.д.
no subject
when' = flip when
f = do
do_something `when'` condition
Вы всё напираете на синтаксис, как и большинство других разработчиков. Синтаксис всего ли часть языка программирования, далеко не самая важная и сложная. Смысл конструкций гораздо важнее.
В чём смысл XML-литералов? В "наглядности", это раз (в кавычках из-за плохой читаемости XML), и в "скорости", это два (ибо всё равно строки соединять). Так вот может важнее правильность этого XML, чтобы вам компилятор быстрее сказал об ошибке в проверке по схеме, чем эти два сомнительных преимущества?
Ознакомьтесь с реализацией Agda2 и семейств типов Хаскеля. Обе реализации ленивые. Это касательно манипуляции с типами функций.
no subject
Правильность XML тоже важна, и ее макрос тоже может проверить, это не преимущество ленивости.
no subject
Нормальный порядок вычислений именно таков: уменьшает количество труда по всему фронту работ.
Типы данных тоже.
И макросы тоже, если рассудить.
Я перечислил инструменты в порядке понимаемой мной важности.
90% применений макросов может быть убрано нормальным порядком вычислений. См. Алана Кея: http://kazimirmajorinc.blogspot.com/2010/02/alan-kay-on-fexprs.html
Ещё 90% оставшихся 10% - типами (правильность XML).
И вот где уж совсем никак, надо применять макросы. 1% применений макросов действительно оправдан, а не вызван недостатками семантики или системы типов языка.
no subject
(no subject)
(Anonymous) - 2012-05-15 15:17 (UTC) - Expandno subject
(Anonymous) 2012-05-15 03:15 pm (UTC)(link)> Ещё 90% оставшихся 10% - типами (правильность XML).
С другой стороны, 100% применений ленивости может быть убрано макросами. !00% применений типов тоже может быть убрано макросами.
То есть случаев, в которых применение типов и лени оправдано не остается. Зачем же множить сущности?
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
no subject
В чём же недостаток?
no subject
no subject
(Anonymous) 2012-05-15 03:07 pm (UTC)(link)no subject
Лиспомакросы:
Типизированные ленивые частично-применяемые функции:
bracket = unwind-protect
no subject
(Anonymous) 2012-05-15 03:03 pm (UTC)(link)no subject
no subject
ACL2 использовался, когда не было других средств (Coq, Isabelle и прочих). Последнее крупное применение - верификация FPU для AMD.
Про применение Qi я ничего не слышал.
no subject