Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>ты сказал только для того, чтобы показать что Python может вызывать быструю библиотеку на C/C++/Fortran? Круто
Питон всегда вызывает нативный код, в 100% случаях. После этого можешь выдать объяснение почему же многие классы приложений уже перестали писать на С++, хотя, казалось бы, этот С++ даст вагон перформанса.
В частности это справедливо для WoT и Eve. Нет там никакой специфики, всё можно на С++ оформить.
Но вот известно, что плюсовые аналоги тупо не взлетели.
EP>И доступ к памяти, нарезку по кэшам, кластеризацию, векторизацию, comiple-time полиморфизм, распределение по потокам, за-оптимизируют? Чудеса! EP>Пример покажи.
Пример самый простой — плюсовый код не взлетел, зато взлетел Эрланг, с чего собтсвенно и началась история Эрланга.
EP>Дальше-то что? Чистый ФП код внезапно станет оптимальным для каждого из ядер?
Объясняю еще раз — эффективность работы одного ядра очень слабо коррелирует с эффективностью всей распределенной сети.
Если отбросить случаи когда задача легко дробится на сколь угодно большое количесво параллельных кусочков, то для С++ пространства не так и много.
Re[44]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
I>>Я пока не вижу никакого внятного кода, есть код добавления одного мембера. Надо полагать я должен додумать весь недостающий код ,что бы угадать твои мысли ?
EP>Код чего? Как класс Foo может использоваться в разных местах? Хотя бы: EP>
EP>class Bar
...
EP>
Я не вижу в твоём коде никакого использования ресурсов, даже косвенного. Покажи внятный код или будем считать, что это настолько сложный случай, что тебе не под силу.
Re[38]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
_>Запретить нельзя. Но никто и не заставляет использовать такое в своём коде. Т.е. да, работая на C++, надо понимать что ты делаешь. В отличие от языков специально заточенных под слабых программистов, которые ограничивают их. Но если ты понимаешь как как правильно себя ограничивать, то дальше C++ будет контролировать корректность всего сам.
Если я понимаю, как правильно себя ограничивать, то мне незачем контроль со стороны компилятора. А если я рассеян и/или необучен особенностям конкретной библиотеки, то С++ спокойно даст мне выстрелить себе в ногу.
_>Вообще то, насколько я помню, они потом отказались от всего этого и вернулись к обычному классическому коду, написанному другой компанией. Именно благодаря этому Эрланг и попал в open source.
Вот про это я уже не в курсе. Можно пруфлинк?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[56]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали: _>Это цена за уникальные возможности. ) На мой взгляд незначительная, т.к. мы всегда можем добавить к библиотеке тестовую программку (не в смысле классических полноценных тестов, а просто один обычный сценарий использования) и получить от компилятора полный отчёт о всех проблемах типизации.
Что-то мне подсказывает, что нет, не получим мы от компилятора "полный отчёт о всех проблемах типизации". Точнее, что "тестовая программка", которую надо добавить к библиотеке, запросто окажется по размеру больше самой библиотеки — если мы хотим проверить все аспекты типизации.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[38]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>В языке нет, но при необходимости можно сделать внешний верификатор который запретит "плохие" конструкции в тех или иных модулях. То есть это скорее инфраструктурный вопрос.
Вы всеръёз сейчас предлагаете воспроизвести весь фронт-енд компилятора С++ во внешнем верификаторе, и называете это "инфраструктурным вопросом"? А что тогда останавливает вас от банального внесения логики этого "верификатора" прямо в язык?
EP>Другой вопрос насколько это необходимо. В том же Node.js можно точно также отстрелить себе ногу. Да и вообще, как только у нас есть while или аналог — то "можно делать плохие вещи".
Лично я никогда не позиционировал Node.js как панацею надёжности. И далеко не всякий аналог while даёт нам возможность "делать плохие вещи".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[39]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Sinclair, Вы писали:
S>Если я понимаю, как правильно себя ограничивать, то мне незачем контроль со стороны компилятора.
Очень даже есть зачем. Не стоит путать ошибочный общий стиль и какие-то мелкие местные огрехи — их компилятор с удовольствием выявит.
S>А если я рассеян и/или необучен особенностям конкретной библиотеки, то С++ спокойно даст мне выстрелить себе в ногу.
Вот как раз то, что по рассеянности делается, компилятор будет хорошо отлавливать. Ну а с применением плохого стиля (например типа использования вышеупомянутого char* вместо string) и последующими ошибками из-за него, компилятор действительно ничего не может сделать.
Вообще говоря, C++ сейчас по сути включает в себя и весьма безопасное подмножество и весьма опасное. Причём в отличие от C# они не разделяются каким-то ключевым словом, собственно нет даже чёткой границы по набору конструкций языка. Но любой C++ профессионал прекрасно осознаёт это разделение и не будет использовать опасные вещи без критической необходимости.
S>Вот про это я уже не в курсе. Можно пруфлинк?
Например здесь http://www.erlang-factory.com/upload/presentations/416/MikeWilliams.pdf есть хорошее описание всей истории и кстати частично самого языка. ) И там видно, что вопреки мифам, Erlang разрабатывался как замена некого хитрого внутреннего языка (PLEX), а не C++. Им удалось реализовать один проект (с 1996 по 1998), который получился весьма не плохим. Но при этом всё равно в 1998-ом Erlang был запрещён к использованию в Ericsson — там решили сосредоточиться на работе с индустриальными языками и кажется как раз с C++. )))
Re[57]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Sinclair, Вы писали:
S>Что-то мне подсказывает, что нет, не получим мы от компилятора "полный отчёт о всех проблемах типизации". Точнее, что "тестовая программка", которую надо добавить к библиотеке, запросто окажется по размеру больше самой библиотеки — если мы хотим проверить все аспекты типизации.
Неправильно подсказывает. ) Автор шаблона прекрасно знает под какие типы он создаётся. Соответственно реализуем в тестовой программке один новый тип с минимальным набором требуемых от него свойств. И дальше просто инстанцируем наш шаблон с ним и всё. Если код собирается, то значит будет корректно работать со всеми соответствующими типами — можно приступать уже к функциональному тестированию (как для не обобщённого кода). А если не собирается, то компилятор подробно укажет, что мы не правильно написали в нашем шаблоне.
Re[39]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Sinclair, Вы писали:
EP>>В языке нет, но при необходимости можно сделать внешний верификатор который запретит "плохие" конструкции в тех или иных модулях. То есть это скорее инфраструктурный вопрос. S>Вы всеръёз сейчас предлагаете воспроизвести весь фронт-енд компилятора С++ во внешнем верификаторе, и называете это "инфраструктурным вопросом"?
Воспроизводить фронт-енд необязательно — есть готовые, типа Clang. У него есть достаточно простое API для нахождения тех или иных конструкций: AST Matcher. Например:
#include"clang/ASTMatchers/ASTMatchers.h"#include"clang/ASTMatchers/ASTMatchFinder.h"using namespace clang;
using namespace clang::ast_matchers;
StatementMatcher LoopMatcher =
forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl(
hasInitializer(integerLiteral(equals(0)))))))).bind("forLoop");
class LoopPrinter : public MatchFinder::MatchCallback {
public :
virtual void run(const MatchFinder::MatchResult &Result) {
if (const ForStmt *FS = Result.Nodes.getNodeAs<clang::ForStmt>("forLoop"))
FS->dump();
}
};
int main(int argc, const char **argv) {
CommonOptionsParser OptionsParser(argc, argv);
ClangTool Tool(OptionsParser.getCompilations(),
OptionsParser.getSourcePathList());
LoopPrinter Printer;
MatchFinder Finder;
Finder.addMatcher(LoopMatcher, &Printer);
return Tool.run(newFrontendActionFactory(&Finder));
}
S>А что тогда останавливает вас от банального внесения логики этого "верификатора" прямо в язык?
1. Добавление верификатора поломает backward compatability.
2. Для разных целей нужны разные средства — кому-то нужен один верификатор, кому-то другой.
EP>>Другой вопрос насколько это необходимо. В том же Node.js можно точно также отстрелить себе ногу. Да и вообще, как только у нас есть while или аналог — то "можно делать плохие вещи". S>Лично я никогда не позиционировал Node.js как панацею надёжности.
Ну да — так там её просто нет, но тем не менее это не мешает его использовать.
S>И далеко не всякий аналог while даёт нам возможность "делать плохие вещи".
Если нет возможности сделать вечный цикл — то это не аналог while.
Re[38]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
_>Запретить нельзя. Но никто и не заставляет использовать такое в своём коде. Т.е. да, работая на C++, надо понимать что ты делаешь. В отличие от языков специально заточенных под слабых программистов, которые ограничивают их. Но если ты понимаешь как как правильно себя ограничивать, то дальше C++ будет контролировать корректность всего сам.
То есть, ты хочешь делегировать компилятору контроль всего подряд ? Зачем же тогда понимать что ты делаешь ? И зачем тебе такой контролёр, если ты сам понимаешь, как надо себя контролировать ?
По моему ты боишься сказать простую вещь — С++ ничего не контролирует, то есть, вообще. У тебя полностью ручной контроль и компиялтор сводит к минимуму твои трудозатраты. Правда этот минимум кактой то странный — что бы внятно работать с ресурсами, надо нагородить вагон шаблонов.
Ну или взять такое чудовщие как Boost и несколько лет осваивать его. Итого, если у С++ разработчика менее 5 лет опыта и заявлено свободное владение stl и boost, то гарантировано никаких других скилов не будет, можно даже не искать.
Если ты не согласен, то почему ты не пишешь на ассемблере ? Вот в ём точно надо понимать что ты делаешь, надо понимать как правильно себя ограничивать и тд и тд.
Re[40]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
S>>А если я рассеян и/или необучен особенностям конкретной библиотеки, то С++ спокойно даст мне выстрелить себе в ногу.
_>Вот как раз то, что по рассеянности делается, компилятор будет хорошо отлавливать. Ну а с применением плохого стиля (например типа использования вышеупомянутого char* вместо string) и последующими ошибками из-за него, компилятор действительно ничего не может сделать.
Практика показывает, что хороший стиль вырабатывается годами. По моему разумению, стиль, соглашения всех сортов люди начинают понимать где то после 10 лет опыта. Проблема в том, что к этим 10 года подавляющее большинство уходит в менеджмент, собственный бизнес или вообще в другую область.
_>Вообще говоря, C++ сейчас по сути включает в себя и весьма безопасное подмножество и весьма опасное. Причём в отличие от C# они не разделяются каким-то ключевым словом, собственно нет даже чёткой границы по набору конструкций языка. Но любой C++ профессионал прекрасно осознаёт это разделение и не будет использовать опасные вещи без критической необходимости.
Тоже самое можно и про ассемблер сказать — любой профессионал на ассемблере глупостей не делает.
Ну вот скажем, у меня бывало так — набираю код на асме около недели, эдакий жосцкий кодинг 8 часов в день и 5 дней подряд, в конце недели запускаю, и все не только компилируется, но и работает без крешей и подвисаний.
Личный рекорд — один месяц такого кодинга без промежуточных компиляний и тд и тд. При чем софтина запускалась в прошивке одной железяки для телефонных станций.
Вопрос — ты можешь повторить такое на С++ ?
_>Например здесь http://www.erlang-factory.com/upload/presentations/416/MikeWilliams.pdf есть хорошее описание всей истории и кстати частично самого языка. ) И там видно, что вопреки мифам, Erlang разрабатывался как замена некого хитрого внутреннего языка (PLEX), а не C++. Им удалось реализовать один проект (с 1996 по 1998), который получился весьма не плохим. Но при этом всё равно в 1998-ом Erlang был запрещён к использованию в Ericsson — там решили сосредоточиться на работе с индустриальными языками и кажется как раз с C++. )))
"– Frightened of using little known programming language"
То есть, политическое решение, никакого отношения к качеству софта не имело.
Re[58]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, alex_public, Вы писали:
S>>Что-то мне подсказывает, что нет, не получим мы от компилятора "полный отчёт о всех проблемах типизации". Точнее, что "тестовая программка", которую надо добавить к библиотеке, запросто окажется по размеру больше самой библиотеки — если мы хотим проверить все аспекты типизации.
_>Неправильно подсказывает. ) Автор шаблона прекрасно знает под какие типы он создаётся. Соответственно реализуем в тестовой программке один новый тип с минимальным набором требуемых от него свойств. И дальше просто инстанцируем наш шаблон с ним и всё. Если код собирается, то значит будет корректно работать со всеми соответствующими типами — можно приступать уже к функциональному тестированию (как для не обобщённого кода). А если не собирается, то компилятор подробно укажет, что мы не правильно написали в нашем шаблоне.
А как мне узнать, как правильно писать свой тип, что бы правильно заюзать вон тот шаблон ? Опаньки ! С учетом того, что мета-информация динамически типизирована, это превращается в небольшой квест.
Re[40]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>В языке нет, но при необходимости можно сделать внешний верификатор который запретит "плохие" конструкции в тех или иных модулях. То есть это скорее инфраструктурный вопрос. S>>Вы всеръёз сейчас предлагаете воспроизвести весь фронт-енд компилятора С++ во внешнем верификаторе, и называете это "инфраструктурным вопросом"?
EP>Воспроизводить фронт-енд необязательно — есть готовые, типа Clang. У него есть достаточно простое API для нахождения тех или иных конструкций: AST Matcher.
Это какая то плохая реализация паттерн-матчинга в виде библиотеки.
Такое ощущение, что в этой либе сэмулировали Лисп на С
Здравствуйте, Ikemefula, Вы писали:
I>Практика показывает, что хороший стиль вырабатывается годами. По моему разумению, стиль, соглашения всех сортов люди начинают понимать где то после 10 лет опыта. Проблема в том, что к этим 10 года подавляющее большинство уходит в менеджмент, собственный бизнес или вообще в другую область.
Достаточно лидера проекта с правильным стилем, а остальное можно обеспечить с помощью административных стилевых гайдов. Вот тот же Гугл так делает и ещё даже выкладывает свои варианты для публичного использования.
I>Ну вот скажем, у меня бывало так — набираю код на асме около недели, эдакий жосцкий кодинг 8 часов в день и 5 дней подряд, в конце недели запускаю, и все не только компилируется, но и работает без крешей и подвисаний. I>Личный рекорд — один месяц такого кодинга без промежуточных компиляний и тд и тд. При чем софтина запускалась в прошивке одной железяки для телефонных станций.
Сильно. Правда не очень пойму смысл кодинга без компиляции. )
I>Вопрос — ты можешь повторить такое на С++ ?
Не пробовал такого. )))
I>"– Frightened of using little known programming language"
I>То есть, политическое решение, никакого отношения к качеству софта не имело.
Только благодаря этому Эрланг и стал open source, так что его фанаты должны быть благодарны этому решению. )))
И это скорее не политическое решение, а экономическое и возможно вполне оправданное... )
Re[59]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Ikemefula, Вы писали:
I>А как мне узнать, как правильно писать свой тип, что бы правильно заюзать вон тот шаблон ? Опаньки ! С учетом того, что мета-информация динамически типизирована, это превращается в небольшой квест.
Ты про использование уже готовой библиотеки? А тут то в чём проблема? Подставляешь свой тип в шаблон и если скомпилировалось, то значит всё будет работать. А если нет, то компилятор обязательно укажет, определения какой операции не хватает у твоего типа.
Re[30]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Никакого монадического кода там не было, если конечно не считать тривиальную монаду.
там не Identity, а Continuation монада (наскольк вообще можно говоритьо монадах в бестиповом языке).
EP>Там не обработка пустого значения — а возвращение (причём возвращать пустое значение не обязательно). Это просто void. Я добавил if чтобы продемонстрировать что это именно монада, а не АФ.
Да про if-то понятно, дело в (). Ну, представьте, что это на типизированном языке написано — какой у нее возвращаемый тип?
EP>Подробнее. В примере Scheme — никакой ленивости нет, но раннее завершение у maybe — есть.
Я на этот вопрос отвечаю прямо в посте на который вы отвечаете.
EP>Приведите тогда пример немонадического кода на Scheme.
Затрудняюсь. Я вообще не составил для себя твердого представления, что можно считать (не)монадическим кодом в бестиповых языках. (В принципе, о монадах в языках без * -> * кайндов мы говорим, может и тут что-то можно придумать).
EP>Ленивость позволяет не вычислять ненужное в тех случаях, когда функция/алгоритм описаны с ненужными вычислениями.
Ну, вроде бы причина понятна, когда мы комбинируем функции, то часто описываем как раз такой вот код с ненужными вычислениями. И пока мы вычисляем что-то лишнее по сравнению с сфьюженой вручную версией — подход "комбинирование комбинаторов" всегда будет ущербным по сравнению с подходом "пишем рекурсивную лапшу". А это полноценному ФП сильно не способствует.
EP>Какое-то засилье ненужных вычислений в ФП, из-за которого ленивость необходима как пища, продемонстрировано не было.
Довольно странно сейчас спрашивать подтверждение тому, что вы сами же и заметили и разговор о чем начали здесь
foldl (+) 0 a (обсуждаемый выше) для [Maybe a] будет неэффективным
EP>Более того, судя по Q&A на stackoverflow, когда нужна скорость — от этой ленивости бегут, точно также как и от GC.
Это, мягко говоря, сильное упрощение проблемы. Во многих случаях как раз ленивость и GC скорость и обеспечивают. Особенно это касается именно высокоуровневого и идиоматичного кода.
EP>Непрактичность ленивости? Комбинирование обязательно влечёт за собой ленивость?
С.м. выше начиная с "Ну, вроде бы причина понятна, когда мы комбинируем функции, то часто..."
EP>Мы же вроде обсуждали монадический код?
Вы же сами перешли на тему обеспечения производительности "комбинаторного" кода. Но темы, конечно, пересекающиеся.
EP>С этим я не спорю. Я просто показал, как в языках с call/cc обычный код легко превращается в монадичный.
Это скорее демонстрация того, что монада Cont[inuation] может служить функциональной заменой для многих монад.
Проблема превращения "обычного" кода в монадический, вообще принципиально сложная. Без указания мест где нужны >>= это не сделать. Вашем коде они вручную помечены. Вот сделать из монадического обычный гораздо проще — для этого Identity монады достаточно.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[41]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Ikemefula, Вы писали:
EP>>Воспроизводить фронт-енд необязательно — есть готовые, типа Clang. У него есть достаточно простое API для нахождения тех или иных конструкций: AST Matcher. I>Это какая то плохая реализация паттерн-матчинга в виде библиотеки.
Своё дело она выполняет отлично — позволяет находить нужные куски AST, и трансформировать их (в обсуждаемом контексте трансформация не нужна).
Причём качество "понимания" C++ у неё на высоте — это же Clang, один из лучших компиляторов C++.
I>Такое ощущение, что в этой либе сэмулировали Лисп на С I>
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Опять 25. Почему они не работающие? Они работают даже для ресурсов в отличии от.
Потом, что доступность не гарантируют. И для дефицитных ресурсов доступность — это как раз то, чем можно пожертвовать ради закрытия по завершению использования.
EP>На C++ есть всякие DSL библиотеки, позволяющие писать высокоуровневый, который отлично мэппятся в железо. Например Eigen может во время компиляции выбрать оптимальный путь вычисления матричного выражения, и автоматически векторизовать.
Это пример куда лучше, но, тем не менее, числодробление не особенно высокоуровнево.
EP>Опять-таки высокоуровневый != огромное penalty.
Это, конечно, верно. Однако подход высокоуровневого языка заключается в том, чтоб дать широкий набор инструментов, в том числе и таких, где penalty неизбежно, однако постараться минимизировать это "огромное penalty". Ну а подход "вот тут мы можем как-то обойтись без огромного penalty, значит это у нас будет — вот это — нет." — это подход низкоуровневого языка.
EP>В большинстве кода не то что shared_ptr нет, а даже unique_ptr.
В большинстве низкоуровневого кода — да, в большинстве идиоматического ФП-кода — нет.
EP>Где вычисляется то что ненужно?
В примере "монадизации" на D, например.
EP>Выводы на основе ложных утверждений. Далеко не все абстракции дорогие.
Но многие абстракции, востребованные для написания ФП кода как раз дорогие.
K>>Поэтому никакого высокоуровневого кода и нет — есть только продвинутый интерфейс для двигания указателей. А поддержка высокоуровневых инструментов ограничивается заявлениями о их ненужности. EP>См. Eigen.
Смотрим. То, что не использовано для написания Eigen — не нужно?
EP>Да — это именно то решение, которое вы описали для UFP с ресурсами: "ненужно, поэтому запретить".
EP>1. Какую abstraction penalty вносит указатель сам по себе?
Указатель — это абстракция "плоская память произвольного доступа", если мы не "проделаем в ней дыру" и не станем учитывать иерархию памяти и прочее, от чего она нас вроде бы должна абстрагировать — мы будем биться об стену памяти, например. Вот такая вот penalty.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[32]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Встроенная абстракция языка, которая как вы говорите является "пищей ФП" и которая судя по всему используется повсеместно, даже в hello world, вводит меж-поточную синхронизацию (относительная цена которой с каждым годом только возрастает) — это и называется "на ровном месте".
Ну так ленивость предоставляет возможность изменять по месту. Причем в многопоточном случае дешевле (в чистом языке) о чем в статье и написано. Если вы будете переписывать хвост списка, как это обычно делается в строгих ФЯ, то тормозов из-за межпоточной синхронизации будет больше.
EP>Нужна ли такая абстракция или нет, приемлема ли такое penalty или нет — естественно зависит от прикладной области.
Все-таки необходимость таких вещей слабо связана с предметной областью. Предметная область для таких средств — написание хорошо взаимодействующих друг с другом библиотек. Но допустим, что это так. И что нам делать, если язык ленивость нормально не поддерживает? Избегать эту прикладную область?
EP>Я предполагаю что лучшего решения нет — мутабельные данные (модификация/чтение для которых может пересекаться) требуют синхронизации by-design, поэтому их и нужно избегать.
И вы сможете без них обходиться?
EP>Решение аналогичных задач (но через другую функциональность) в других языках достигается куда более дешёвыми средствами.
Дешевыми в смысле производительности получившегося кода — да. В смысле труда программиста — нет. Аналогичные задачи в низкоуровневых языках решаются ручным слиянием функций, вместо их комбинирования.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[52]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
K>>Непонятно, в каком смысле это аналогично C++ если там нет даже второго крайнего положения, не говоря уже о промежуточных, а есть только одно.
EP>Второе крайнее положение есть — type-erasure, но оно достигается специальным кодом, а не компилятором. EP>Например можно сделать так: EP>
Оба варианта работают с "callable" типа int(double), без всякого наследоавния. Но в первом случае код шаблона должен быть виден в месте использования (хотя конкретные специализации можно компилировать отдельно), а во втором — раздельная компиляция.
Речь идет о разных вариантах компиляции одного и того же кода. А тут код отличается.
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[31]: Есть ли вещи, которые вы прницпиально не понимаете...
Здравствуйте, Klapaucius, Вы писали:
EP>>Никакого монадического кода там не было, если конечно не считать тривиальную монаду. K>там не Identity, а Continuation монада (наскольк вообще можно говоритьо монадах в бестиповом языке).
Где тут continuation:
(define (user_func get Mx My)
(define x '())
(define y '())
(set! x (get Mx))
(if (less x 1000)
(begin
(set! y (get My))
(* x y))
'()))
?
EP>>Там не обработка пустого значения — а возвращение (причём возвращать пустое значение не обязательно). Это просто void. Я добавил if чтобы продемонстрировать что это именно монада, а не АФ. K>Да про if-то понятно, дело в (). Ну, представьте, что это на типизированном языке написано — какой у нее возвращаемый тип?
Зависит от идиом языка, возможно какой-нибудь null/nil/nullptr/void/etc, под всё можно подстроить оборачивающий код.
Но, это пустое значение не является необходимостью. В большинстве кода не будет никакого пустого значения.
EP>>Приведите тогда пример немонадического кода на Scheme. K>Затрудняюсь. Я вообще не составил для себя твердого представления, что можно считать (не)монадическим кодом в бестиповых языках.
В Scheme ведь строгая типизация.
EP>>Какое-то засилье ненужных вычислений в ФП, из-за которого ленивость необходима как пища, продемонстрировано не было. K>Довольно странно сейчас спрашивать подтверждение тому, что вы сами же и заметили и разговор о чем начали K>здесь
foldl (+) 0 a (обсуждаемый выше) для [Maybe a] будет неэффективным
Мы же говорим про монадизацию существующего кода?
1. Так а чем ленивость помогает в случае с foldl [Maybe a]?
2. Как ленивость поможет монодизировать foldl/foldr [list a] ?
EP>>Мы же вроде обсуждали монадический код? K>Вы же сами перешли на тему обеспечения производительности "комбинаторного" кода. Но темы, конечно, пересекающиеся.
Это другая тема. Да — call/cc это дорогая конструкция.
EP>>С этим я не спорю. Я просто показал, как в языках с call/cc обычный код легко превращается в монадичный. K>Это скорее демонстрация того, что монада Cont[inuation] может служить функциональной заменой для многих монад.
Для всех монад http://blog.sigfpe.com/2008/12/mother-of-all-monads.html
K>Проблема превращения "обычного" кода в монадический, вообще принципиально сложная. Без указания мест где нужны >>= это не сделать. Вашем коде они вручную помечены. Вот сделать из монадического обычный гораздо проще — для этого Identity монады достаточно.
Я же говорю: они помечены только из-за ограничений Scheme.
1. Но даже в Scheme — эти get/await могут быть где-то в глубине call-tree, а функции их вызывающие никак не поменяются.
2. Изменения минимальны — вместо x будет (get x). Нет никакого кардинального изменения кода как в Haskell в виде нарезания всего control-flow на замыкания.
3. В том же C++/D ничего помечать не нужно. Но там нет полноценного call/cc, а есть ограниченный.