Здравствуйте, metaprogrammer, Вы писали: M> Тормоза при CPS берутся от расходов на замыкания, от черзмерного количества вызовов и от мелкого размера каждой функции, что отрубает все возможности для оптимизации.
Тут не могу прокомментировать — не знаю. А чем вредны мелкие функции? Малая длина "последовательного" кода и частые безусловные переходы как-то влияют?
M>Чтоб CPS-ный код не тормозил — это уж очень специализированная VM нужна.
Хм, а не дашь ссылочек на более оптимальный способ сделать call/cc? Любопытно.
Здравствуйте, Mr.Cat, Вы писали:
MC>Даже если используются более-менее умные cps-трансформеры? Наивное преобразование — да, плодит замыкания, но про борьбу с этим чуть ли не докторские пишут.
Да даже самые умные плодят замыкания. Требование "каждый вызов — хвостовой" мешает любым возможным оптимизациям. Можно не плодить ненужные административные лямбды, но как минимум по лямбде на каждый вызов получится всё равно.
Здравствуйте, Mr.Cat, Вы писали:
MC>А что ее просить-то? Вон она, psyntax называется (точнее — это имплементация большого куска r6rs). Что-то около 4000 строк кода, кажется.
Это из бывшего SRFI? Там не только syntax-case, там много всякой шелухи.
M>> f в рантайме вызывается. MC>Я давал ссылку на пример, работающий в chicken scheme и где трансформер юзает функции из того же файла. Принципиальных препятствий этому нет — только искусственное ограничение.
В chicken сработает, в plt — уже не обязательно. Стандарт не оговаривает окружение, доступное из трансформеров.
Здравствуйте, Mr.Cat, Вы писали:
M>> Тормоза при CPS берутся от расходов на замыкания, от черзмерного количества вызовов и от мелкого размера каждой функции, что отрубает все возможности для оптимизации. MC>Тут не могу прокомментировать — не знаю. А чем вредны мелкие функции?
У JIT очень мало времени на оптимизации. Так что ничего умного и сложного он делать не может. А при хвостовых вызовах не может даже инлайнить (он и так это не очень охотно делает). Более крупные методы оптимизируются лучше.
MC>Хм, а не дашь ссылочек на более оптимальный способ сделать call/cc? Любопытно.
Да даже знаменитый 90 minutes scheme compiler даёт более-менее эффективное решение. Тоже CPS, причём наивный — но при трансляции в Си всё это намного дешевле, чем в .NET.
Здравствуйте, metaprogrammer, Вы писали: M> Это из бывшего SRFI? Там не только syntax-case, там много всякой шелухи.
Наверное. Там еще модули как минимум. Но без модулей гигиена уже не та.
M>>> f в рантайме вызывается. M> В chicken сработает, в plt — уже не обязательно. Стандарт не оговаривает окружение, доступное из трансформеров.
Угу, что в r6rs, что в plt начинаются пласки, когда появляется много стадий выполнения (больше, чем 2).
Здравствуйте, metaprogrammer, Вы писали: M> Да даже знаменитый 90 minutes scheme compiler даёт более-менее эффективное решение. Тоже CPS, причём наивный — но при трансляции в Си всё это намного дешевле, чем в .NET.
Его точно так же можно транслировать в дотнет. Дотнет загнется от большого количества "джампов"?
Здравствуйте, Mr.Cat, Вы писали:
MC>Наверное. Там еще модули как минимум. Но без модулей гигиена уже не та.
Модули с полноценным метапрограммированием вообще хреново сочетаются.
MC>Угу, что в r6rs, что в plt начинаются пласки, когда появляется много стадий выполнения (больше, чем 2).
Именно. Стандарт хоть модули и описал, но оставил много простора для отсебятины.
Здравствуйте, metaprogrammer, Вы писали:
M> Я использую метапрограммирование гораздо в больших масштабах, чем это обычно делается всеми другими в коде на Лиспе или Схеме. И ни разу за всю мою практику я не сталкивался с ошибками, которые должна предотвращать гигиена. Вообще ни разу. А вот ограничения гигиены мне бы мешали на каждом шагу.
А я за свою практику сталкивался, да и вообще, человек я рассеянный и глупый, мне нужно, чтобы мой инструмент не давал мне возможности делать глупые и трудноуловимые ошибки. Пишешь себе макрос, отлаживаешь, все вроде бы работает отличненько, начинаешь его юзать везде, где надо и тут начинается веселье, маловнятные ошибки, макрос отлажен, работает 100%, претензий к нему никаких. И тут опачки, протечка абстракции в макросе в виде неэкранированной генсимом внутренней переменной.
Конечно, этого довольно легко избежать, если выработать в себе ряд правил и всегда их придерживаться.
Lisp is not dead. It’s just the URL that has changed: http://clojure.org
Здравствуйте, metaprogrammer, Вы писали:
M> Нормальная она, медленнее обычных вызовов процентов на 20 в самом худшем случае. Проблема не в этом, а в оверхеде на реализации замыканий, которые плодятся при CPS. M> В моно, кстати, не на всех платформах .tail работает.
Да, отстал я от жизни видимо, надо будет освежить свои знания.
Lisp is not dead. It’s just the URL that has changed: http://clojure.org
Здравствуйте, yumi, Вы писали:
Y>А я за свою практику сталкивался,
Научи!
Y> да и вообще, человек я рассеянный и глупый, мне нужно, чтобы мой инструмент не давал мне возможности делать глупые и трудноуловимые ошибки.
1. Use Haskell
2. Проблема не в инструменте, а в методологии. При правильном подходе никаких проблем с именами быть не может и не должно.
Y> Пишешь себе макрос, отлаживаешь, все вроде бы работает отличненько, начинаешь его юзать везде, где надо и тут начинается веселье, маловнятные ошибки, макрос отлажен, работает 100%, претензий к нему никаких. И тут опачки, протечка абстракции в макросе в виде неэкранированной генсимом внутренней переменной.
Ради такой фигни, как собственные биндинги, и городить целую гигиену? Перанальное решение.
Y> Конечно, этого довольно легко избежать, если выработать в себе ряд правил и всегда их придерживаться.
Именно. Без них и с гигиеной код будет нечитабельным уродством.
Здравствуйте, Аноним, Вы писали:
А>Я тебе сразу говорю, что задачи сильно объемные, чтоб решать их только для того, чтобы ПОПЫТАТЬСЯ чего то доказать тупому общелисповому троллю (хотя весь опыт, накопленный человечеством, говорит, что троллю ничего доказать нельзя — его можно только контртроллить).
Здравствуйте, metaprogrammer, Вы писали:
M> 1. Use Haskell
But sometimes I do...
M> 2. Проблема не в инструменте, а в методологии. При правильном подходе никаких проблем с именами быть не может и не должно.
Вот об этом я тебе и говорил ниже, но до выработки этой методологии нужно еще дожить, и особенно это актуально для маленького учебного языка вроде Схемы.
M> Ради такой фигни, как собственные биндинги, и городить целую гигиену? Перанальное решение.
Здравствуйте, yumi, Вы писали:
Y>Вот об этом я тебе и говорил ниже, но до выработки этой методологии нужно еще дожить, и особенно это актуально для маленького учебного языка вроде Схемы.
Я уже ранее писал, что в учебном языке никакими defmacro даже вонять не должно. Это убойный инструмент для профессионалов.
Y>Ну можно конечно примерно как-то так,
Так и делается.
Y>Но проблема все равно остается, можно забыть использовать with-gensym.
Много чего забыть можно.
Проблема в том, что при многоуровневом метапрограммировании запаришься отслеживать, кто и где вводит новые имена. Потому и проще везде использовать gensym, и не надеяться на гигиену.
M>> Именно. Без них и с гигиеной код будет нечитабельным уродством.
Y>О да, а куча (let ((variable-name (gensym)) ... в коде макроса добавляют читабельности...
Здравствуйте, metaprogrammer, Вы писали:
M> Проблема в том, что при многоуровневом метапрограммировании запаришься отслеживать, кто и где вводит новые имена. Потому и проще везде использовать gensym, и не надеяться на гигиену.
Я может плохо гигиену понимаю (да, на Схеме я почти не писал), но мне всегда казалось что именно для этого и нужна гигиена, чтобы не париться и не отслеживать кто и где вводит новые имена и что гигиена это грубо говоря автоматическое использование gensym везде где можно
Lisp is not dead. It’s just the URL that has changed: http://clojure.org
Здравствуйте, yumi, Вы писали:
Y>Я может плохо гигиену понимаю (да, на Схеме я почти не писал), но мне всегда казалось что именно для этого и нужна гигиена, чтобы не париться и не отслеживать кто и где вводит новые имена и что гигиена это грубо говоря автоматическое использование gensym везде где можно
В том и дело, что тогда надо париться и отслеживать, где наоборот переименовывать нельзя (и это более частый случай, кстати). А поскольку семантика у гигиены весьма сложна, то ошибиться на этом пути намного проще, чем при ручной раздаче имён.
В качестве примера задачи, где введённые при раскрытии макры биндинги нельзя переименовывать — любой pattern matching.
Здравствуйте, metaprogrammer, Вы писали:
M> В том и дело, что тогда надо париться и отслеживать, где наоборот переименовывать нельзя (и это более частый случай, кстати). А поскольку семантика у гигиены весьма сложна, то ошибиться на этом пути намного проще, чем при ручной раздаче имён.
А, все, я понял. Да, ты прав.
Lisp is not dead. It’s just the URL that has changed: http://clojure.org
Здравствуйте, metaprogrammer, Вы писали: MC>>много стадий выполнения (больше, чем 2).
Имел в виду три, конечно: expand, компиляция и выполнение — это все можно в r6rs в 1 модуле уместить. Больше вроде не влазит.
M> Именно. Стандарт хоть модули и описал, но оставил много простора для отсебятины.
Не обратил внимание, где там отсебятина. В одном модуле экспортишь, в другом импортишь for expand.
Здравствуйте, metaprogrammer, Вы писали: M> Один метод с большим селектом — не загнётся, очень даже эффективно получается. Но динамически такой код генерить уже нельзя.
Почему нельзя динамически?