Здравствуйте, alex_public, Вы писали:
_>С удовольствием посмотрю на аналогичную реализацию на Java/C#. Особенно с учётом того, что в .net вообще не осилили нормальные кортежи (ограничение на 8 элементов — это же смешно) даже просто классами, а не лямбдами.
Да хоть на чистой сишке. Понятно, что придётся каждый частный случай вручную расписывать. Но теоретически расписать можно. Главное — это подождать, когда хотя бы компиляторы определятся, как же понимать этот код
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
_>>С удовольствием посмотрю на аналогичную реализацию на Java/C#. Особенно с учётом того, что в .net вообще не осилили нормальные кортежи (ограничение на 8 элементов — это же смешно) даже просто классами, а не лямбдами. TB>Да хоть на чистой сишке. Понятно, что придётся каждый частный случай вручную расписывать. Но теоретически расписать можно. Главное — это подождать, когда хотя бы компиляторы определятся, как же понимать этот код
Там дело всего лишь в неопределённом порядке argument evaluation, это вообще ортогональная тема. Если нужен жёсткий порядок — то без проблем форсится.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Если нужен жёсткий порядок — то без проблем форсится.
Да, можно завести временные переменные и явно всё расписать. Я боюсь, если в этом коде всё явно расписать, то он потеряет всю свою загадочность.
Возможно, есть какой-то трюк, чтобы заставить параметры функции выполняться в верном порядке, и без временных переменных. Только пожалуйста, не показывайте его, мне на сегодня кода с лямбдами хватило.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
_>>С удовольствием посмотрю на аналогичную реализацию на Java/C#. Особенно с учётом того, что в .net вообще не осилили нормальные кортежи (ограничение на 8 элементов — это же смешно) даже просто классами, а не лямбдами. TB>Да хоть на чистой сишке. Понятно, что придётся каждый частный случай вручную расписывать. Но теоретически расписать можно. Главное — это подождать, когда хотя бы компиляторы определятся, как же понимать этот код
Здравствуйте, T4r4sB, Вы писали:
EP>>Если нужен жёсткий порядок — то без проблем форсится. TB>Да, можно завести временные переменные и явно всё расписать. Я боюсь, если в этом коде всё явно расписать, то он потеряет всю свою загадочность. TB>Возможно, есть какой-то трюк, чтобы заставить параметры функции выполняться в верном порядке, и без временных переменных. Только пожалуйста, не показывайте его, мне на сегодня кода с лямбдами хватило.
Ещё раз повторяю: прежде чем делать этот жёсткий порядок, в начале покажите мне пример строго определения очерёдности обхода функцией map коллекции.
Здравствуйте, T4r4sB, Вы писали:
TB>>>Дельфи? _>>Не знаком (подробно), не знаю. ) TB>Строки и динмассивы через счётчик ссылок, строки коровьи (COW, то есть при записи копируются), но мы ж вроде писать в них не собираемся?
Подсчёт ссылок — это тоже не эффективно в большинстве случаев.
Здравствуйте, T4r4sB, Вы писали:
_>>Что за лямбды в C? ) TB>Лямбда — это просто структура с методом (). В сишке это будет структура Lambda1337 и функция TB>
Здравствуйте, alex_public, Вы писали:
_>Ещё раз повторяю: прежде чем делать этот жёсткий порядок, в начале покажите мне пример строго определения очерёдности обхода функцией map коллекции.
Я для начала не понимаю, что тут мап делает. Возвращает какую-то функцию, возвращающую функцию, которая...
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, T4r4sB, Вы писали:
TB>>>>Дельфи? _>>>Не знаком (подробно), не знаю. ) TB>>Строки и динмассивы через счётчик ссылок, строки коровьи (COW, то есть при записи копируются), но мы ж вроде писать в них не собираемся?
_>Подсчёт ссылок — это тоже не эффективно в большинстве случаев.
Любой жёсткий алгоритм на все случаи жизни будет неэффективен в большинстве случаев, ты вроде про какую-то конкретную задачу говорил.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
EP>>Если нужен жёсткий порядок — то без проблем форсится. TB>Да, можно завести временные переменные и явно всё расписать. Я боюсь, если в этом коде всё явно расписать, то он потеряет всю свою загадочность.
Я к тому что это не баг, а фича. Даже если не брать в расчёт особенность порядка evaluation аргументов в C++ — то всё равно map'у обычно соответствует произвольный порядок, точнее для map порядок не важен. Если важен, то это выражается через другие примитивы — foldl, for_each.
Кстати, например std::transfrom не гарантирует порядок, а std::for_each гарантирует.
TB>Возможно, есть какой-то трюк, чтобы заставить параметры функции выполняться в верном порядке, и без временных переменных.
Да, помимо прямого способа есть трюк.
TB>Только пожалуйста, не показывайте его, мне на сегодня кода с лямбдами хватило.
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, lpd, Вы писали:
lpd>>Если в терминологии wikipedia{C++11}{C++14}: lpd>>lamda-выражения считаю бесполезными — если мне надо вызвать несколько функций, я их вызову без lambda. lpd>>Alternative function syntax — зачем? lpd>>User-defined literals — бесполезно. lpd>>Function return type deduction — ужас lpd>>Variable templates — бесполезно
TB>Ты на С++ писал, как на Си, только с классами, да?
Даже если усложнить C++ еще парой десятков вариадиков и лямбд, для фреймворков его использовать больше не будут. А в каком случае будут, и далеко ли до этого, — вопрос этого топика.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, AlexRK, Вы писали:
ARK>Какие реальные задачи оно решает или может решить?
Например есть набор разнотипных объектов поддерживающих одинаковую функцию draw. Эти объекты нужно где-то хранить и делать обход с вызовом draw.
Если решать через наследование с виртуальными функциями, положив всё в один массив — то получаем overhead от косвенных вызовов, лишних индерекций, аллокаций и т п.
Альтернативный вариант — класть объект каждого типа в свой отдельный массив соответствующего типа. А при обходе обрабатывать массивы по-очереди — сначала первый массив, потом второй и т.п. — в этом случае не будет ни косвенных вызовов, ни лишних индерекций и т.п.
Вручную выписывать каждый контейнер, а потом выписывать каждый вариант обхода, да ещё и следить за изменением списка типов не удобно. Вот как раз для автоматизации всего этого и используются библиотеки подобного рода (например Boost.Fusion или Hana).
Здравствуйте, T4r4sB, Вы писали:
_>>Ещё раз повторяю: прежде чем делать этот жёсткий порядок, в начале покажите мне пример строго определения очерёдности обхода функцией map коллекции. TB>Я для начала не понимаю, что тут мап делает. Возвращает какую-то функцию, возвращающую функцию, которая...
Ну это особенность реализации кортежа через лямбды. Т.е. кортеж — это замыкание, которое принимает другую функцию (и применяет её к данным).
Но я говорил про другое. Что данный данная реализация кортежей в общем то корректна (хотя это всего лишь демо пример лямбд) и соответствует общепринятым техникам в функциональном программирование. Единственная небольшая некорректность там, это использование в map нечистой функции (вывода на консоль).
Здравствуйте, T4r4sB, Вы писали:
TB>>>Строки и динмассивы через счётчик ссылок, строки коровьи (COW, то есть при записи копируются), но мы ж вроде писать в них не собираемся? _>>Подсчёт ссылок — это тоже не эффективно в большинстве случаев. TB>Любой жёсткий алгоритм на все случаи жизни будет неэффективен в большинстве случаев, ты вроде про какую-то конкретную задачу говорил.
В данном конкретном примере тоже не эффективно (по сравнению с реализацией в современном C++).
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Например есть набор разнотипных объектов поддерживающих одинаковую функцию draw. Эти объекты нужно где-то хранить и делать обход с вызовом draw. EP>Если решать через наследование с виртуальными функциями, положив всё в один массив — то получаем overhead от косвенных вызовов, лишних индерекций, аллокаций и т п. EP>Альтернативный вариант — класть объект каждого типа в свой отдельный массив соответствующего типа. А при обходе обрабатывать массивы по-очереди — сначала первый массив, потом второй и т.п. — в этом случае не будет ни косвенных вызовов, ни лишних индерекций и т.п.
EP>Вручную выписывать каждый контейнер, а потом выписывать каждый вариант обхода, да ещё и следить за изменением списка типов не удобно. Вот как раз для автоматизации всего этого и используются библиотеки подобного рода (например Boost.Fusion или Hana).
Проблему понял, хотя связь с приведенным лямбдовым кодом не вполне уловил.
Лично я, не будучи программистом экстра-класса (хотя и знаком с функциональными приблудами), однозначно предпочел бы видеть в проекте три или четыре руками написанных контейнера с разными объектами, чем нечитаемый (как минимум, лично мной) вышеприведенный говнокод с лямбдами. Если же число разнотипных контейнеров велико, то я бы задумался о применении нормальной — читаемой — кодогенерации (не на С++). Вот такое мое скромное мнение.
Здравствуйте, alex_public, Вы писали:
_>В данном конкретном примере тоже не эффективно (по сравнению с реализацией в современном C++).
Несколько раз счётчик лишний раз подёргать, это уже жёсткая оптимизация константы пошла, не встречал случаев, когда надо работу со строками оптимизировать до константы.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте