Re: Metaprogramming & higher-order functions dualis
От: Jack128  
Дата: 18.03.11 06:48
Оценка: 3 (2) +2
Здравствуйте, __lambda__, Вы писали:

___>Итого, я выдвигаю такую гипотезу, что метапрограммирование на макросах и функции высшего порядка равносильны. И что, то же самое, мы можем делать в рамках нашего языка, не меняя его синтаксис. Для опровержения моей гипотезы, достаточно привести пример такого макроса, который не возможно повторить на функциях высшего порядка. Жду ваших мыслей по этому поводу.


Если в языке есть только функции, то возможно(не уверен) на ФВП и можно повторить все, что можно сделать на макрасах. Но как только в языке появляется еще что нить (ну например типы) — то все. макрос может создать новый тип, а функция — нема.
Re[3]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.03.11 15:00
Оценка: -1 :))
Здравствуйте, __lambda__, Вы писали:

___>Я вот еще что подумал, на самом деле это хорошо, что нельзя вводить новый синтаксис. Достаточно посмотреть на loop в Common Lisp'е, такой хитрый новый синтаксис там ввели, что иногда хочется застрелиться.


Уважамый, ты видимо вообще не слушаешь что тебе говорят. В Лиспе нельзя вводить новый синтаксис. Там можно вводить только новую семантику. Это раз.

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

___>Так вот, насколько мне известно, Common Lisp'еры делятся на два лагеря, противники такого вида извращения и любители такого дела.


Ты прочитал одну книку и на основании этого судишь о вещах которые не пробывал на практике. Это из серии "Сам я Пастернака не читал, но как и вест советский народ осуждаю его...".

___>Я бы себя отнес к противникам введения нового синтаксиса.


Ты бы лучше отнес себя к новичкам прочитавшим о чем-то большом и интересным, но пока что не разобравшихся в нем. И попробывал бы освоить то о чем прочитал.

Не равен час, ты приобщишся к весьма печальному лагерю теоретиков-критиков. Котрые критикую то, что сами до конца не понимаю. Твои теории о равнозначности мощности говорят именно об этом.

Так что мой тебе совет. Разберись в том что хочешь критиковать, или не берись за критику. Иначе нечего кроме пропаганды заблуждений и домыслов ты не добьешься.

___>Тогда у нас получается единый синтаксис, причем очень простой, вида:

___>
___>(op arg1 arg2 arg3 ...)
___>

___>где, op — встроенная специальная форма, функция или макрос. Макрос становится не сложнее, чем вызов обычной функции. Что не вредит читабельности кода в целом.

Синтаксис есть синтаксис. Где-то он нужен, где-то нет. Если макрос — это всего лишь метапрограмма генерирующая код по определенной модели, то возможно синтаксис ей и не нужен. Но если это DSL, то наличие подходящего синтаксиса может значительно повысить читабельность. Хороший пример тому — это макрос PegGrammar
Автор: Чистяков Владислав Юрьевич
Дата: 11.12.10
или XML-литералы.

Вообще, макросы можно разделить на три независимых вида:
1. Макросы меняющие семантику языка. Это когда синтаксис не меняется, но меняется его интерпретация (семанитика).
2. Макросы описывающие DSL (мини язык). DSL-и могут быть внешними и внутренними. Макры в осноновом рассчитаны на создание внутрениних DSL-ей (DSL-ей встроенных в основной язык).
3. Макросы расширяющие язык новыми конструкциями.

Все три имеют право на жизнь и удобны при определенных условиях. Если не затыкать макрами все дыры, то это очень эффективный инструмент.

___>Хотя из всех правил должны быть исключения, например, я двумя руками за такой макрос:

___>
___>(infix 1 + 2 * 4)
___>

___>потому как, математические выражения более привычны в таком виде.

Это проблемы Липа. В Немерле, например, для операторов и так используется инфиксная запись. Более того можно объявлять новые операторы которые по выбору могут быть или статическими функциями, или макросами. Например, вот макрос оператора ?. аналогичного Грувийному оператору.
Пример использования:
using System;
using System.Console;
using Nemerle;
using OverloadedList;

namespace IgnoreNullOperator
{
  class A { public i : int = 2; }
  class B { public a : IgnoreNullOperator.A = null; }
  class C { public a : IgnoreNullOperator.B = null; }
  module Test
  {
    public Test() : void
    {
      WriteLine("--------- Begin '?.' test ---------");
      def b1 = IgnoreNullOperator.B();
      
      WriteLine(b1?.a?.i);
      
      for (mutable str = null; str?.Length <= 4; str += "Test")
      {
        WriteLine(str?.ToString() + "s");
        WriteLine(str?.Length);
        //WriteLine(str?.[0]);
      }
      
      WriteLine("--------- End '?.' test ---------");
    }
  }
}

Код макроса

___>Если послушать опытных Лисперов, то их мнение такое, что макросы нужно применять только в том случае, когда уже ни одно средство не помогает, то есть, в исключительных случаях.


Если послушать опытных программистов, то языковые средства нужно применять только там где надо. Сказем, не стоит городить функцию ради вычисления умещающегося в пяти символах. Точно так же не стоит лепить макросы там где можно обойтись функций. Но есть множество случаев когда языковых средств нехватает. И тут макросы приходят на выручку, в то время как преверженцы безмакросных языков начинают лепить говнокод.

А вообще, слушал ты поять же лисперов плохо. Точнее слушакл, но интерпретировал по-своему (не смотря на отсутствие опыта). Фраза эта звучала так:

Однако мне кажется, что я могу дать убедительный аргумент. Исходный текст редактора Viaweb на 20-25 процентов состоял из макросов. Макросы сложнее писать, чем обычные функции Lisp'а, и считается дурным тоном использовать их там, где можно без них обойтись. Поэтому каждый макрос в той программе был необходим. Это значит, что примерно 20-25 процентов кода в программе делают то, что нельзя просто сделать на других языках.

Впервые я услышал ее в статье Пола Грехема "Lisp: побеждая посредственность". Она была чатстью забавнейшего рассуждения о мощности языков и парадоксе Блаба
Автор: VladD2
Дата: 23.11.06
.
Важно вэтой фразе не то, что "считается дурным тоном использовать их (макросы) там, где можно без них обойтись", а то что "каждый макрос в той программе был необходим". Подумай об этом.

ЗЫ

Вообще исходя из того же парадокса Блаба можно смело утверждать, что необходимость макросов вещь надуманная. Любую задачу можно решить и без них. Макросы — это мощный интрумент снижения сложности разработки ПО. Но действует он только в тех руках которые пренадлежат к голове полностью понимающей смысл макросов и умеющей испльзовать их на практике (проектировать ПО с их помощью).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Metaprogramming & higher-order functions dualis
От: hi_octane Беларусь  
Дата: 18.03.11 10:02
Оценка: 5 (1) :)
___>Итого, я выдвигаю такую гипотезу, что метапрограммирование на макросах и функции высшего порядка равносильны. И что, то же самое, мы можем делать в рамках нашего языка, не меняя его синтаксис. Для опровержения моей гипотезы, достаточно привести пример такого макроса, который не возможно повторить на функциях высшего порядка. Жду ваших мыслей по этому поводу.

Ты только одно малюсенькое применение макросов просто рассмотрел, вот и создалось ложное впечатление. У нас есть макрос который javascript файл из сети во время компиляции вытягивает, парсит, и по нему кучу кода строит, с типами, интерфейсами и т.п. Нужен для согласования с внешней системой. На ФВП такое не слепишь, кодогенератором заранее не сгенерируешь.
Вот ещё сейчас пишу макрос для проекта, который дополнительно ограничивает область видимости переменных:
class A
{  
  public func() : void
  {
    private c = 0;

    //код использующий c
  }
}

Из функции поле C выносится в класс, но доступно определение только в этой функции, остальным C не видно. Так что при всём желании нахачить ошибку не смогут. На ФВП такое попробуй повтори
Re: Metaprogramming & higher-order functions dualis
От: Sinclair Россия https://github.com/evilguest/
Дата: 18.03.11 06:53
Оценка: 4 (1) +1
Здравствуйте, __lambda__, Вы писали:
___>Жду ваших мыслей по этому поводу.
Для чисто-ФП языка всё будет работать. См. например серию Барта про построение всех высокоуровневых конструкций из подручных средств:
http://bartdesmet.net/blogs/bart/archive/2009/07/14/bart-s-control-library-not-what-you-think-it-is-part-2.aspx (и по ссылкам на части 1 и 0)

Но вот, к примеру, прикрутить к классу дефолтную реализацию некоего интерфейса при помощи чисто ФВП не выйдет. А макросы способны и на это.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Metaprogramming & higher-order functions dualis
От: dotneter  
Дата: 18.03.11 08:41
Оценка: +2
Здравствуйте, Jack128, Вы писали:

J>Если в языке есть только функции, то возможно(не уверен) на ФВП и можно повторить все, что можно сделать на макрасах.

Макросы это кодогенерация, как с помощью фвп сгенерировать например по wsdl обертку к сервису?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Talk is cheap. Show me the code.
Re[2]: Metaprogramming & higher-order functions dualis
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 18.03.11 09:53
Оценка: -1 :)
Здравствуйте, Jack128, Вы писали:

J>Если в языке есть только функции, то возможно(не уверен) на ФВП и можно повторить все, что можно сделать на макрасах. Но как только в языке появляется еще что нить (ну например типы) — то все. макрос может создать новый тип, а функция — нема.


А как с помощью макроса можно создать новый тип?

Я например, новый тип создавал с помощью одних только функций в Common Lisp'e:
(define make-pos (row col)
  (cons row col))

(define get-row (pos)
  (car pos))

(define get-col (pos)
  (cdr pos))

То есть, на одних лишь функциях создаю новую абстракцию pos, у которой есть конструктор make-pos, есть геттеры get-row и get-col.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[4]: Metaprogramming & higher-order functions dualis
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 23.03.11 02:00
Оценка: +2
Здравствуйте, VladD2, Вы писали:

VD>Уважамый, ты видимо вообще не слушаешь что тебе говорят. В Лиспе нельзя вводить новый синтаксис. Там можно вводить только новую семантику. Это раз.


Уважаемый, потрудитесь пройти по той ссылке, которую я привел. Когда изучите более подробно мат. часть, тогда можно с Вами продолжить беседу, а пока, извините.

VD>Ты прочитал одну книку и на основании этого судишь о вещах которые не пробывал на практике. Это из серии "Сам я Пастернака не читал, но как и вест советский народ осуждаю его...".


Ты судишь о человеке, котором ничего не знаешь, обсуждаешь его личность, хотя это запрещено правилами форума. Ах да, Вы же у нас модератор, Вам все можно, я понял, не бейте меня, все, я удаляюсь...

VD>Ты бы лучше отнес себя к новичкам прочитавшим о чем-то большом и интересным, но пока что не разобравшихся в нем. И попробывал бы освоить то о чем прочитал.


Ты бы лучше мне не указывал, что мне делать и куда себя относить, тогда я не скажу куда тебе следует пойти со своими советами.

VD>Не равен час, ты приобщишся к весьма печальному лагерю теоретиков-критиков. Котрые критикую то, что сами до конца не понимаю. Твои теории о равнозначности мощности говорят именно об этом.


Круто, я попал на передачу "Битва экстрасенсов"

VD>Так что мой тебе совет. Разберись в том что хочешь критиковать, или не берись за критику. Иначе нечего кроме пропаганды заблуждений и домыслов ты не добьешься.


А вот мой тебе совет, прежде чем вести себя так по хамски и высокомерно, убедись в том, что ты не выглядишь при этом как клоун, даже я со своими базовыми начальными знаниям о Лиспе, вижу как ты глубоко ошибаешься.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re: Metaprogramming & higher-order functions dualis
От: 0x7be СССР  
Дата: 18.03.11 06:56
Оценка: 4 (1)
Здравствуйте, __lambda__, Вы писали:


___>Итого, я выдвигаю такую гипотезу, что метапрограммирование на макросах и функции высшего порядка равносильны. И что, то же самое, мы можем делать в рамках нашего языка, не меняя его синтаксис. Для опровержения моей гипотезы, достаточно привести пример такого макроса, который не возможно повторить на функциях высшего порядка. Жду ваших мыслей по этому поводу.

Разбери, плз, такой прецедент: есть необходимость проверять параметры функций на не-null`овость. Для этого в начале каждой функции приходится писать однообразный код вида:
public SomeType MyFunction(ReferenceType1 param1, ReferenceType2 param2, ValueType param3)
{
  Guard.CheckNotNull(param1, "param1");
  Guard.CheckNotNull(param2, "param2");
  ...
}

Тупой и однообразный код, который легко генерируется макросами (на том же Немерле).
Как через ФВП решить эту задачу? Если ещё придумаешь удовлетворительное решение на C#, то я тебе бутылку коньяка куплю,
ибо задача из реального проекта, где этот код в больших количествах приходится писать ручками
Re[2]: Metaprogramming & higher-order functions dualis
От: deniok Россия  
Дата: 18.03.11 08:23
Оценка: +1
Здравствуйте, Jack128, Вы писали:


J>Если в языке есть только функции, то возможно(не уверен) на ФВП и можно повторить все, что можно сделать на макрасах. Но как только в языке появляется еще что нить (ну например типы) — то все. макрос может создать новый тип, а функция — нема.


Зависимые типы именно для этого и созданы — они позволяют создавать типы из выражений языка (термов), то есть строить функции из термов в типы.
Re: Metaprogramming & higher-order functions dualis
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 18.03.11 10:32
Оценка: +1
Здравствуйте, __lambda__, Вы писали:

___>Итого, я выдвигаю такую гипотезу, что метапрограммирование на макросах и функции высшего порядка равносильны. И что, то же самое, мы можем делать в рамках нашего языка, не меняя его синтаксис. Для опровержения моей гипотезы, достаточно привести пример такого макроса, который не возможно повторить на функциях высшего порядка. Жду ваших мыслей по этому поводу.


Действительно, оказывается есть такие примеры, где макросы мощнее, чем ФВП. Моя гипотеза опровергнута.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[4]: Metaprogramming & higher-order functions dualis
От: Mr.Cat  
Дата: 18.03.11 13:14
Оценка: +1
Здравствуйте, WolfHound, Вы писали:
___>>Я например, новый тип создавал с помощью одних только функций в Common Lisp'e:
WH>Лисп динамически типизированный язык.
И?
Re[4]: Metaprogramming & higher-order functions dualis
От: FR  
Дата: 20.03.11 07:01
Оценка: +1
Здравствуйте, Mr.Cat, Вы писали:

MC>Формально — это не тип. Твой pos будет откликаться на предикаты, проверяющие на принадлежность к cons cell (не знаю, как оно в cl, в схеме это "pair?") и корректно обрабатываться функциями, работающими с cons cell. И, самое важное, нет предиката, который отличал бы pos от любой другой cons cell. Обычно в лиспах есть возможность объявить структуру или типа того — без таких неприятных особенностей.


Ну если взять например питон (в руби вроде также) можно без проблем написать функцию возвращающую новый класс (не объект).
В общем в динамическом языке вполне реально обойтись только функциями, но все равно эти функции используют возможность относящуюся
к метапрограммированию а именно мета классы и возможность создавать классы на ходу.
То есть без макросов вполне можно обойтись, но мета в том или ином виде все равно появится.
Re[4]: Metaprogramming & higher-order functions dualis
От: FR  
Дата: 20.03.11 07:05
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

___>>Я например, новый тип создавал с помощью одних только функций в Common Lisp'e:

WH>Лисп динамически типизированный язык.

По моему достаточно языка с первоклассными классами, то есть с поддержкой метаклассов, правда все сейчас живые такие языки динамические.
Ну или чтобы язык поддерживал манипуляцию типами хотя бы в compile time то есть шаблоны C++ или D.
Re[3]: Metaprogramming & higher-order functions dualis
От: hardcase Пират http://nemerle.org
Дата: 23.03.11 07:25
Оценка: +1
Здравствуйте, __lambda__, Вы писали:

___>Здравствуйте, VladD2, Вы писали:


VD>>Да, и еще хочу тебя удивить. В Лиспе (лкассическом) нельзя вводить новый синтаксс. То есть вообще нельзя вводить синтаксис. Лисп строится на реинтерпретации весьма обобщеггого синтаксиса S-выражений. Все что ты в нем меняешь — это семантика. А вот в Немерле можно менять и синтаксис. Не на 100, но все же. Например, тот же случай с файлами в немерле превращается в конструкцию using полностью аналогичную C#-овской.


___>Я вот еще что подумал, на самом деле это хорошо, что нельзя вводить новый синтаксис. Достаточно посмотреть на loop в Common Lisp'е, такой хитрый новый синтаксис там ввели, что иногда хочется застрелиться. Так вот, насколько мне известно, Common Lisp'еры делятся на два лагеря, противники такого вида извращения и любители такого дела.


Этот "синтаксис" вообще не выходит за рамки S-выражений. Я почти уверен, что макра loop просто матчит все эти ключевые слова.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[5]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.03.11 16:09
Оценка: :)
Здравствуйте, __lambda__, Вы писали:

VD>>Уважамый, ты видимо вообще не слушаешь что тебе говорят. В Лиспе нельзя вводить новый синтаксис. Там можно вводить только новую семантику. Это раз.


___>Уважаемый, потрудитесь пройти по той ссылке, которую я привел. Когда изучите более подробно мат. часть, тогда можно с Вами продолжить беседу, а пока, извините.


Я знаком с CL и его крутым for-ом. Вот только никакого нового синтаксиса в нем нет. Точно такой же синтаксис у вызова функции.

VD>>Ты прочитал одну книку и на основании этого судишь о вещах которые не пробывал на практике. Это из серии "Сам я Пастернака не читал, но как и вест советский народ осуждаю его...".


___>Ты судишь о человеке, котором ничего не знаешь, обсуждаешь его личность, хотя это запрещено правилами форума.


Я сужу о высказываниях человека. И обсуждаю тоже их. Правилами форума это не запрещается ни разу. Если человек говорит вещи не соответствующие действительности или выносит поверхностные суждения, то я так и говорю.

___>Ах да, Вы же у нас модератор, Вам все можно, я понял, не бейте меня, все, я удаляюсь...


Еще одно не соответствующие действительности заявление. В этом форуме я не модератор.

VD>>Ты бы лучше отнес себя к новичкам прочитавшим о чем-то большом и интересным, но пока что не разобравшихся в нем. И попробывал бы освоить то о чем прочитал.


___>Ты бы лучше мне не указывал, что мне делать и куда себя относить, тогда я не скажу куда тебе следует пойти со своими советами.


Вот за указание куда пойти здесь точно в баню отправляют. Так что не стоит.
А не хочешь выслушивать советы, сиди дома и не вылезай в отрытые форумы.

Указывать я тебе не могу, конечно. Только советовать. Ну, а советы вещь такая. Хочешь игнорируешь, хочешь прислушивайся.

Если ты лиспер (или использовал другой язык с макрами) с многолетним стажем, написавший и отладивший не один макрос, то конечно надо игнорировать подобные советы. Ну, а если весь опыт общения с лиспом сводится к прочтению пары книг и баловству в репле, то почему бы не прислушаться?

VD>>Не равен час, ты приобщишся к весьма печальному лагерю теоретиков-критиков. Котрые критикую то, что сами до конца не понимаю. Твои теории о равнозначности мощности говорят именно об этом.


___>Круто, я попал на передачу "Битва экстрасенсов"


Не надо быть экстрасенсом чтобы видеть что ты критикуешь то, что сам плохо знаешь.

VD>>Так что мой тебе совет. Разберись в том что хочешь критиковать, или не берись за критику. Иначе нечего кроме пропаганды заблуждений и домыслов ты не добьешься.


___>А вот мой тебе совет, прежде чем вести себя так по хамски и высокомерно, убедись в том, что ты не выглядишь при этом как клоун, даже я со своими базовыми начальными знаниям о Лиспе, вижу как ты глубоко ошибаешься.


Я как-то не понял в чем я ошибаюсь. И уверяю тебя, что хамить я даже не собирался.

Мои слова кажутся тебе высокомерными и хамскими именно потому, что ты и сам понимаешь, что ты не прав. Все что я тебе пытался сказать — это то что прежде чем судить о тех же макросах нужно попробовать их на практике. Всего то! Причем даже не обязательно делать это в Лисп. Есть и другие языки.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 25.03.11 07:09
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, VoidEx, Вы писали:


VE>>И будешь везде пропихивать этот кортеж? Отличное решение.


VD>Куда его пропихивать то? Кода 5 строк.


Не 5, а 25, из них в 8-ми повторяется (loc, n), причем в каждой неоднократно.
Metaprogramming & higher-order functions dualis
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 18.03.11 06:39
Оценка:
Я тут немного пофилософствовал на тему метапрограммирования на макросах и его дуализма с функциями высшего порядка. Давайте по порядку, начнем с самого начала. А началось все с того, что начал я изучать очень клевый язык, который называется Лисп (если быть точнее, то это семейство языков). Одним из его мощнейших свойств являются макросы. Суть в том, что с помощью них, мы можем избежать дублирования кода. А также строить полноценные мини-языки (eDSL) и т.д. Но давайте ближе к делу, то есть, ближе к коду. Рассмотрим такой участок кода на гипотетическом языке похожем на Си:
try
{
    file.assign(fname);
    file.open();
    // do something
    file.process();
}
finally
{
    file.close();
}

Такой код может часто встречаться в программе и мы вынуждены будем каждый раз дублировать его. Сразу видно, что "переменными" тут являются file, fname и код после комментария do something. Все остальное, всегда будет одним и тем же, открытие файла, обработка исключений и закрытие файла.

Что могут в данном случае нам предоставить макросы Лиспа? Давайте рассмотрим гипотетический код на языке похожем на Лисп:
(with-open-file (file fname)
    (file.process))

Этот код аналогичен вышеприведенному коду. Здесь мы видим, что тут у нас остались так называемые "переменные" участки кода. А все остальное скрывается под капотом макроса with-open-file, то есть, открытие/закрытие файла, обработка исключения все равно выполняются. Мы можем вызывать этот макрос с другими "переменными":
(with-open-file (in-file "input.txt")
    (parse-data in-file)
    (print "file parsed"))

Нам не пришлось заново писать рутину в виде обработки исключений, открытия и закрытия файла.

И достигалось бы это с помощью примерно такого гипотетического макроса:
(defmacro with-open-file (file fname rest &body)
    `(try
         (,file.assign ,fname)
         (,file.open)
         ,@body)
         (finally
             (,file.close))))

Пишу от балды, похожем на Common Lisp синтаксисе. Главное, чтобы передавало суть, основную идею.

То есть, с помощью макросов, мы можем избавиться от дублирующегося кода. Более того, вводим новую синтаксическую конструкцию with-open-file, обладающей заданной нами семантикой.

И тут я глубоко призадумался, можно ли в других языках, избавляться от такого вида дублирования кода или мы обречены писать дублирующийся код?

Ответ, да. Мы можем это сделать, но с помощью другого механизма, который называется функции высшего порядка. Это когда, функции, являются объектами первого класса, то бишь, мы функции можем хранить в переменных, передавать как параметр в другую функцию и возвращать из функции как результат. Давайте посмотрим, как можно было сделать все то же самое, что мы делали с помощью макросов, будь у нас функции высокого порядка, на гипотетическом языке похожем на Си, у которого есть функции высокого порядка:
var open-file = function (file, fname, action) {
                             try {
                                 file.assign(fname);
                                 file.open();
                                 action();
                             }
                             finally {
                                 file.close();
                             }

open-file("input1.txt", in-file1, function () { in-file1.process(); });
open-file("input2.txt", in-file2, function () { in-file2.process(); });

Таким образом мы можем избавиться от дублирующегося кода с помощью функций высокого порядка без применения макросов. Я тут у себя даже попробовал примерно нарисовать небольшой eDSL'чик. Вроде получается, например, попробовал ввести аналог цикла while:
var while = function (i, cond, body) {
                       loop {
                           if (cond(i))
                               body(i);
                           else
                               break;
                       }
                   }

var i = 0;
while(i, func (i) { i < 10 }, func (i) { print(i); });


Итого, я выдвигаю такую гипотезу, что метапрограммирование на макросах и функции высшего порядка равносильны. И что, то же самое, мы можем делать в рамках нашего языка, не меняя его синтаксис. Для опровержения моей гипотезы, достаточно привести пример такого макроса, который не возможно повторить на функциях высшего порядка. Жду ваших мыслей по этому поводу.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re: Metaprogramming & higher-order functions dualis
От: WolfHound  
Дата: 18.03.11 07:12
Оценка:
Здравствуйте, __lambda__, Вы писали:

___>Итого, я выдвигаю такую гипотезу, что метапрограммирование на макросах и функции высшего порядка равносильны. И что, то же самое, мы можем делать в рамках нашего языка, не меняя его синтаксис. Для опровержения моей гипотезы, достаточно привести пример такого макроса, который не возможно повторить на функциях высшего порядка. Жду ваших мыслей по этому поводу.

Вот макра попроще.
Вот посложнее. Пример.
Вот макра которая переписывается в вызовы ФВП. Ибо если использовать ФВП напрямую получается такая грязюка что аж жуть...
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Metaprogramming & higher-order functions dualis
От: dotneter  
Дата: 18.03.11 07:34
Оценка:
Здравствуйте, __lambda__, Вы писали:

___>Для опровержения моей гипотезы, достаточно привести пример такого макроса, который не возможно повторить на функциях высшего порядка.

define-struct
___>Жду ваших мыслей по этому поводу.
В чем то они конечно похожи, функция это переиспользуемый статический кусок кода, макрос динамический, там где динамику можно заменить функцией, по сути они равны. C фвп можно более менее оперировать на уровне потока вычисления, но до уровня типов вы с ними не доберетесь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Talk is cheap. Show me the code.
Re[2]: Metaprogramming & higher-order functions dualis
От: Temoto  
Дата: 18.03.11 08:01
Оценка:
___>>Итого, я выдвигаю такую гипотезу, что метапрограммирование на макросах и функции высшего порядка равносильны. И что, то же самое, мы можем делать в рамках нашего языка, не меняя его синтаксис. Для опровержения моей гипотезы, достаточно привести пример такого макроса, который не возможно повторить на функциях высшего порядка. Жду ваших мыслей по этому поводу.
0>Разбери, плз, такой прецедент: есть необходимость проверять параметры функций на не-null`овость. Для этого в начале каждой функции приходится писать однообразный код вида:
0>
0>public SomeType MyFunction(ReferenceType1 param1, ReferenceType2 param2, ValueType param3)
0>{
0>  Guard.CheckNotNull(param1, "param1");
0>  Guard.CheckNotNull(param2, "param2");
0>  ...
0>}
0>

0>Тупой и однообразный код, который легко генерируется макросами (на том же Немерле).
0>Как через ФВП решить эту задачу? Если ещё придумаешь удовлетворительное решение на C#, то я тебе бутылку коньяка куплю,
0>ибо задача из реального проекта, где этот код в больших количествах приходится писать ручками

А разве в шарпе не было полноценных контрактов через [аттрибуты] ?
Re[3]: Metaprogramming & higher-order functions dualis
От: 0x7be СССР  
Дата: 18.03.11 10:02
Оценка:
Здравствуйте, Temoto, Вы писали:

T>А разве в шарпе не было полноценных контрактов через [аттрибуты] ?

Есть, но не в шарпе, в виде сторонней библиотеки.
Однако вопрос не в этом, а как сделать сказанное через ФВП.
Re[4]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 18.03.11 10:16
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Здравствуйте, Temoto, Вы писали:


T>>А разве в шарпе не было полноценных контрактов через [аттрибуты] ?

0>Есть, но не в шарпе, в виде сторонней библиотеки.
0>Однако вопрос не в этом, а как сделать сказанное через ФВП.

А в чём вообще вопрос? В том, как из идентификатора получить его имя в виде строки или в том, чтобы не писать x второй раз в foo x = { notnull x; ... }?
foo = notnull $ \x -> notnull $ \y -> \z ->
    x + y + z


Красота сомнительна, конечно, но речь и не о ней, как я понял. Иначе достаточно было бы попросить сделать в ФВП
var camelCased(some_name) = 34; // SomeName = 34;
SomeName = 22;
Re[2]: Metaprogramming & higher-order functions dualis
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 18.03.11 10:24
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Разбери, плз, такой прецедент: есть необходимость проверять параметры функций на не-null`овость. Для этого в начале каждой функции приходится писать однообразный код вида:

0>
0>public SomeType MyFunction(ReferenceType1 param1, ReferenceType2 param2, ValueType param3)
0>{
0>  Guard.CheckNotNull(param1, "param1");
0>  Guard.CheckNotNull(param2, "param2");
0>  ...
0>}
0>


Не знаю, я бы тут мудрить не стал бы, а тупо написал бы функцию хелпер, типа:
void CheckNotNulls(params object[] args)
{
  // и тут бы дергал для каждого параметра CheckNotNull
}

Итого, твой пример превратился бы в:
public SomeType MyFunction(ReferenceType1 param1, ReferenceType2 param2, ValueType param3)
{
  Guard.CheckNotNulls(param1, param2);
  ...
}

Вместо N строк на каждый параметр, мы теперь вызываем одну функцию CheckNotNulls, но зато с N параметрами, а это все равно 1 строка.

А так, да. Кажется тут ФВП не особо помогут.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[3]: Metaprogramming & higher-order functions dualis
От: 0x7be СССР  
Дата: 18.03.11 10:29
Оценка:
Здравствуйте, __lambda__, Вы писали:

___>Вместо N строк на каждый параметр, мы теперь вызываем одну функцию CheckNotNulls, но зато с N параметрами, а это все равно 1 строка.

А названия параметров откуда этот метод будет брать?
Не, есть один обходной вариант, но он завязан на использование Reflection и нецелевого использования анонимных типов.
Re[4]: Metaprogramming & higher-order functions dualis
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.03.11 10:33
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Не, есть один обходной вариант, но он завязан на использование Reflection и нецелевого использования анонимных типов.

Он не один. Есть вариант с нецелевым использованием Expression Tree.
Re[4]: Metaprogramming & higher-order functions dualis
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 18.03.11 10:36
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>А названия параметров откуда этот метод будет брать?


А я не понял, зачем тебе названия параметров? Но все равно, тебе никто не мешает передавать имена параметров тоже CheckNotNulls(param1, "param1", param2, "param2"); а потом уже из этой хелперной функции попарно читать и передавать параметр и его имя в конкретную CheckNotNull.

0>Не, есть один обходной вариант, но он завязан на использование Reflection и нецелевого использования анонимных типов.


Reflection — разве не тормознутый?
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[5]: Metaprogramming & higher-order functions dualis
От: 0x7be СССР  
Дата: 18.03.11 10:44
Оценка:
Здравствуйте, samius, Вы писали:

S>Он не один. Есть вариант с нецелевым использованием Expression Tree.

И так можно, да.
Re[5]: Metaprogramming & higher-order functions dualis
От: 0x7be СССР  
Дата: 18.03.11 10:45
Оценка:
Здравствуйте, __lambda__, Вы писали:

0>>А названия параметров откуда этот метод будет брать?

___>А я не понял, зачем тебе названия параметров? Но все равно, тебе никто не мешает передавать имена параметров тоже CheckNotNulls(param1, "param1", param2, "param2"); а потом уже из этой хелперной функции попарно читать и передавать параметр и его имя в конкретную CheckNotNull.
Названия для того, что бы их в ArgumentException засунуть. Тогда в логе будет видно, что такая вот функйия получила на вход недопустимое значение в такмо-то параметре.

0>>Не, есть один обходной вариант, но он завязан на использование Reflection и нецелевого использования анонимных типов.

___>Reflection — разве не тормознутый?
Тормознутый, но там так хитро придумано, что эти траты одноразовые.
Re[3]: Metaprogramming & higher-order functions dualis
От: WolfHound  
Дата: 18.03.11 12:03
Оценка:
Здравствуйте, __lambda__, Вы писали:

___>А как с помощью макроса можно создать новый тип?

Например вот так:
<[ decl:
    ..$attrs
    class $(name : usesite) : $anonymous_ref, System.IEquatable[ $ty_ref ] {
        ..$members
    }
]>


___>Я например, новый тип создавал с помощью одних только функций в Common Lisp'e:

Лисп динамически типизированный язык.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Metaprogramming & higher-order functions dualis
От: dotneter  
Дата: 18.03.11 12:04
Оценка:
Здравствуйте, hi_octane, Вы писали:
_>кодогенератором заранее не сгенерируешь.
Что ему помешает сделать все тоже самое?
из сети во время компиляции вытягивает, парсит, и по нему кучу кода строит
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Talk is cheap. Show me the code.
Re[3]: Metaprogramming & higher-order functions dualis
От: Mr.Cat  
Дата: 18.03.11 13:13
Оценка:
Здравствуйте, __lambda__, Вы писали:
___>Я например, новый тип создавал с помощью одних только функций в Common Lisp'e:
___>(define make-pos (row col)...
Define — это не функция (я не коммонлиспер, но тут концепции, обшие для всех лиспов). Вызов функции предполагает вычисление значений аргументов. В данном же случае дергаются какие-то внутренние механизмы, создающие биндинг к имени make-pos. Т.е. define — это либо специальная форма, либо макрос вокруг специальной формы.
Re[4]: Metaprogramming & higher-order functions dualis
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 18.03.11 13:29
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

MC>Define — это не функция (я не коммонлиспер, но тут концепции, обшие для всех лиспов).


Я опечатался, имел в виду defun. Запутался я в диалектах Лиспа

Вызов функции предполагает вычисление значений аргументов. В данном же случае дергаются какие-то внутренние механизмы, создающие биндинг к имени make-pos. Т.е. define — это либо специальная форма, либо макрос вокруг специальной формы.

Это специальная форма, привязывающая функцию к имени make-pos, но сути это не меняет, я всего лишь объявляю функцию.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re: Metaprogramming & higher-order functions dualis
От: IT Россия linq2db.com
Дата: 18.03.11 13:30
Оценка:
Здравствуйте, __lambda__, Вы писали:

___>Итого, я выдвигаю такую гипотезу, что метапрограммирование на макросах и функции высшего порядка равносильны. И что, то же самое, мы можем делать в рамках нашего языка, не меняя его синтаксис. Для опровержения моей гипотезы, достаточно привести пример такого макроса, который не возможно повторить на функциях высшего порядка. Жду ваших мыслей по этому поводу.


Дано — строка соединения с базой данных.
Задача — получить сгенерированную по БД модель в виде классов.
Плюсом будет предоставление eDSL, позволяющего модифицировать прочитанные из базы метаданные.
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Metaprogramming & higher-order functions dualis
От: Mr.Cat  
Дата: 18.03.11 13:35
Оценка:
Здравствуйте, __lambda__, Вы писали:
___>Это специальная форма, привязывающая функцию к имени make-pos, но сути это не меняет, я всего лишь объявляю функцию.
Не знаю, что имел в виду автор исходного сообщения под "созданием типа" и будет ли он удовлетворен твоим примером. Я просто подумал, что ты назвал define функцией.
Re[3]: Metaprogramming & higher-order functions dualis
От: Mr.Cat  
Дата: 18.03.11 13:44
Оценка:
Здравствуйте, __lambda__, Вы писали:
___>Я например, новый тип создавал с помощью одних только функций в Common Lisp'e:
___>[code]
___>(define make-pos (row col)
___> (cons row col))
И да.
Формально — это не тип. Твой pos будет откликаться на предикаты, проверяющие на принадлежность к cons cell (не знаю, как оно в cl, в схеме это "pair?") и корректно обрабатываться функциями, работающими с cons cell. И, самое важное, нет предиката, который отличал бы pos от любой другой cons cell. Обычно в лиспах есть возможность объявить структуру или типа того — без таких неприятных особенностей.
Re[3]: Metaprogramming & higher-order functions dualis
От: hardcase Пират http://nemerle.org
Дата: 18.03.11 19:05
Оценка:
Здравствуйте, dotneter, Вы писали:

D>Здравствуйте, Jack128, Вы писали:


J>>Если в языке есть только функции, то возможно(не уверен) на ФВП и можно повторить все, что можно сделать на макрасах.

D>Макросы это кодогенерация, как с помощью фвп сгенерировать например по wsdl обертку к сервису?

Макросы — это не только ценный мех кодогенерация, но еще и ДСЛ-естроение.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: Metaprogramming & higher-order functions dualis
От: hardcase Пират http://nemerle.org
Дата: 18.03.11 19:07
Оценка:
Здравствуйте, dotneter, Вы писали:

D>Здравствуйте, hi_octane, Вы писали:

_>>кодогенератором заранее не сгенерируешь.
D>Что ему помешает сделать все тоже самое?
D>из сети во время компиляции вытягивает, парсит, и по нему кучу кода строит

Если есть завязка на код проекта, где раскрывается макрос, то внешнему кодогенератору придется туго — придется парсить исходники целевого языка.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: Metaprogramming & higher-order functions dualis
От: hi_octane Беларусь  
Дата: 18.03.11 20:46
Оценка:
D>Что ему помешает сделать все тоже самое?
D>из сети во время компиляции вытягивает, парсит, и по нему кучу кода строит

hardcase верно предположил.
Простая кодогенерация может создать код вроде библиотечного, может партиал-классов наклепать по захардкоженному знанию о проекте. Но прочитать существующие в проекте типы, расширить их, дополнить классы реализацией интерфейсов — это уже нужно либо кодогенератор ацки хардкодить, дублируя в нём по сути часть проекта, либо учить его парсить исходники. А с макросом получается красивая декларативная форма и без ошибок.
Re: Metaprogramming & higher-order functions dualis
От: Aleх  
Дата: 19.03.11 21:31
Оценка:
Здравствуйте, __lambda__, Вы писали:

___>Итого, я выдвигаю такую гипотезу, что метапрограммирование на макросах и функции высшего порядка равносильны. И что, то же самое, мы можем делать в рамках нашего языка, не меняя его синтаксис. Для опровержения моей гипотезы, достаточно привести пример такого макроса, который не возможно повторить на функциях высшего порядка. Жду ваших мыслей по этому поводу.


Например, генерация кода выполняющего сериализацию структуры данных по её естественному описанию в языке (ну всмысле то, что не надо как-то дополнительно её описывать).
Re: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.11 20:21
Оценка:
Здравствуйте, __lambda__, Вы писали:

___>Итого, я выдвигаю такую гипотезу, что метапрограммирование на макросах и функции высшего порядка равносильны. И что, то же самое, мы можем делать в рамках нашего языка, не меняя его синтаксис. Для опровержения моей гипотезы, достаточно привести пример такого макроса, который не возможно повторить на функциях высшего порядка. Жду ваших мыслей по этому поводу.


1. Тамими примерами является добрая половина макросов немерла.
2. Даже в твоем примере код не развнозначен. Он имеет разную производительность и длинну. Если производительность можно списать на умные оптимизаторы, то длинну уже не спишешь. Для макросов вида:
keyword "(" expression ")" expression

еще можно придумат синтаксический сахар. Например, так сделано в Scala. Но для более сложных макросов это работать не будет. Другими словами нельзя придуать сахар для общего случая.

ЗЫ

Да, и еще хочу тебя удивить. В Лиспе (лкассическом) нельзя вводить новый синтаксс. То есть вообще нельзя вводить синтаксис. Лисп строится на реинтерпретации весьма обобщеггого синтаксиса S-выражений. Все что ты в нем меняешь — это семантика. А вот в Немерле можно менять и синтаксис. Не на 100, но все же. Например, тот же случай с файлами в немерле превращается в конструкцию using полностью аналогичную C#-овской.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.11 20:22
Оценка:
Здравствуйте, deniok, Вы писали:

D>Зависимые типы именно для этого и созданы — они позволяют создавать типы из выражений языка (термов), то есть строить функции из термов в типы.


Только они практически в макросы и превращаются. Что есть макросы? Выисления в компайлтайме которые могут порождать (или менять) код.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.11 20:23
Оценка:
Здравствуйте, hardcase, Вы писали:

D>>Макросы это кодогенерация, как с помощью фвп сгенерировать например по wsdl обертку к сервису?


H>Макросы — это не только ценный мех кодогенерация, но еще и ДСЛ-естроение.


Ключевое слово тут "и". Скажу больше, ДСЛ-естроениек это следствие, а не причина или цель. Но очен приятное следствие.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.11 20:27
Оценка:
Здравствуйте, FR, Вы писали:

FR>То есть без макросов вполне можно обойтись, но мета в том или ином виде все равно появится.


Превразирую твои слова. Без макросов вполне можно обойтись, но получятся все равно те же макросы, но вид в профиль.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.11 20:34
Оценка:
Здравствуйте, __lambda__, Вы писали:

___>Итого, я выдвигаю такую гипотезу, что метапрограммирование на макросах и функции высшего порядка равносильны.


Обдумай очень простую мысль. Лисп — это первый фунциональный да еще и динамический язык. Он с рождения поддерижвал ФВП. Если бы все можно было бы решить ими, то зачем лиспарям было придумывать макросы?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.11 20:37
Оценка:
Здравствуйте, Temoto, Вы писали:

T>А разве в шарпе не было полноценных контрактов через [аттрибуты] ?


Через атрибуты — нет. В шарпе контракты выглядят как вызов фунций внутри тела методов.
А вот, кстати, аналог мета-атрибута (аналога кастом-атрибута C#, но по сути являющегося макросом) немерла:
Примеры испльзования
Реализация
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.11 20:54
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

___>>>Я например, новый тип создавал с помощью одних только функций в Common Lisp'e:

WH>>Лисп динамически типизированный язык.
MC>И?

И в нем метапрограммирование доступно в том числе в форме динамического выполнения. Лиспу это не особо нужно, но разным Руби и Питонам позволяют получить средства метапрограммирвоания без явного наличия макросов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.11 20:56
Оценка:
Здравствуйте, FR, Вы писали:

FR>По моему достаточно языка с первоклассными классами, то есть с поддержкой метаклассов, правда все сейчас живые такие языки динамические.


Смешно. Они и могут быть только в динамических языках. Ну разве что еще в гибридных (но я таких не видел). Ведь метакласс уже сам по себе предпологает динамическое связыание.

FR>Ну или чтобы язык поддерживал манипуляцию типами хотя бы в compile time то есть шаблоны C++ или D.


Дык это и етсть недоделанные макросы. По крайней мере средства метапрограммирования. Автор же утверждал, что макросы эквивалентны по мощности ФВП.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Metaprogramming & higher-order functions dualis
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 22.03.11 06:30
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Да, и еще хочу тебя удивить. В Лиспе (лкассическом) нельзя вводить новый синтаксс. То есть вообще нельзя вводить синтаксис. Лисп строится на реинтерпретации весьма обобщеггого синтаксиса S-выражений. Все что ты в нем меняешь — это семантика. А вот в Немерле можно менять и синтаксис. Не на 100, но все же. Например, тот же случай с файлами в немерле превращается в конструкцию using полностью аналогичную C#-овской.


Я вот еще что подумал, на самом деле это хорошо, что нельзя вводить новый синтаксис. Достаточно посмотреть на loop в Common Lisp'е, такой хитрый новый синтаксис там ввели, что иногда хочется застрелиться. Так вот, насколько мне известно, Common Lisp'еры делятся на два лагеря, противники такого вида извращения и любители такого дела.

Я бы себя отнес к противникам введения нового синтаксиса. Тогда у нас получается единый синтаксис, причем очень простой, вида:
(op arg1 arg2 arg3 ...)

где, op — встроенная специальная форма, функция или макрос. Макрос становится не сложнее, чем вызов обычной функции. Что не вредит читабельности кода в целом.

Хотя из всех правил должны быть исключения, например, я двумя руками за такой макрос:
(infix 1 + 2 * 4)

потому как, математические выражения более привычны в таком виде.

Если послушать опытных Лисперов, то их мнение такое, что макросы нужно применять только в том случае, когда уже ни одно средство не помогает, то есть, в исключительных случаях.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[2]: Metaprogramming & higher-order functions dualis
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 22.03.11 06:35
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Обдумай очень простую мысль. Лисп — это первый фунциональный да еще и динамический язык. Он с рождения поддерижвал ФВП. Если бы все можно было бы решить ими, то зачем лиспарям было придумывать макросы?


Тут есть одна забавная история на эту тему:

История Мака: обычная такая история
Когда-то, давным-давно, жила-была компания Lisp программистов. Это было так давно, что в Lisp даже не существовало макросов. Каждый раз все то, что не могло быть определено с помощью функций или сделано с помощью специализированных операторов, должно было быть написано в полном объеме, что было довольно трудоемким делом. К сожалению, программисты в этой компании были хоть и блестящи, но очень ленивы. Нередко в своих программах, когда процесс написания больших объемов кода становился слишком утомителен, они вместо кода писали комментарии, описывающие требуемый в этом месте программы код. К еще большему сожалению, из-за своей лени программисты также ненавидели возвращаться назад и действительно писать код, описанный в комментариях. Вскоре компания получила большую кучу кода, которую никто не мог запустить, потому что он был полон комментариев с описанием того, что еще предстоит написать.

В отчаянии большой босс нанял младшего (junior) программиста, Мака, чьей работой стал поиск комментариев, написание требуемого кода и вставка его в программу на место комментариев. Мак никогда не запускал программы, ведь они не были завершены и поэтому он попросту не мог этого сделать. Но даже если бы они были завершены, Мак не знал, какие данные необходимо подать на их вход. Поэтому он просто писал свой код, основываясь на содержимом комментариев, и посылал его назад создавшему комментарий программисту.

С помощью Мака все программы вскоре были доделаны, и компания заработала уйму денег продавая их: так много денег, что смогла удвоить количество программистов. Но по какой-то причине никто не думал нанимать кого-то в помощь Маку; вскоре он один помогал нескольким дюжинам программистов. Чтобы не тратить все свое время на поиск комментариев в исходном коде, Мак внес небольшие изменения в используемый программистами компилятор. Теперь, если компилятор встречал комментарий, то отсылал его электронной почтой Маку, а затем ждал ответа с замещающим комментарий кодом. К сожалению, даже с этими изменениями Маку было тяжело удовлетворять запросам программистов. Он работал так тщательно, как только мог, но иногда, особенно когда записи не были ясны, он допускал ошибки.

Однако программисты обнаружили, что чем точнее они пишут свои комментарии, тем больше вероятность того, что Мак вернет правильный код. Как-то раз один из программистов, встретив затруднение с описанием в словах нужного кода, включил в один из комментариев программу на Lisp, которая генерировала нужный код. Такой комментарий был удобен Маку: он просто запустил программу и послал результат компилятору.

Следующее новшество появилось, когда программист вставил в самый верх одной из своих программ комментарий, содержащий определение функции и пояснение, гласившее: "Мак, не пиши здесь никакого кода, но сохрани эту функцию на будущее; я собираюсь использовать ее в некоторых своих комментариях." Другие комментарии в этой программе гласили следующее: "Мак, замени этот комментарий на результат выполнения той функции с символами x и y как аргументами."

Этот метод распространился так быстро, что в течение нескольких дней большинство программ стало содержать дюжины комментариев с описанием функций, которые использовались только кодом в других комментариях. Чтобы облегчить Маку различение комментариев, содержащих только определения и не требующих немедленного ответа, программисты отмечали их стандартным предисловием: "Definition for Mac, Read Only" (Определение для Мака, только для чтения). Это (как мы помним, программисты были очень ленивы) быстро сократилось до "DEF. MAC. R/O", а потом до "DEFMACRO".

Очень скоро в комментариях для Мака вообще не осталось английского. Целыми днями он читал и отвечал на электронные письма от компилятора, содержащие DEFMACRO комментарии и вызывал функции, описанные в DEFMACRO. Так как Lisp программы в комментариях осуществляли всю реальную работу, то работа с электронными письмами перестала быть проблемой. У Мака внезапно стало много свободного времени, и он сидел в своем кабинете и грезил о белых песчаных пляжах, чистой голубой океанской воде и напитках с маленькими бумажными зонтиками.

Несколько месяцев спустя программисты осознали что Мака уже довольно давно никто не видел. Придя в его кабинет, они обнаружили, что все покрыто тонким слоем пыли, стол усыпан брошюрами о различных тропических местах, а компьютер выключен. Но компилятор продолжал работать! Как ему это удавалось? Выяснилось, что Мак сделал заключительное изменение в компиляторе: вместо отправки электронного письма с комментарием Маку компилятор теперь сохранял функции, описанные с помощью DEFMACRO комментариев, и запускал при вызове их из других комментариев. Программисты решили, что нет оснований говорить большим боссам, что Мак больше не приходит на работу. Так происходит и по сей день: Мак получает зарплату и время от времени шлет программистам открытки то из одной тропической страны, то из другой.

Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[3]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.03.11 15:04
Оценка:
Здравствуйте, __lambda__, Вы писали:

VD>>Обдумай очень простую мысль. Лисп — это первый фунциональный да еще и динамический язык. Он с рождения поддерижвал ФВП. Если бы все можно было бы решить ими, то зачем лиспарям было придумывать макросы?


___>Тут есть одна забавная история на эту тему:


Спасибо. Я эти притчи читал несколько лет тому назад.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Metaprogramming & higher-order functions dualis
От: maxkar  
Дата: 22.03.11 21:25
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Да, и еще хочу тебя удивить. В Лиспе (лкассическом) нельзя вводить новый синтаксс. То есть вообще нельзя вводить синтаксис. Лисп строится на реинтерпретации весьма обобщеггого синтаксиса S-выражений. Все что ты в нем меняешь — это семантика. А вот в Немерле можно менять и синтаксис. Не на 100, но все же. Например, тот же случай с файлами в немерле превращается в конструкцию using полностью аналогичную C#-овской.


Ну тогда сразу вопрос. А что такое синтаксис? В использованном определении. Потому что в более-менее общепринятом определении "множество допустимых программ" синтаксис в лиспе все же есть. Да и сам лисп считает примерно также:
max@progressor ~
$ cat test.lisp
"aa

max@progressor ~
$ clisp test.lisp
*** - READ: input stream
      #<INPUT BUFFERED FILE-STREAM CHARACTER #P"test.lisp" @2> ends within a
      string

Что-то он ругается на то, что "input stream" не правильный. А не на то, что S-expression неверный. Вот с тем, что "AST", выходящее из reader'а, динамически типизировано, я согласен, но это же не отсутствие синтаксиса (когда буковки переводятся в дерево). Кстати, вот описание этого самого синтаксиса. Более того, как раз на то, как буковки превращаются в S-form можно влиять программно. Это в том же common lisp есть. Например, set-macro-character. Ну например, можно немножко потюнинговать, как читаются числа:
(defun bad-read (str c)
    (do ((chr (read-char str) (read-char str))
             (agg (make-array 5 :fill-pointer 0 :adjustable t :element-type 'character)))
        ((not (digit-char-p chr))
         (unread-char chr str)
         (multiple-value-bind (v x) (parse-integer (reverse agg)) v))
        (vector-push chr agg)))

(set-macro-character #\? #'bad-read) 

(format t "~a" ?321)

Можно также проверить, что до этого (format t "~a" ?321) не работало.
Ну и никто не мешает в set-macro-character подсунуть полноценный парсер DSL. И будет он парсить кастомный синтаксис. Например, xml-литералы. Ну или грамматики парсить. А на выходе все равно будет s-expression. Точнее, какое-то значение. Ведь можно вернуть что-нибудь и пользовательского типа. В контексте вызова пользовательского макроса это может быть даже оправдано. Может быть, можно вычитать и несколько s-expression (несколько значений), я настолько глубоко ридеры не копал.
Re[5]: Metaprogramming & higher-order functions dualis
От: Воронков Василий Россия  
Дата: 22.03.11 21:41
Оценка:
Здравствуйте, FR, Вы писали:

FR>По моему достаточно языка с первоклассными классами, то есть с поддержкой метаклассов, правда все сейчас живые такие языки динамические.


C#?
Re[6]: Metaprogramming & higher-order functions dualis
От: Воронков Василий Россия  
Дата: 22.03.11 21:43
Оценка:
Здравствуйте, VladD2, Вы писали:

FR>>По моему достаточно языка с первоклассными классами, то есть с поддержкой метаклассов, правда все сейчас живые такие языки динамические.

VD>Смешно. Они и могут быть только в динамических языках. Ну разве что еще в гибридных (но я таких не видел).

C# сейчас как раз и есть такой язык. А IDynamicObject — метакласс практически в явном виде.
Re[4]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 23.03.11 08:35
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Код макроса


> (loc, n)

> (loc, n)
> (loc, n)
> (loc, n)

Напрашивается монада.
Re[3]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.03.11 15:46
Оценка:
Здравствуйте, maxkar, Вы писали:

M>Ну тогда сразу вопрос. А что такое синтаксис?


Ответ

M>В использованном определении. Потому что в более-менее общепринятом определении "множество допустимых программ" синтаксис в лиспе все же есть.


Синтаксис — это скорее множество последовательностей символов которое может быть формально признанно программой.
В Лиспе синтаксис — это S-выражения, или иными словами форма записи списка. Посему практически любая последовательность символов заключенная в скобки может быть синтаксически верной программой на Лиспе.

M>Что-то он ругается на то, что "input stream" не правильный. А не на то, что S-expression неверный.


Что-то я не улавливаю в этих словах логики.

M>Кстати, вот описание этого самого синтаксиса.


Ну, вот и почитай его, а за одно подумай как может синтаксис такого мощного языка языка умещаться на одном экране. И почему основную его часть занимает раздел с названием "Syntax of S_expressions".

M>Более того, как раз на то, как буковки превращаются в S-form можно влиять программно. Это в том же common lisp есть.


Это не более чем детали реализации читалок S-выржаний. Мы же говорим о синтаксисе языка.

M>Например, set-macro-character. Ну например, можно немножко потюнинговать, как читаются числа:

M>
M>(defun bad-read (str c)
M>    (do ((chr (read-char str) (read-char str))
M>             (agg (make-array 5 :fill-pointer 0 :adjustable t :element-type 'character)))
M>        ((not (digit-char-p chr))
M>         (unread-char chr str)
M>         (multiple-value-bind (v x) (parse-integer (reverse agg)) v))
M>        (vector-push chr agg)))

M>(set-macro-character #\? #'bad-read) 

M>(format t "~a" ?321)
M>


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

Я не говорю о попытках прилепить синтаксис к лиспам. Их было много, но все они не получили известности.

M>Можно также проверить, что до этого (format t "~a" ?321) не работало.


Да что это все изменит то? Как была польская нотация с морем скобок, так и останется. Другого синтаксиса тут не появилось.

M>Ну и никто не мешает в set-macro-character подсунуть полноценный парсер DSL.


Этак к любому языку можно подсунуть парсер и сказать, что мы получили изменение синтаксиса.

В общем, я даже не хочу обсуждать эту тему. Автор темы утверждал, что обычные макросы вводят новый синтаксис. Я всего лишь сделал замечание, что это не так. Они не вводят синтаксис. Они вводят новую семантику. Синтаксиса в Липе вообще почти нет. Потому на этом языке и не может писать большая часть программистов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.03.11 15:49
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

FR>>>По моему достаточно языка с первоклассными классами, то есть с поддержкой метаклассов, правда все сейчас живые такие языки динамические.

VD>>Смешно. Они и могут быть только в динамических языках. Ну разве что еще в гибридных (но я таких не видел).

ВВ>C# сейчас как раз и есть такой язык. А IDynamicObject — метакласс практически в явном виде.


C# это помесь бульдога с носорогом. К метаклассам он не имеет никакого отношения хотя бы потому, что не позволят менять собственные классы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.03.11 16:12
Оценка:
Здравствуйте, VoidEx, Вы писали:

VD>>Код макроса


>> (loc, n)

>> (loc, n)
>> (loc, n)
>> (loc, n)

VE>Напрашивается монада.


Зачем?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Metaprogramming & higher-order functions dualis
От: Воронков Василий Россия  
Дата: 23.03.11 19:01
Оценка:
Здравствуйте, VladD2, Вы писали:

ВВ>>C# сейчас как раз и есть такой язык. А IDynamicObject — метакласс практически в явном виде.

VD>C# это помесь бульдога с носорогом. К метаклассам он не имеет никакого отношения хотя бы потому, что не позволят менять собственные классы.

Во-первых, это утверждение неверно. Типы менять можно и довольно давно. См. DynamicMethod.

Во-вторых, понятие "класс" в C# и в Питоне — это, что называется, две большие разницы. В Питоне нет системы типов, и класс там — это просто функция-конструктор, заполняющая хэш-таблицу. Код на Питоне, использующий метаклассы, можно переписать на C# с MetaObject практически один-в-один. Не вижу причин не считать это метаклассами, пусть и в динамическом сабсете языка.
Re[4]: Metaprogramming & higher-order functions dualis
От: maxkar  
Дата: 23.03.11 20:03
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Синтаксис — это скорее множество последовательностей символов которое может быть формально признанно программой.


Согласен. По ссылке определение примерно такое же.

VD>В Лиспе синтаксис — это S-выражения, или иными словами форма записи списка. Посему практически любая последовательность символов заключенная в скобки может быть синтаксически верной программой на Лиспе.


Нет. S-выражения — это то, что кормится evaluator'у. "Внутренняя кухня" того, как работает язык. Пользователь же видит то, что кормит читалке. И пишет то, что будет читать его читалка + выполнять среда выполнения. Так что с точки зрения пользователя синтаксис как раз может быть. Что еще более интересно — на этом самом уровне может существовать семантика, которая теряется после перевода в S-form. Это что-то вроде того, как работают обычные макросы, например, определения теста (взять тот же пример из Practical common lisp). На уровне кода абстракция теста существует, сразу после чтения reader'ом запись теста превращается в s-выражения. Но пользователя при использовании в первую очередь интересует начальная запись, а не то, во что она раскрывается после макросов.

Кстати, еще одно уточнение про синтаксис. Положим, следующую программу на C:
int main(int argc, char** argv) {
   int x;
   y = 3;
}

Это неверная программа. Вопрос — является ли она синтаксически верной? Если является, то ошибка в семантике программы или где? Если же не является, то почему же тогда программа на лиспе с подобной проблемой (обращение к несуществующей переменной) называется синтаксически верной?

M>>Что-то он ругается на то, что "input stream" не правильный. А не на то, что S-expression неверный.


VD>Что-то я не улавливаю в этих словах логики.


Пример того, что какой-то синтаксис все же есть.

M>>Кстати, вот описание этого самого синтаксиса.


M>>Более того, как раз на то, как буковки превращаются в S-form можно влиять программно. Это в том же common lisp есть.


VD>Это не более чем детали реализации читалок S-выржаний. Мы же говорим о синтаксисе языка.


Ага. Именно о синтаксисе мы и говорим. См. определения выше. Как раз особенности интерпретации буковок нас и интересуют. Зачем сюда приплетать то, как работает evaluator то? Ну да, он примитивен до безобразия. Особенно по сравнению с msil/java bytecode или тем, что скармливается на вход их кодогенератору. Но на "корректная/некорректная" программа оно влияет слабо.

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

Мне что, в примере нужно было полноценный парсер какого-нибудь С в S-expressions написать? Где-то там в буковках появилась "абстракция" число "задом-наперед". Ну была бы абстракция "c-процедура". Вообще, до тех пор, пока никаких страшных проблем с взаимодействием с другими библиотеками не возникает, мне абсолютно без разницы, на каком этапе потеряется моя абстракция.

VD>Я не говорю о попытках прилепить синтаксис к лиспам. Их было много, но все они не получили известности.

А он таки оказался не очень нужен . Потери на написание S-expressions не очень большие. Плюс в них то как раз можно выразить практически все, что угодно в силу их динамической типизированности. Так что не стоит задачи "как бы впихнуть что-то в модель выполнения языка или другой синтаксис".

M>>Можно также проверить, что до этого (format t "~a" ?321) не работало.


VD>Да что это все изменит то? Как была польская нотация с морем скобок, так и останется. Другого синтаксиса тут не появилось.

Почему не появилось? Ну да, скобок много, полноценный разбор структур я не писал. А вот синтаксис ?321 появился. Буковки раньше такие не являлись корректной программой, а теперь стали. Так что формально именно синтаксис языка мы и изменили. Да, на уровне "среды выполнения" ничего не изменилось. А разве это что-то меняет? Более того, все остальные языки тоже имеют вполне конкретный "исполнитель", который никак не меняется (msil/bytecode/etc...). Наличие промежуточной раскрывалки макросов принципиально ничего не меняет. Ей тоже кормится код в уже фиксированном формате.

M>>Ну и никто не мешает в set-macro-character подсунуть полноценный парсер DSL.


VD>Этак к любому языку можно подсунуть парсер и сказать, что мы получили изменение синтаксиса.


Ну да. А что, нет? Если я кодогенератору паскаля подсуну читалку от C от этого язык не престанет быть Паскалем? Пользователя то в первую очередь интересует то, что кормится как раз читалке. Затем то, что происходит в среде выполнения. Но только в той части, которая видна в выбранном синтаксисе. Что-то может быть доступно, что-то — нет.

VD>В общем, я даже не хочу обсуждать эту тему. Автор темы утверждал, что обычные макросы вводят новый синтаксис. Я всего лишь сделал замечание, что это не так. Они не вводят синтаксис. Они вводят новую семантику. Синтаксиса в Липе вообще почти нет. Потому на этом языке и не может писать большая часть программистов.


Так в широком смысле то он прав. Хотя я ответ на пример с неверным именем переменной в C-программе хочу услышать. Не все S-выражения являются корректной программой. Здесь грань очень тонкая между компилятором и интерпретатором. Вот если смотреть на "целевой результат", то передача всякого мусора в макрос loop будет являться синтаксической ошибкой или семантической? И почему в этом случае код все же не сгенерируется? Более того, как раз таки практически любой макрос фактически определяет новый синтаксис — он определяет какую-то корректную структуру S-выражений. Ну а раз не все S-выражения допускаются, то, видимо, допускаются и не все исходные тексты (пусть даже с well-formed s-expressions).

То, что большая часть писать не может — это другая история. В lisp'е совершенно непривычная большинству программистов "низкоуровневая" модель выполнения. Большинство программистов, насколько я знаю, обучают на примере машины Тьюринга или аналогичной императивной модели. И это самое большинство программистов в целом на уровне этой машины и остается. У них операции на уровне "прочитали значение/записали значение из общей памяти". И абстракции на уровне процедур сводятся не к "семантическому значению процедуры", а к тому "какие же байтики памяти она внутри будет менять". А лисп так читать и понимать нельзя. Там как раз эта низкоуровневая модель "слишком простая" и одновременно "слишком общая". Правильный подход думать в терминах абстракций. Вот есть абстракция loop. В большинстве случаев вообще не важно, макрос это или специальная форма. Это именно абстракция цикла. И то, что в ней внутри используется в качестве параметров в общем случае — тоже "абстракции". Переход на уровень S-expression для понимания — путь в никуда, это опять опускание на уровень среды выполнения. В лиспе как раз слишком легко вводить различные абстракции. И именно поэтому он пугает большинство программистов. В других языках набор "абстракций", с которыми приходится оперировать, конечен (и ограничен). В том же nemerle все в итоге сводится ко вполне фиксированному набору понятий. Даже вышеприведенные макросы xml и PegGrammar в результате все же сводятся к уже существующим абстракциям. В одном случае — LinqExpression, в другом — класс. Да, оно добавляет методы в класс и т.п., но сущность остается "классом". Сущности "грамматика" не появляется. Появляется какой-то класс, отражающий "грамматику", но там новых действий по сравнению с другим "классом" не появляется. В лиспе же запись (peg-grammar "...") ни о чем не говорит. Ну за исключением того, что это S-expression. Но это же не интересно. Интересна семантика. А из семантики это именно "какой-то абстрактный peg-grammar". Все остальное зависит от действий. В контексте (parse-grammar (peg-grammar "...") "...") будет, например, две абстракции. И, вообще говоря, нельзя полагаться на то, что те же parse-grammar и peg-grammar являются макросами или функциями. Они определены для конкретной задачи и именно ее и решают. То, как они это делают, не должно интересовать никого.
Re[6]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 24.03.11 18:01
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, VoidEx, Вы писали:


VD>>>Код макроса


>>> (loc, n)

>>> (loc, n)
>>> (loc, n)
>>> (loc, n)

VE>>Напрашивается монада.


VD>Зачем?


Затем же, зачем макросы, генерики, ФВП. Чтобы не повторять одно и то же в каждой строке.
Re[7]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.03.11 18:06
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Затем же, зачем макросы, генерики, ФВП. Чтобы не повторять одно и то же в каждой строке.


Чтобы избавиться от дублирования (loc, n) ? Проще значение в кортеж поместить. Только это ловля блох.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 24.03.11 18:08
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, VoidEx, Вы писали:


VE>>Затем же, зачем макросы, генерики, ФВП. Чтобы не повторять одно и то же в каждой строке.


VD>Чтобы избавиться от дублирования (loc, n) ? Проще значение в кортеж поместить. Только это ловля блох.


И будешь везде пропихивать этот кортеж? Отличное решение.
Re[9]: Metaprogramming & higher-order functions dualis
От: hardcase Пират http://nemerle.org
Дата: 24.03.11 21:07
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>И будешь везде пропихивать этот кортеж? Отличное решение.


Везде — это в 10 строках?
/* иЗвиНите зА неРовнЫй поЧерК */
Re[9]: Metaprogramming & higher-order functions dualis
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.03.11 22:12
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>И будешь везде пропихивать этот кортеж? Отличное решение.


Куда его пропихивать то? Кода 5 строк.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 25.03.11 07:11
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, VoidEx, Вы писали:


VE>>И будешь везде пропихивать этот кортеж? Отличное решение.


H>Везде — это в 10 строках?


Я бы сказал, не в 10, а в половине строк функции.

Судя по нападкам я начинаю подозревать, что такая элементарная задача не по силам Немерлю с его макросами. Либо посильна, но какой ценой.
Re[11]: Metaprogramming & higher-order functions dualis
От: WolfHound  
Дата: 25.03.11 09:19
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Судя по нападкам я начинаю подозревать, что такая элементарная задача не по силам Немерлю с его макросами. Либо посильна, но какой ценой.

Судя по тому что от тебя не поступило даже псевдокода того как этот код можно сократить в 100500 раз то...
Короче код на хаскеле в студию.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[12]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 25.03.11 10:18
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, VoidEx, Вы писали:


VE>>Судя по нападкам я начинаю подозревать, что такая элементарная задача не по силам Немерлю с его макросами. Либо посильна, но какой ценой.

WH>Судя по тому что от тебя не поступило даже псевдокода того как этот код можно сократить в 100500 раз то...
WH>Короче код на хаскеле в студию.
Думаю, если я его напишу, то отрежу тебе единственный путь к отступлению с гордо поднятой головой "спервадобейся". Не буду лишать тебя этой радости.
Re[13]: Metaprogramming & higher-order functions dualis
От: WolfHound  
Дата: 25.03.11 10:26
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Думаю, если я его напишу, то отрежу тебе единственный путь к отступлению с гордо поднятой головой "спервадобейся". Не буду лишать тебя этой радости.

Ну да пошла демагогия... что слив сразу засчитываем?
Ты заявил что тут нужны монады.
Монады ради монад глупость.
Значит они нужны чтобы сократить код.
Вот и покажи как в данном случае с помощью монады сократить код.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[14]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 25.03.11 10:30
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, VoidEx, Вы писали:


VE>>Думаю, если я его напишу, то отрежу тебе единственный путь к отступлению с гордо поднятой головой "спервадобейся". Не буду лишать тебя этой радости.

WH>Ну да пошла демагогия... что слив сразу засчитываем?
WH>Ты заявил что тут нужны монады.
WH>Монады ради монад глупость.
WH>Значит они нужны чтобы сократить код.
WH>Вот и покажи как в данном случае с помощью монады сократить код.

Я сказал, что напрашиваются монады (подозреваю, что (loc, n) повторяется не только в этом макросе, больно общо выглядит код), и что ими тут можно сократить код. Может, мне ещё коммит сделать? Как правильно говорил Влад, совет можно или проигнорить, или воспользоваться, а в няньки я не нанимался.
Засчитывай слив, скриншот в рамку и на стену.
Re[15]: Metaprogramming & higher-order functions dualis
От: WolfHound  
Дата: 26.03.11 07:56
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Я сказал, что напрашиваются монады (подозреваю, что (loc, n) повторяется не только в этом макросе, больно общо выглядит код),

Код придельно конкретный.

VE>и что ими тут можно сократить код.

Вот и покажи как. Я не вижу куда тут можно монаду воткнуть так чтобы код стал короче.

VE>Может, мне ещё коммит сделать?

Ты хотябы псевдокод напиши.
За то время что ты тут трындишь давно бы эти 10 строк переписал и показал всем как надо.

VE>Как правильно говорил Влад, совет можно или проигнорить, или воспользоваться, а в няньки я не нанимался.

Какой пафос... а все ради того чтобы сделать хорошую мину при плохой игре.
Ибо куда там можно воткнуть монаду ты и сам не знаешь.
А признать боишься.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[16]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 26.03.11 19:20
Оценка:
Здравствуйте, WolfHound, Вы писали:

VE>>Как правильно говорил Влад, совет можно или проигнорить, или воспользоваться, а в няньки я не нанимался.

WH>Какой пафос... а все ради того чтобы сделать хорошую мину при плохой игре.
До тебя мне далеко.
WH>Ибо куда там можно воткнуть монаду ты и сам не знаешь.
О великий пророк.
WH>А признать боишься.
Re[16]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 26.03.11 19:37
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, VoidEx, Вы писали:


VE>>Я сказал, что напрашиваются монады (подозреваю, что (loc, n) повторяется не только в этом макросе, больно общо выглядит код),

WH>Код придельно конкретный.

VE>>и что ими тут можно сократить код.

WH>Вот и покажи как. Я не вижу куда тут можно монаду воткнуть так чтобы код стал короче.

VE>>Может, мне ещё коммит сделать?

WH>Ты хотябы псевдокод напиши.
WH>За то время что ты тут трындишь давно бы эти 10 строк переписал и показал всем как надо.
Хами — переходи на личности — время не теряй — моё жизненное кредо.

Устроит псевдокод или разжевать попросишь?
make r = PExpr.Member e1 `ap` make' r where
    make' (Ref n) = Splicable.Name n
    make' (ToComplete n) = Splicable.HalfId
    make' _ = failMatch
e2 <- msum [
    r ~~> make r
    Call(r, parms) ~~> PExpr.Call `ap` make r `ap` parms
    Indexer(r, parms) ~~> PExpr.Indexer `ap` make r `ap` parms
    otherwise ~~> Message.FatalError "blabla"] expr2
-- ...
Re[17]: Metaprogramming & higher-order functions dualis
От: WolfHound  
Дата: 26.03.11 20:44
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Хами — переходи на личности — время не теряй — моё жизненное кредо.

Я давно заметил что ты только этим и занимаешься.

VE>Устроит псевдокод или разжевать попросишь?

Уже лучше.
Теперь сделай код эквивалентным (а то ты его сократил за счет потери функциональности) и не экономь на именах.
Что такое ~~> ? hoogle молчит. И не ясно в каком месте в АСТ засовывается Location.
Вот тогда и сравним.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[18]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 28.03.11 07:24
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, VoidEx, Вы писали:


VE>>Хами — переходи на личности — время не теряй — моё жизненное кредо.

WH>Я давно заметил что ты только этим и занимаешься.
Не думаю, что ты не понял, кому предназначается эта фраза.
Не я тут искажаю чужие слова, а затем обвиняю в демагогии и засчитываю сливы, как пубертатное школоло.

VE>>Устроит псевдокод или разжевать попросишь?

WH>Уже лучше.
WH>Теперь сделай код эквивалентным (а то ты его сократил за счет потери функциональности) и не экономь на именах.
WH>Что такое ~~> ? hoogle молчит. И не ясно в каком месте в АСТ засовывается Location.
WH>Вот тогда и сравним.

make r = PExpr.Member e1 `ap` make' r where
    make' (Ref n) = Splicable.Name n
    make' (ToComplete n) = Splicable.HalfId
    make' _ = failMatch
e2 <- runExprT $ msum $ map ExprT [
    \r -> make r
    \Call(r, parms) -> PExpr.Call `ap` make r `ap` parms
    \Indexer(r, parms) -> PExpr.Indexer `ap` make r `ap` parms
    \_ -> Message.FatalError "blabla"] expr2


Вполне можно вот так. Location протягивается через монаду. Всё неслабо зависит от того, какие у вас там могут быть Expr, и что у него внутри. Именно поэтому я сказал, что монада "напрашивается", а не "нужна". Но тебе же виднее, что именно я сказал. Я не иду на попятную, но ковырять весь код и потом писать более короткий аналог, чтобы что-то кому-то (а уж тем более тебе) доказать, я не собираюсь.
Re[19]: Metaprogramming & higher-order functions dualis
От: WolfHound  
Дата: 28.03.11 07:57
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Не думаю, что ты не понял, кому предназначается эта фраза.

VE>Не я тут искажаю чужие слова, а затем обвиняю в демагогии и засчитываю сливы, как пубертатное школоло.
Тебя так легко тролить...
А знаешь что самое интересное в этой истории? Ты первый начал.

VE>Вполне можно вот так. Location протягивается через монаду. Всё неслабо зависит от того, какие у вас там могут быть Expr, и что у него внутри. Именно поэтому я сказал, что монада "напрашивается", а не "нужна". Но тебе же виднее, что именно я сказал. Я не иду на попятную, но ковырять весь код и потом писать более короткий аналог, чтобы что-то кому-то (а уж тем более тебе) доказать, я не собираюсь.

Ты именно что юлишь и идешь на попятную.
Ибо тот код сократить практически не реально.
Тем более монадой.
Короче ты как обычно влез в тему, в которой ничего не понимаешь и пытаешься строить из себя великого гуру, которого все должны слушать.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[20]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 28.03.11 08:19
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, VoidEx, Вы писали:


VE>>Не думаю, что ты не понял, кому предназначается эта фраза.

VE>>Не я тут искажаю чужие слова, а затем обвиняю в демагогии и засчитываю сливы, как пубертатное школоло.
WH>Тебя так легко тролить...
Да ну неужели. Тут аж четыре человека возбурлило на мой вброс, а ты так и до сих пор не угомонился.
WH>А знаешь что самое интересное в этой истории? Ты первый начал.

WH>Ты именно что юлишь и идешь на попятную.

WH>Ибо тот код сократить практически не реально.
Если две частные реализации sort короче, чем одна общая, то общая всё равно приоритетнее. Вопрос не в сокращении, а в убирании повторяющегося говна.
Re[21]: Metaprogramming & higher-order functions dualis
От: WolfHound  
Дата: 28.03.11 08:41
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Да ну неужели. Тут аж четыре человека возбурлило на мой вброс, а ты так и до сих пор не угомонился.

Да ты еще и считать не умеешь...
И бурлишь тут только ты. Наезды у тебя в каждом первом сообщении.

VE>Если две частные реализации sort короче, чем одна общая, то общая всё равно приоритетнее.

Причем тут сортировки я вообще не понял.
Раскрой тему.
Это становится забавным.

VE>Вопрос не в сокращении, а в убирании повторяющегося говна.

Если тебе так не нравится (n, loc) то их почти все можно убрать замыканием.
В любом случае нужно сохранять функциональность, а не заниматься сжатием кода с потерями как это делаешь ты.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[22]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 28.03.11 09:06
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, VoidEx, Вы писали:


VE>>Если две частные реализации sort короче, чем одна общая, то общая всё равно приоритетнее.

WH>Причем тут сортировки я вообще не понял.
WH>Раскрой тему.
WH>Это становится забавным.
При том, что повторяющийся код убирают далеко не только за тем, чтобы сократить.

VE>>Вопрос не в сокращении, а в убирании повторяющегося говна.

WH>Если тебе так не нравится (n, loc) то их почти все можно убрать замыканием.
Ну так убери.
WH>В любом случае нужно сохранять функциональность, а не заниматься сжатием кода с потерями как это делаешь ты.
Где там потери у меня?
Re[23]: Metaprogramming & higher-order functions dualis
От: WolfHound  
Дата: 28.03.11 09:58
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>При том, что повторяющийся код убирают далеко не только за тем, чтобы сократить.

А зачем еще? И каким боком тут сортировка?

WH>>Если тебе так не нравится (n, loc) то их почти все можно убрать замыканием.

VE>Ну так убери.
Зачем? Код от этого практически ничего не выиграет.
А политика проекта такова что перед коммитом изменений в компилятор или стандартную библиотеку нужно все тесты прогонять, а это куча времени.

WH>>В любом случае нужно сохранять функциональность, а не заниматься сжатием кода с потерями как это делаешь ты.

VE>Где там потери у меня?
Ну то есть ты не только считать но и читать не умеешь?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[24]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 28.03.11 10:03
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, VoidEx, Вы писали:


VE>>При том, что повторяющийся код убирают далеко не только за тем, чтобы сократить.

WH>А зачем еще? И каким боком тут сортировка?
Я думал на её примере станет понятно, зачем ещё. Но на нет и суда нет.

WH>>>Если тебе так не нравится (n, loc) то их почти все можно убрать замыканием.

VE>>Ну так убери.
WH>Зачем? Код от этого практически ничего не выиграет.
WH>А политика проекта такова что перед коммитом изменений в компилятор или стандартную библиотеку нужно все тесты прогонять, а это куча времени.
Не-не, ты мне тут, псевдокодом убери.

WH>>>В любом случае нужно сохранять функциональность, а не заниматься сжатием кода с потерями как это делаешь ты.

VE>>Где там потери у меня?
WH>Ну то есть ты не только считать но и читать не умеешь?
На языке для глухонемых не умею.
Re[25]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 28.03.11 10:23
Оценка:
Здравствуйте, VoidEx, Вы писали:

Я посмотрел остальные макры, там и правда с location работы мало, но в operators.n частенько встречается ручная работа. Мне вот интересно, там неужто везде такой специфичный код, что надо руками Location протягивать?
Re[25]: Metaprogramming & higher-order functions dualis
От: WolfHound  
Дата: 28.03.11 10:35
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Я думал на её примере станет понятно, зачем ещё. Но на нет и суда нет.

А где пример то? И что словами сказать не можешь?

VE>Не-не, ты мне тут, псевдокодом убери.

Осталось всего два (loc, n)
    def loc = expr2.Location;
    def makeMemberAccess(n) { PExpr.Member(loc,  <[ e1 ]>, Splicable.Name(loc, n)) }
    def makeComplation  (n) { PExpr.Member(loc,  <[ e1 ]>, Splicable.HalfId(loc, n)) }
    def e2 = 
      match (expr2)
      {
        | Ref(n)                    => makeMemberAccess(n)
        | Call(Ref(n), parms)       => PExpr.Call(loc, makeMemberAccess(n), parms)
        | Indexer(Ref(n), parms)    => PExpr.Indexer(loc, makeMemberAccess(n), parms)
        | ToComplete(n)             => makeComplation(n)
        | Call(ToComplete(n), _)    => makeComplation(n)
        | Indexer(ToComplete(n), _) => makeMemberAccess(n)
        | _ => Message.FatalError(expr2.Location, $"The expression of this ($(expr2.GetType())) type not supported with operator '?.'");
      };
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[26]: Metaprogramming & higher-order functions dualis
От: WolfHound  
Дата: 28.03.11 10:35
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Я посмотрел остальные макры, там и правда с location работы мало, но в operators.n частенько встречается ручная работа. Мне вот интересно, там неужто везде такой специфичный код, что надо руками Location протягивать?

Почти все Location используются в сообщениях об ошибках.
И только в двух операторах Location используется для чегото еще.
И таки да. Работа с Location всегда очень специфична.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[27]: Metaprogramming & higher-order functions dualis
От: VoidEx  
Дата: 28.03.11 10:42
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, VoidEx, Вы писали:


VE>>Я посмотрел остальные макры, там и правда с location работы мало, но в operators.n частенько встречается ручная работа. Мне вот интересно, там неужто везде такой специфичный код, что надо руками Location протягивать?

WH>Почти все Location используются в сообщениях об ошибках.
WH>И только в двух операторах Location используется для чегото еще.
WH>И таки да. Работа с Location всегда очень специфична.

В таком случае беру слова обратно. Мне поначалу показалось, что location'ы как-то комбинируются.
Re[24]: Metaprogramming & higher-order functions dualis
От: __lambda__ Россия http://zen-hacker.blogspot.com/
Дата: 28.03.11 11:27
Оценка:
Здравствуйте, WolfHound, Вы писали:

VE>>При том, что повторяющийся код убирают далеко не только за тем, чтобы сократить.

WH>А зачем еще? И каким боком тут сортировка?

Хотя бы для того случая, когда мы исправили ошибку в одном месте, но забыли ее исправить в тех местах, где этот код повторяется. Это же азы. Суть не в том, чтобы написать как можно короче. Самый короткий код, не всегда самый лучший, я лучше предпочту более длинный, но за то более понятный код.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.