1. Си / Говнокод #14224

    +135

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    void permutate(int a[10], int n) {
        // God bless mr. Donald E. Knuth;
        // Tons of oil to English bell ringers!
    
        // WARNING: It's dangerous to go alone, take this^H read this shit
        int c[10], o[10], j, s, q;
        for (j = 1; j <= n; j++) {
            c[j] = 0;
            o[j] = 1;
        }
        while (1) {
            check(a, n);
            j = n;
            s = 0;
            while (1) {
                do {
                    q = c[j] + o[j];
                    if (q < 0) { o[j] = -o[j]; --j; }
                } while (q < 0);
                if (q == j) {
                    if (j == 1) return; else ++s;
                    o[j] = -o[j];
                    --j;
                    continue;
                }
                int t = a[j - c[j] + s];
                a[j - c[j] + s] = a[j - q + s];
                a[j - q + s] = t;
                c[j] = q;
                break;
            }
        }
    }

    Реализация алгоратма "простых изменений" по описанию из Кнута (т4. Комбинаторный поиск, генерация всех перестановок).
    Напрашивающиеся goto раздражают, было бы приятно увидеть менее пахучие реализации. Не смог нагуглить, забугорного названия этого алгоритма не знаю, а про "простые изменения" тинай вики молчит.

    Запостил: vistefan, 13 Декабря 2013

    Комментарии (95) RSS

    • > забугорного названия этого алгоритма
      plain changes

      http://en.wikipedia.org/wiki/Steinhaus%E2%80%93Johnson%E2%80%93Trotter_algorithm

      Оно?
      Ответить
      • http://code.google.com/p/i-iterate/source/browse/trunk/lisp/i-iterate.el#954
        Моя самописная реализация Джонсона-Троттера (его отличие от других пермутаций в том, что всегда изменяется только одна соседняя пара.
        Там же дальше есть более простой вариант, но изменения там происходят в более сложном порядке.
        Ответить
        • праздный вопрос
          а зачем нужны ,запятые ,перед ,словами?
          что они означают?
          Ответить
          • Если не вдаваться в подробности:
            ' - quote, возвращает список как есть, не исполняя его
            ` - quasi quote, возвращает список как есть, не исполняя его, но в этом списке можно юзать ,
            , - позволяет вставить значение некого выражения
            Ответить
            • Если очень-очень грубо (да простит меня wvxvw за такие примеры):
              if ($x) {
                  // включаем квазицитирование (аналог `)
                  ?>
                      <p class="shit">
                          <!-- аналог , -->
                          <?= $some_shit + 5 ?>
                      </p>
                  <?php
              }
              Ответить
              • wvxvw обидится, если намекнуть, что даже js лучше лиспа
                впрочем, так оно и есть
                Ответить
                • > даже js лучше лиспа
                  Чем? Ну кроме раскрученности.
                  Ответить
                  • write-only код
                    медленное исполнение
                    нулевая область применения

                    чем бы ещё потроллить...
                    js не требует после пробела уродских запятых, за которыми пробела нет
                    что там про типографику сегодня было?
                    Ответить
                    • > js не требует после пробела уродских запятых, за которыми пробела нет
                      Эти запятые не после пробела, а перед следующим за ними выражением ;) К тому же эстеты могут юзать функцию list вместо `, ' и ,.

                      > write-only код
                      А это зависит от исполнителя. Метапрограмминг на лиспе выходит почитабельней, чем исходники буста (если писать helper-функции, и не следовать стилю "я ебашу мммаксимум функционала в одну функцию/макро").

                      > медленное исполнение
                      Ой ли :) js только в последние годы jit'ом обзавелся, а у лиспов генерация кода была с хер пойми каких времен. Дико тормозной из них разве что clisp, который чистый интерпретатор.
                      Ответить
                      • > метапрограмминг
                        в примере выше, очевидно, он присутствует?
                        без подсветки синтаксиса непосвященному человеку вообще не разобрать где что
                        в бусте нечитабельны только вещи, злоупотребляющие BOOST_PP_

                        > Ой ли
                        что-то не припоминаю графических игор на lisp
                        или тру-лисперы выбирают адобе плоть для побочных задач?

                        да ну да ладно
                        перейдем к высокому
                        как с помощью лиспа зарабатывать?
                        вот приходит заказчик и говорит - у меня есть задача <заполните поле>, за которую заплачу <заполните поле> иллионов ублей <либо заполните валюту>, сделайте мне, пожалуйста, её на <лиспе??>, потому что это <всем будет удобно??>
                        Ответить
                        • > без подсветки синтаксиса непосвященному человеку вообще не разобрать где что
                          А это тот самый стиль "я ебашу мммаксимум функционала в одну функцию/макро", так обожаемый wvxvw (видимо ради производительности?). Если вынести часть кода в хелперы, чтобы в макросе остался только необходимый минимум подстановок - будет вполне читаемо.

                          > как с помощью лиспа зарабатывать?
                          http://www.linux.org.ru/forum/development/6620869
                          Ответить
                          • ох ну тут лисп как-то ненадежно приделан
                            примерно так же, как "ребята использовали винду для запуска программы трассировки - при помощи винды мы заработали охулиярд, слава винде!"
                            но биржевые железки это хоть и нишевая, но очень годная и дорогая тема
                            Ответить
                        • На Лиспе было написано пару игрушек, но это как-то совсем не сильная сторона языка. Есть биндинги к ЛТК / КУДА, я даже что-то простенькое делал, но опять же, это было сделано исключительно в качестве развлечения / от нечего делать.
                          Типичное использование Лиспа: проекты типа Cyc, ACT-R и т.д. Тот же AllegroGraph, с которым я сейчас пытаюсь активно познакомиться. Где Лисп хорошо подходит: моделирование новых языков или их частей. Обработка натуральных языков. Прототипирование (умеючи, на Лиспе можно очень быстро писать). Еще где используется: ну, например, ACL2 - это прувер для железа / фирмвареза который автоматически ищет дефекты в схемах / функциях взаимодействующих с железом. Но мне этим пользоваться не приходилось.

                          Я за всю свою жизнь видел только одно объявление, где искали Лисп-программиста. В лабораторию MIT нужен был человк заведующий серверной частью какого-то исследовательского проекта.
                          Но, на самом деле нет особой проблемы сваять, например, веб-сайт, или какое-нибудь ПО для встраиваемых систем (ECL вполне даже неплохая альтернатива тем же Луа / Питону). Обычно все упирается в отстутствие кадров, способных поддерживать код, и зависимость циклическая: нету кадров -> нет работы, нет работы -> нет кадров.
                          Я когда только знакомился с языком, то использовал его для написания билд скриптов и тестов :) и для генерации всякой херни, которая нужна была для проекта, типа ассетов встраиваемых в программу, каких-то таблиц и т.д. Сделать это не сложно, и работает хорошо, но поддерживать некому.
                          Ответить
                        • И еще раз, этот код не показательный, если нужно посмотреть на то, как выглядит обычный код на Лиспе (того же человека), то, вот пример: https://github.com/wvxvw/sudoku-solver/blob/master/src/solver.lisp
                          Код был написан для падавана, чтобы было на чем учиться. Комментариев практически нет, потому что они давались в устной форме, но возможно я когда-нибудь сподоблюсь оформить.

                          Код выше - это, еще раз, один очень сложный макрос. К сожалению, ничего даже похожего в Ц++ с шаблонами никто не делает, поэтому найти аналогию не представляется возможным. Этот макрос создает мини-язык для написания разных циклов, вот как в Си есть for, while, do, continue, break, так в этом языке есть for, for-in-hash-table, for-in-string, for-in-buffer, for-in-tree, for-in-list, for-<destructuring-binding>-<something-to-destrucutre>, collect, minimize, maximize, reduce, accumulate-<how>, search, previous-value-of-iterator, generate-unique-random и т.д.
                          Ну, как бы это традиционно для Лиспа, что у циклов гораздо более сложная структура и больше составляющих, чем, например, в Си. В Эмакс лиспе есть только один базовый цикл: while, а все остальное приходится восполнять макросами, которые на нем основываются.
                          Ответить
                          • > for, for-in-hash-table, for-in-string, for-in-buffer, for-in-tree, for-in-list, for-<destructuring-binding>-<something-to-destrucutre>,
                            >К сожалению, ничего даже похожего в Ц++ с шаблонами никто не делает
                            Несомненно никто не делает. Оно уже есть.

                            >один очень сложный макрос
                            god object. golden hummer.

                            >создает мини-язык
                            >поэтому найти аналогию не представляется возможным
                            boost.foreach, boost.preprocesor, boost.proto, boost.spirit 2.5.2, boost.phoenix 2.0, Boost.Xpressive и много других.
                            Ответить
                            • Лол, нет. Это один макрос специально написаный для итерации, а не для всего, что угодно. Ц++ / буст утилиты очень-очень скромно выглядят по сравнению с loop / iterate. На ЦПП очень тяжело написать макросы подобного характера / они бы почти наверняка включали бы в себя целый компайл-тайм интерпретатор типа ПХП.
                              Просто в языках с плохими / отстутствующими шаблонами такие вещи не делают, потому что очень сложно.
                              Ответить
                              • > loop
                                А ведь о нужности и удобстве loop идут споры даже среди лисперов...

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

                                В крестах (особенно в с++11) императивный цикл смотрится намного проще и понятней, чем язык лиспового loop'а.

                                Итерирование по контейнерам? У каждого контейнера есть begin() и end(), возвращающие итератор. В с++11 для обхода любого контейнера достаточно простого for'а. Что мы видим в loop - отдельное слово для каждого контейнера, in, being, across и прочие.

                                Локальные переменные? Выполняемые действия? Условия? Да не нужен тут специальный язык, тупо ставим скобки и описываем переменные, вызываем нужные функции, проверяем условия. Что мы видим в loop - отдельный язык аля with, when, while, until и т.п.

                                Деструктурирование? А так ли оно нужно... в крестах user.name и user.age смотрятся не так ужасно, чтобы их копировать в отдельные переменные name и age.

                                Вот единственный плюс loop'а - аггрегирующие функции аля collect, append и т.п. Но и тут императивное max_age = std::max(user.age, max_age) смотрится не так уж ужасно.

                                P.S. Про iteratee ничего сказать не могу, надо раскуривать их. Может быть в них как раз есть интересные и новые идеи, которых я не заметил в loop.
                                Ответить
                                • Те, кому loop не нравятся делятся на две категории:
                                  1. Не нравится потому, что нельзя расширять и дополнять - эти используют iterate.
                                  2. Не нравится потому, что сложно - пишут на Схеме.

                                  Нормальный программист на Лиспе либо будет использовать loop всегда, даже там, где можно было бы использовать do / dotimes / dolist и т.д. Либо будет использовать iterate (его тоже есть причины нелюбить, но это отдельная история).

                                  Блин, как это можно не понимать. Один шаблон /= один объект. В этом случае, один шаблон = один язык. Это как регулярные выражения, а не как "очень длинная функция". Если всю реализацию регулярных выражений упихать в одну функцию - да, будет плохо, но в примере же нет ничего подобного, в примере система функций, шаблонов, и там даже классы есть с методами, которые реализуют один большой шаблон.
                                  Ответить
                                  • > Не нравится потому, что нельзя расширять и дополнять - эти используют iterate.
                                    У меня именно эта причина. Надо почитать про них, да попробовать поюзать, но все никак руки не доходят.

                                    > Нормальный программист на Лиспе либо будет использовать loop всегда, даже там, где можно было бы использовать do / dotimes / dolist
                                    Но не потому, что loop такой крутой, а потому что do - неюзабельное говно :)

                                    > В этом случае, один шаблон = один язык.
                                    Да я прекрасно понимаю, что loop это отдельный язык, и что он удобен в пределах лиспа. Я не понимаю только смысла тащить его в кресты и другие императивные языки, в них из функционала этого loop'а нет разве что аггрегации. В общем же случае да, иногда хочется запилить DSL для конкретной задачи, но кресты толком не дают :)
                                    Ответить
                                • Хз. Ну вот это тоже замечательный объектвиный показатель качества: "мне нравится потому, что я так привык", "неюзабельное говно, потому что не умею пользоваться" и т.д. Есть теоретические основания, которые нужно показывать и доказывать с использованием семантических правил, систем которые позволяют на основании общепринятых аксиом и теорем полученных с помощью общепринятых методов сделать какие-то выводы. Без этого обсуждение превращается в "сам дурак".
                                  do в Лиспе не может выразить те же понятия, что и do цикл в Си? И где это можно увидеть? Формально, у Лиспового do большая выразительная сила потому что в нем можно описать возвращаемое значение и локальные переменные, чего нету в сишном do. Ну и на одно ключевое слово меньше, т.как положение в тексте достаточно для того, чтобы отличить условие выхода из цикла от остального кода (так же, как и в сишном for, например).
                                  Причина его не использовать заключается в недостаточном уровне абстракции, в необходимости указывать технические детали, там, где они не важны. Особо в этом смысле показательно то, что те, кто приходят из других языков, типа Си обычно чувствуют себя по-началу лучше с do, потому что им хочется писать бойлерплейт, к которому они привыкли. (Это выглядит так же глупо, как когда приходят из функциональных языков и пытаются циклы заменять рекурсией - это как правило с подачи какого-нибудь старпера преподавателя, который думает, что Лисп - это функциональный язык).
                                  Ответить
                                  • > do в Лиспе не может выразить те же понятия, что и do цикл в Си?
                                    Формально, do и сишные for/while эквивалентны - есть инициализация, есть проверка для остановки, есть некоторые действия, выполняемые в цикле, можно вернуть значение (в си через присваивание переменной). С этой точки зрения у меня претензий нет ;)

                                    > Причина его не использовать заключается в недостаточном уровне абстракции
                                    Да, это и есть основная проблема, из-за которой я назвал do говном. Хотя ее частично решают отдельные функции - dolist, dotimes, и другие самодельные версии.

                                    > Особо в этом смысле показательно то, что те, кто приходят из других языков, типа Си обычно чувствуют себя по-началу лучше с do
                                    Ну не знаю, я посмотрел на do, мне очень не понравились его синтаксис и низкоуровневость, не подходящие к высокоуровневой натуре лиспа, и я как-то сразу начал юзать loop.

                                    > функциональных языков и пытаются циклы заменять рекурсией
                                    Да рекурсия смотрится глупо даже в ФЯП. Все-таки основная черта ФЯП - это широкое использование ФВП, а рекурсия или "цикл" инкапсулированы в этой функции - не важно. В том же хаскеле я пользуюсь рекурсией довольно редко.
                                    Ответить
                                • Мне, кстати, никогда не нравился лисповый loop. По большей части он write-only: читается легко, писать сложно, если ты не варишься в языке постоянно. Помню, где-то видел графический чит-шит для него, портянка на весь экран (что-то она уже не гуглится).
                                  В последнее время я всё больше склоняюсь к плюсовым алгоритмам или тупым циклам.
                                  Ответить
                                  • > По большей части он write-only
                                    Да просто не надо писать на нем всё тело цикла ;) Когда его юзаешь на уровне типичного foreach или for со счетчиком - читается очень легко.

                                    > плюсовым алгоритмам
                                    А вот интересно, почему в плюсах нет итерируемых прокси-объектов в духе filter, map или take_while?
                                    for (int x : my::filter(some, [](int x){return x < 5;})) {
                                    }
                                    Ответить
                                    • Хоть и ограничено из-за малого числа алгоритмов и отвратительной многословной расширяемости, но часть функций boost::range можно юзать как чистые функции высшего порядка. К слову фильтра там вроде нет.
                                      Ответить
                                  • > write-only: читается легко, писать сложно
                                    WTF? read-only тогда уж ;)
                                    Ответить
                              • > такие вещи не делают, потому что очень сложно

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

                                Лисп же ближе опытным хакерам-одиночкам, ну на крайней случай сплоченной группе из 2-3 человек. В такой ситуации метапрограмминг и прочие мощные фишки никому не навредят, и послужат во благо.
                                Ответить
                                • > Излишняя мощность языка просто сломает эту коммуникацию и снизит взаимозаменяемость программистов, а без нее таким командам очень и очень плохо.

                                  На практике не случается. Я учавствовал в проектах с другими лисперами, ничего похожего не заметил. (Мы несколько раз учавствовали в ICFP).

                                  Что до полезности таких шаблонов безотносительно языка (мое мнение, что Си говно, и что улучшать его таким образом - не сильно поможет, поэтому я не агитирую за его улучшение вобщем).
                                  Такие шаблоны помогают писать более общий код, т.как они позволяют программисту не указывать детали реализации, которые ему не интересны, оставляя их на совести компилятора / автора библиотеки.
                                  Хрестоматийный пример: есть у нас Си-подобный цикл:
                                  for (int i = 0; i < limit; i++) {
                                    element = some_collection[i];
                                    if (filter(element)) {
                                      other_collection.add(element);
                                    }
                                  }

                                  плох тем что: Нужно написать скучный бойлерплейт по объявлению счетчика, его тип, инкремент, получение элемента из коллекции. Нужно заранее тип инкремента (вперед, назад, а может на треды разбить?). Нужно указать как именно добавлять элемент в новую коллекцию (а может быть мы наперед не знаем как лучше это сделать?) Аналогично с получением элемента из коллекции. Самое плохое в этом то, что программисту, который просто хотел отфильтровать элементы из коллекции, все эти детали не интересны / не важны. И уж подавно не хочется их писать вновь и вновь. Шаблон как раз и предназначен для того, чтобы решить все эти проблемы один раз, и больше с ними не заморачиваться. В шаблоне может быть логика позволяющая выяснить тип счетчика исходя из типа коллекции, можно так же разбить на треды исходя из параметров коллекции, можно исходя из типа целевой коллекции определить способ добавления элементов и исходя из типа изначальной коллекции - способ получения элементов. И все это можно сделать один раз, чтобы больше об этом голова никогда не болела.
                                  Ответить
                                  • > Си говно
                                    Си - не говно. Это просто низкоуровневый системный язык. И писать на нем прикладнуху в 21 веке - ССЗБ.

                                    > Я учавствовал в проектах с другими лисперами, ничего похожего не заметил.
                                    Значит сказывается скилл вашей команды :)

                                    > Нужно написать скучный бойлерплейт по объявлению счетчика, его тип, инкремент, получение элемента из коллекции.
                                    В си - да. В с++ - обычный for (т.к. у любого контейнера можно получить итераторы).

                                    > программисту, который просто хотел отфильтровать элементы из коллекции, все эти детали не интересны / не важны
                                    Не важны - std::copy_if(). Важны - пишем ФВП (ну или функцию, принимающую указатель на функцию и контекст, если это сишка), и инкапсулируем в нее детали обхода. Либо делаем специализированный итератор, и над ним можем гонять стандартные алгоритмы.

                                    Пример из практики: нужна была функция, которая возвращает объекты, стоящие неподалеку от другого объекта. Я реализовал ее в виде ФВП:
                                    map.for_nearest_objects(..., [](object &obj) {
                                        // делаем что-нибудь с объектом
                                    });
                                    И потом раза 3 переделывал реализацию, не трогая кучу мест, который ей пользовались ;) Как вариант - можно было реализовать ее в виде итератора, и юзать так:
                                    for (object & obj : map.get_nearest_objects(...)) {
                                        // делаем что-то с объектом
                                    }
                                    Ответить
                                    • Не нужно прикрываться низкоуровневостью, есть замечательные вменяемые низкоуровневые языки, типа того же Форта, которые теоретически и морально обогнали Си на несколько световых лет. Но их не используют по той же причине, по которой в анекдоте человек искал ключи под фонарем, вместо того, чтобы искать их там, где потерял. Синтаксис Си больше похож на европейские языки / европейскую математическую нотацию. (Например, для японца порядок слов типа <объект>, <метод>, <аргумент> звучит дико, т.как в японском фразы строятся по принципу <объект>, <аргумент>, <метод>).
                                      Есть очень хорошая лекция, которую дал автор Фортрана, Бакус, на получении награды Тюринга о семантике и о будущем развитии языков. В этой лекции он очень сжато и доступно описал проблемы языков похожих на Фортран, и предложил пути решения.

                                      Ц++ итераторы уступают шаблонам, т.как это опять же, недостаточный уровень абстракции. Например, в iterate есть возможность не зависимо от типа коллекции, того в какую сторону идет итерация и т.д. получить предыдущий или следующий элемент коллекции. Для того, чтобы такое реализовать с Ц++ итераторами нужно будет очень сильно постараться.

                                      В той же лекции, Бакус упоминает о том, что функции несут с собой так же дополнительную семантическую нагрузку. Функция типа for_each в Ц++ не эквивалентна / хуже аналогичного макроса потому, что уже будучи функцией добавляет ненужный семантический мусор: мы не хотели вызывать функцию / в for_each, как функции нет необходимости, мы ее используем только потому, что мы хотим разбить код на меньшие блоки, но это не то, для чего вообще нужны функции. Кроме того, использование такой функции налагает определенные ограничения на структуры по управлению контролем выполнения цикла, делает невозможным параллельное перечисление нескольких коллекций.
                                      Ответить
                                      • > вменяемые низкоуровневые языки, типа того же Форта
                                        Кстати, на форте вроде бы даже пытались сделать универсальный bios. openbios или как там его...

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

                                        > чтобы такое реализовать с Ц++ итераторами нужно будет очень сильно постараться.
                                        Ну в крестах же есть разные итераторы, в том числе и двунаправленные, и даже random access, которые умеют полноценную адресную арифметику. Просто не для всякой коллекции они имеют смысл. И не всякий итератор связан с коллекцией: например для istream_iterator'а перемотка назад и запись вобще не имеют смысла.

                                        Любой алгоритм должен использовать итератор с минимально-достаточными возможностями. c++11 for - алгоритм обхода в неком порядке, известном только контейнеру. Поэтому ему достаточно однонаправленного итератора.
                                        Ответить
                                        • Ну это как слепому про цвета рассказывать. Нет, нельзя с Ц++ итераторми сделать обобщенный next-item / previous-item.
                                          Почему?
                                          Рассмотрим следующий пример:
                                          for (some_iterator i = some_container.end; i != some_container.begin; i--) {
                                            j = NEXT_ITEM(i);
                                          }

                                          Откуда в таком случае NEXT_ITEM узнает о том, что для того, чтобы получить следующий логически элемент нужно инкрементить итератор а не декрементить?
                                          Ответить
                                          • в данном случае как раз в с++ ты написал не очень правильно
                                            начинаешь с end - несуществующего элемента, к которому нельзя обращаться
                                            игнорируешь "последний" begin - его не обрабатываешь
                                            поэтому на с++ то же самое будет выглядеть как
                                            for (reverse_iterator i = container.rbegin(); i != container.rend(); ++i)
                                               j = NEXT_ITEM(i);
                                            }
                                            и вот уже все проблемы взяли как-то взяли и ушли
                                            Ответить
                                            • Неа, это ты просто не понял о чем пример. В примере итерация идет от конца к началу: а почему я не могу этого хотеть? В некоторых случаях, это именно то, что мне и нужно. А вот макрос "получить следующий элемент итерации" никогда не сможет получить информацию о том, в какую сторону идет итерация, и поэтому обламается.
                                              Ответить
                                              • Если ты пользуешься реверсированным итератором, то std::next будет правильно переводить итератор в следующий элемент относительно движения. Если тебе нужен следующий элемент с точки зрения контейнера, то юзай i.base() и применяй к нему std::next
                                                Ответить
                                              • > Неа, это ты просто не понял о чем пример.
                                                очень даже правильно понял
                                                это ты не нашёл в ответе reverse_iterator просто

                                                всё, что нужно знать внутри твоего NEXT_ITEM(iter_type), это то, что этому iter_type ты можешь сделать ++, или std::next, или даже + 10

                                                а уж куда этот ++ будет менять итератор - не сопливое дело NEXT_ITEM

                                                в данном случае такой итератор уже даже есть в стандартной библиотеке для всех контейнеров, где обратная итерация имеет смысл - в виде сущности reverse_iterator

                                                у reverse_iterator перегружен ++, который, верно, будет двигать итератор в обратную сторону к началу контейнера, и перегружены многие другие вещи, которые не позволят отличить этот реверсивный итератор от прямого
                                                Ответить
                                                • Нет, это все-таки ты не понял :) Ну вот полноценный пример:
                                                  (defun palindromp (string)
                                                    (iter
                                                      (with i := 0)
                                                      (with j := (1- (length string)))
                                                      (for ic :next (aref string (incf i)))
                                                      (for jc :next (aref string (decf j)))
                                                      (for pic :previous ic)
                                                      (for pjc :previous jc)
                                                      (when (char/= ic jc) (return (values pic i pjc j)))
                                                      (while (> j i))
                                                      (finally (return t))))

                                                  В этом коде совсем не важно каким образом происходит итерация, я ее могу прямо на месте описать, но используя ключевое слов previous, я могу получить предыдущий элемент сгенерированный драйвером цикла. В Ц++ куда будет показывать next нужно указывать в каждом случае конкретно подставляя конкретный итератор (пример приведенный выше я могу использовать как макрос, и подставлять туда какой-угодно генератор / драйвер, previous все равно будет работать корректно).
                                                  Ответить
                                                  • да блин
                                                    http://ideone.com/c69R1O
                                                    так понятней?
                                                    print_foobar все равно, какой тип ей передали, всё что ей интересно - это наличие у переданного типа операторов + int, - int, *
                                                    что обеспечивают и iterator, и reverse_iterator

                                                    предыдущий элемент итератора ты можешь получить с помощью -1, следующий - +1
                                                    в какую сторону двигается итератор знает только итератор
                                                    Ответить
                                                    • Ну, естесственно, это не то. Возьмем мой предыдущий код, и переделаем его вот так:
                                                      (defmacro palindromp (string do-something do-something-else)
                                                        `(iter
                                                          (with i := 0)
                                                          (with j := (1- (length string)))
                                                          (for ic :next ,do-something)
                                                          (for jc :next ,do-something-else)
                                                          (for pic :previous ic)
                                                          (for pjc :previous jc)
                                                          (when (char/= ic jc) (return (values pic pjc)))
                                                          (while (> j i))
                                                          (finally (return t))))

                                                      Я в этом коде не знаю что конкретно значит "предыдущий" элемент, это конкретизирует кто-то другой, кто будет этим кодом пользоваться, но каким бы ни было значение предыдущего элемента для будущего пользователя оно будет правильным, потому что оно будет понято из того конкретного выражения, которое будущий пользователь ему задал. В Ц++ нельзя наперед не зная какой код будет использоваться для вычисления следующего элемента, написать код, который будет всегда возвращать предыдущий.
                                                      Ответить
                                                      • посмотри внимательно на мой пример
                                                        print_siblings не знает что конкретно значит предыдущий элемент, об этом знает шаблонный тип Iter
                                                        на него (на Iter) накладываются требования реализовать это знание на момент инстанциирования шаблона - компилятор проверит и не промолчит
                                                        всё что мне хочется на момент написания print_ - это чтобы нечто умело в -1 (декремент) и затем умело в * (разыменование)
                                                        поэтому в качестве Iter я могу передать что угодно, лишь бы это что угодно удовлетворило компилятор на тот момент, когда функцию реально начинают использовать с реальным аргументом
                                                        Ответить
                                                  • > сгенерированный драйвером цикла
                                                    Use the Mousepad driver, Luke.
                                                    Ответить
                                                    • Да...
                                                      http://common-lisp.net/project/iterate/doc/Drivers.html#Drivers
                                                      офигеть как смешно, слово знакомое...
                                                      Ответить
                                                      • Я тебе так скажу. Новое понятие они ввели не из-за хорошей жизни.
                                                        Ответить
                                                        • Какое ж оно новое? Так называли и называют части шаблонов цикла еще за два десятилетия до того, как Ц++ был в проекте, например.
                                                          Ответить
                                                          • > Так называли и называют части шаблонов цикла еще за два десятилетия до того, как Ц++ был в проекте

                                                            Кто называл и в рамках какого диалекта языка? Первые версии c++ появились чуть раньше CL.
                                                            Ответить
                                                            • Так они называются в коде / комментариях к реализации loop. Авторство мне не известно / я еще скорее всего не родился, когда это начали использовать. Loop существовал в таком виде до того, как стандарт приняли.

                                                              Кстати, одна из причин, почему макросы внутри loop не раскрываются - обратная совместимость с Мак Лиспом. Но таких древних исходников у меня нет, а гонятся за людьми у которых они могут быть только ради такой фигни я не стану.
                                                              Ответить
                                                              • > Loop существовал в таком виде до того, как стандарт приняли.

                                                                wiki подсказывает, что стандарт приняли в 1994, а сам CL появился в 1984
                                                                Ответить
                                                                • Ну и что? Это стандарт приняли тогда, язык практически в таком же виде существовал с начала 60-х, MAC Lisp практически один в один Common Lisp, просто его начали развивать не стандартизируя / тогда стандарты никого особо не интересовали, т.как это просто был язык нескольких исследовательских лабораторий под эгидой МВД Штатов.
                                                                  Так, же, например, как ПостСкрипт, который стандартизировали хз. сколько лет, после того как его давным давно использовали.
                                                                  Ответить
                                                                  • Ну я поэтому и спросил, в каком диалекте и когда это появилось. К сожалению, нагуглить возможности тогдашнего MAC Lisp нынче очень сложно.
                                                                    Ответить
                                                                • http://maclisp.info/pitmanual/contro.html

                                                                  Искать подстроку "LOOP Iteration Macro", и за ней дальше есть примеры.
                                                                  Ответить
                                  • > Си говно
                                    > other_collection.add(element);
                                    Да ты си и кресты похоже путаешь.
                                    Ответить
                                    • >> other_collection.add(element);
                                      >Да ты си и кресты похоже путаешь.
                                      Ну да, в си все-таки было бы other_collection.add(other_collection, element).
                                      Ответить
                                    • Это абсолютно не важно, я вообще просто наугад написал, смысл то в том, что в Си-подобных циклах необходимо это каждый разк конкретно указывать, и невозможно избежать тупой повторяющейся работы. Так же многие встреченные мной Си-программисты гордятся тем, что им приходится писать много повторяющегося говна, типа их это закаляет...
                                      Ответить
                                      • > это каждый разк конкретно указывать
                                        Что "это"? Что указывать?
                                        Ответить
                          • > вот пример
                            Ну вот этот пример гораздо читабельней ;) Даже без комментариев можно разобраться что к чему.
                            Ответить
                    • Не, ж.скрипту в смысле скорости еще очень далеко до хорорших реализаций разных Лиспов. Из Common Lisp группы SBCL, CCL, Allegro, LispWorks и даже ECL намного быстрее ж.скрипта будут уже хотя бы потому, что язык сообщает больше информации компилятору (типы, структуры данных), может лучше распоряжаться компилятором (указывать, где можно заинлайнить, какой именно из методов использовать и т.д.).

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

                      В Лиспе тяжело оптимизировать производительность, потому что решение влоб, как правило будет сильно уступать тому же Ц++, но потрудившись, можно добиться сравнимых результатов. В конце концов, если очень сильно нужно, можно и ассемблерную вставку сделать (я никогда до такого не доходил, но возможность есть).

                      Код плохо читается с непривычки. Мне удобно, и я во многих случая предпочту переписать алгоритм на Лисп, чтобы с ним работать, даже если есть реализация на другом языке.
                      Еще однин момент: часто говорят, что Лисп очень многословный. Я сейчас портирую клиент АллегроГрафа с Питона обратно на Лисп. Иногда даже есть выигрыш по объему текста.
                      Ответить
                      • Олег, я, между прочим, только сейчас заметил деанонимизацию
                        Ответить
                        • О, еще, где-то в закромах Мозилы когда-то был код Хорвата, где ж.скрипт был реализован как ридер-макросы в Лиспе. Т.е. можно было бы используя его библиотеку писать на ж.скрипте непосредственно в Лиспе. А еще был такой же проект для Питона. Ж.скрипт был написан исключительно для комитета по стандартизации, как модель будущего языка. Но как-то мне не известно о случаях Лисп-программистов использующих этот набор ридер-макросов для других задач :)
                          Хотя видел, как кто-то использовал ридер-макросы для Ясона.

                          ПС. Я тут как-то давал ссылки на мой профиль с флешер.ру. Да и вообще было бы желание, меня по этому нику очень просто найти. Никто как-то не искал особо никогда :)
                          Ответить
                          • Вот кстати и по моему нику легко гуглюсь вконтакте и не только, но похоже я неуловимый.
                            Ответить
                          • Ищу щедрого платёжеспособного кавказца заказчика для написания программы на лиспе. http://govnokod.ru/, спросить Олега.
                            Ответить
                            • Это вот, кстати, очень странный момент, присутствующий восновном в среде программистов. Почему-то программисты уверены, что коммерческая успешность является показателем качества.
                              Например, если вы спросите музыканта, или художника о том, как соотносится плата за его работу с качеством, то скорее всего обнаружите, что связи никакой нет. Но это не ограничивается деятелями исскуства. Спросите теоретического физика, биолога, химика и т.д. - в большинстве случаев нет никакой связи между качеством исследования, его полезностью и оплатой. Более того, вещи, которые делаются на заказ, как правило, делаются без энтузиазма / не особо качественно.
                              Ну, в том смысле, что, например, художник, как правило, зарабатывает изготовлением рекламы, но с точки зрения живописи реклама редко представляет из себя что-то выдающееся. Ну уж по крайней мере совсем не пропорционально оплате.

                              В конце 90-х, в связи с тем, что компьютеры сделали процесс подготовки к печати гораздо дешевле, произошло странное явление в полиграфии: люди без полиграфического образования стали сначала понемногу, а потом массово заниматься работой раньше выполняемой узкопрофильными специалистами. Общее качество печатной продукции сильно снизилось. Кроме этого, произошел переворот в мышлении. Т.как отрасль наполнилась работниками не способными минимально отличить брак от качественной работы, эти люди начали создавать новую систему ценностей, основываясь на своем примитивном понимании проблемы.
                              Очень похожая ситуация происходит в программировании со времен Бейсика. Про что говорил еще Дийкстра. Ну а Си и его наследники только подливают масла в огонь. Люди, которые быстро шагнули к усперху с помощью ПХП или ж.скрипта, просто изза своих очень скромных познаний, создают феноменально идиотскую систему ценностей. В Mad Max был такой момент, где главный герой находит разбившийся самолет и группу детей, переживших аварию и выросших без участия взрослых, с самодельной религией, дефективным языком и т.д.
                              Ответить
                              • > Почему-то программисты уверены, что коммерческая успешность является показателем качества.
                                А потому что программирование сейчас не только и не столько искусство, сколько ремесло. Это как работа художника, и работа маляра. Маловероятно, что маляр сможет похвастаться чем-то кроме аккуратности, производительности труда и коммерческой успешности ;))
                                Ответить
                                • мне не нравится, когда "гении"-одиночки мнят себя высокими художниками, а все остальные, мол, маляры - люди, которым никакое образование вообще не нужно

                                  тут более уместно сравнение с инженерами

                                  тебе, как инженеру, надо построить саяно-шушенскую гэс, в конечные сроки с заданным качеством с заданным бюджетом
                                  и ты либо берёшь экскаваторы, краны, армированные балки, стройматериал нужного стандарта - нынешний мейнстрим - и строишь надёжную понятную документированную систему за 3 года,

                                  либо ищешь одномышленников гринписовцев-веганов, берёшь золотой совочек, продукты без ГМО, и чтобы ни одна корова не пострадала, и аккуратно ковыряешь за 10 лет нечто, что даёт в 100 раз меньше электричества, затем сваливаешь с места преступления и те, кто эксплуатируют просто охреневают

                                  вот вчера история была - наш субподрядчик за неделю так и не смог осилить использование выделенного ему подключения к Oracle, потому что у них какие то ошибки в dll, ведь пишут чуть ли не на руби (любовь к искусству ёпта)

                                  поэтому демонстрировали работоспособность на sqlite - совсем одно и то же, ага
                                  Ответить
                                  • > тут более уместно сравнение с инженерами
                                    Ну да, что-то я с маляром перегнул палку. Хотя, судя по портянкам копипасты и прочей фигне, которую тут выкладывают на гк, половина программистов как раз маляры-штукатуры, а не инженеры :) И хорошо, если над ними стоит опытный инженер-тимлид...

                                    > чуть ли не на руби
                                    Как можно писать чуть-ли не на ${lang}? У меня разрыв шаблона :)
                                    Ответить
                                    • никакого разрыва
                                      если ты собираешься что-то продавать, что должно интегрироваться (а то, что они продали нам, а мы дальше - стоит очень очень много денег), будь готов, что тебя разместят на win сервере, а не на linux, о котором ты мечтал (жаловались на это, что они не могут), будь готов, что тебе выделят oracle, а не mysql, на который ты рассчитывал изначально (ещё два месяца назад было сказано, что наверняка у вас ORM - тестируйтесь в связке с ораклом, это условие)

                                      если уж ты из любви к искусству выбираешь %languagename%, то будь добр уточни его кросс-платформенность и проблемы интеграции
                                      Ответить
                                      • > никакого разрыва
                                        Так они писали всё-таки на руби, или не на руби? :) У меня разрыв именно от слова "чуть-ли" в сочетании с названием языка. Звучит примерно так же, как немного беременна.

                                        > будь готов, что тебя разместят на win сервере, а не на linux, о котором ты мечтал
                                        > тестируйтесь в связке с ораклом
                                        Ну вообще как-то по-раздолбайски они себя повели, раз уж это было написано в ТЗ (а если не было написано - то ситуация некрасивая). Вроде же все всегда тестят именно на основной платформе, описанной в ТЗ, а на остальных багует, т.к. всем было пофиг на кроссплатформенность, и влом тестить :)
                                        Ответить
                                        • ты меня убедил, я залез на сервак и посмотрел на чем сделано говнецо
                                          на питоне, прошу прощения у руби
                                          в качестве веб-сервера pythonservice.exe
                                          это нормально?
                                          Ответить
                                  • Нет, такое сравнение не уместно. Я не говорю об единичном случае. Я проработал много лет в рекламе, и отучившись в двух художественных академиях имею достаточно материала для того, чтобы утверждать, что такие случаи не единичны, а правило. Никакой художник не любит делать рекламу, не смотря на то, что за нее лучше платят. Есть такие, кому это менее противно, но имея выбор, никто бы этим не занимался.
                                    У меня достаточно много друзей, которые занимаются исследованиями в области биологии и теоретической физики. Там даже речь не идет обычно о том, чтобы исследовать то, что нравится; исследованиия, как правило, делаются на полученый грант от какой-нибудь организации, которая в этом исследовании заинтересована. Конечно, этим не противно заниматься, точно так же, как художнику не противно делать рекламу, но никто в здравом уме не возьмется утверждать что заказные исследования, или реклама имеют большое значения для искусства / развития науки. Они имею значение по стольку по скольку позволяют на оставшиеся средства сделать что-нибудь полезное.
                                    Ответить
                                    • > Нет, такое сравнение не уместно.
                                      А сравнение программиста с художником разве всегда уместно? Дефекейт правильно пишет, программист сейчас больше инженер, чем художник. И это и не хорошо, и не плохо.

                                      Если архитектор проектировал типовые панельные дома, чтобы их можно было быстро и дешево построить, то он должен мечтать о дворцах и ненавидеть свою работу?
                                      Ответить
                                      • у меня есть теория, что любая активность становится действительно глубокой только тогда, когда становится средством.
                                        Литература приобретает глубину, когда является средством выражения проблем и идей. Музыка становится глубже при наличии программы. Математика черпает глубину в приложениях. Программы становятся глубокими и интересными, когда решают нетривиальную практическую задачу.
                                        Ответить
                                      • У меня такое впечатление, что отвечающие специально притворяются дураками и реагируют так, как будто текст предыдущего сообщения был совсем другой.
                                        Я специально сказал, "Конечно, этим не противно заниматься", и в ответ "архитектор [...] должен неавидеть свою работу". Как одно может следовать из другого? Смысл сказанного заключался в том, что нет корелляции (корелляция, это такой статистический формализм о том, что если мы изменяем что-то в системе, что-то другое тоже изменится с большой вероятностью) между стоимостью и качеством. Если мы возьмем экономистов, типа того же Смита или Нэша, то они тоже со мной в этом согласятся. Качество далеко не всегда и не в самой большой степени определяет стоимость, в жизни много ситуаций, в которых влияние качества на стоимость будет не достаточно для того, чтобы его вообще учитывать. С другой сторны, так же не наблюдается корреляции стоимости и качества, т.е. заплатив больше вовсе не факт, что работа будет сделана более качественно.
                                        Вещи, которые имеют более фундаментальное влияние на качество: способности производителя, заинтересованость производителя, элемент новшества, эстетическая компонента, социальные и моральные нормы, такие как лояльность, или патриотизм и т.д. соревновательный момент.
                                        Есть разновидности человеческой деятельности очень простые, где непосредственная оплата труда может заменить все остальные стимулы. Например, уборка помещений. Но как только работа переходит в плоскость, где вышеперечисленные стимулы применимы, они начинают играть более существенную роль.
                                        Ответить
                              • > Почему-то программисты уверены, что коммерческая успешность является показателем качества.
                                Это, видимо, карьерасты какие-то. И их достаточно в любой области.
                                А коммерческая успешность скорее - мера счастья :) Чем больше программисту-художнику заплатили за последний скучный говнозаказ, тем он дольше будет счастлив, пописывая себе по-тихоньку идеальный код, ведь деньги на еду ещё есть.
                                Ответить
                                • Нет, не мера счастья. Хаид at al. писал о исследовании которое он проводил по удовлетворенностью жизнью, и, как оказалось, материальный достаток имеет очень низкий приоритет. Т.е. уборщицы в гостиннице в общем не чувствовали себя хуже в этом плане, чем владельцы гостинницы. Более важными факторами оказались востребованность в обществе / семье, моральная обстановка на работе, соответствие работы проф. образованию, отсутствие религиозных / философских конфликтов и т.д.
                                  Конечно, это не относится к голодающим / бездомным, но факт в том, что зависимость счастья от достатка не линейная, и после определенного, совсем небольшого предела перестает значительно влиять на ситуацию.
                                  Ответить
                                  • Глобально - не мера, "не в деньгах счастье", но такие побочные эффекты как вода, еда и возможность не работать на дядю и творить в своё удовольствие какое-то время должны как минимум привлекать к себе внимание.
                                    Думаю, большое количество людей порадовалось бы, если б им сказали, что можно N дней, недель или лет просто жить - делать что угодно, спать когда угодно, быть с семьёй когда угодно.

                                    P.S.
                                    > моральная обстановка на работе, соответствие работы проф. образованию
                                    я рассматриваю ситуацию, когда работа - это стресс, рабство и дедлайны.
                                    Ответить
                                    • Порадовались, пока сами не пережили бы. Исследования того же психолога среди людей выигравших значительные суммы в лотерее показали, что это редко приносит какие-либо улучшения, более того, это чревато разными ухудшениями. Во многих случаях родственники и друзья выигравших чувствовали себя обиженными тем, как "счастливчик" распорядился выигрышем, и на этой почве происходили конфликты. Те же исследования показали, что люди выигравшие в лотерее, как правило остаются без друзей, сильно сужают свой круг общения и т.д. Люди, которые оказались по той же причине длительное время без работы, в целом были больше подвержены депрессии. Показатели самоубийств среди таких людей феноменально высокие.
                                      Другие исследования, сравнивающие людей, которые вышли на пенсию в аккурат в пенсионный возраст с людьми, которые продолжали работать после пенсионного возраста показывают, что работающие чувствуют себя во всех отношениях лучше. При чем это выражается во всем, начиная со здоровья, продолжительности жизни и заканчивая количеством друзей, обстановкой в семье и т.д.
                                      Более того, это не современный феномен, тот же Лао Дзы говорил о том, что две вещи, которые делают взрослого человека счастливым, это любовь и работа.
                                      Ответить
                                      • > остаются без друзей, сильно сужают свой круг общения
                                        Такие "друзья" и не нужны. Ну, не было у людей настоящих друзей - спасибо лотерее - помогла понять, что вокруг было только завистливое говно. Лучше сразу об этом узнать, чем после написания завещания.

                                        > среди людей выигравших
                                        > по той же причине длительное время без работы
                                        > людей, которые вышли на пенсию
                                        В том беда, что Вы и британские учёные рассматриваете какие-то резкие скачки. Человек был бедным, а потом - хоп, выиграл, зазнался, разругался и повесился. Или жил человек, годами приходил на работу в одно и то же время , а там - херакс, пенсионный возраст, вместо привычного режима - кресло, кошки, привычка вставать рано утром, куча свободного времени, которое не на что потратить и устоявшееся мышление.

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

                                        Все нормальные люди стремятся делать то, что им нравится, а не заниматься повседневной суетой. Им хочется больше свободы. Пусть даже они будут делать дома в выходные то же самое, что и на работе, но над ними не будет ненавистного начальника, правил, указаний и т.п. Делать то, что хочешь - не всегда означает "плевать в потолок", программисту-художнику такая свобода поможет, если он не алкаш.
                                        Ответить
                                        • Да, а вы конечно знаете лучше бретанских ученых как нужно проводить социологические исследования, потому что вы всю жизнь этим знанимаетесть, опубликовали дохера статей в научных изданиях, защитили докторскую и сегодня занимаете пост почетного ректора в десятке лучших универов.
                                          Ответить
                                          • http://risovach.ru/upload/2013/03/peterburg-putin-edinaya-rossiya-olimpiada-medvedev-sochi-2014-15133707_orig_.jpeg

                                            Нельзя недооценивать мощь неспециалистов :)

                                            Как-то раз Вы предоставляли список почётных пользователей эмакса. Список известных людей, прекрасно владеющих редактором. Все эти авторитеты и остальные пользователи счастливы. Но не дай Бог кто-то внезапно заменит везде вордики, эклипсики и студии на вим и эмакс, отключит мыши и заклеит на клавиатуре стрелочки. По статистике с вероятностью 90% будет волна конфликтов, провалов и самоубийств. Выжившие может быть запомнят нужные комбинации и научатся работать сверхэффективно в 90% случаев, что покажет статистика, если социологи выживут после испытания вимом.
                                            В первую выборку вошли заедушные питушки, во вторую - цари текстовых редакторов :)
                                            Ответить
                                            • > vim и emacs
                                              Ну эмакс, который с гуем, он вообще казуальный, если юзать на уровне ноутпада. Юзал его ради slime, когда с лиспом возился. Хватало десятка хоткеев, но можно было и меньше, если мышкотыкать ;)

                                              В виме на уровне ноутпада достаточно знать одну кнопку, чтобы начать редактирование. И одну кнопку и 2 команды, чтобы сохранять и выходить ;)
                                              Ответить
                                            • Какая мощь? Я говорю, что существуют исследования, доступные публике, которые были проведены и проверены людьми с опытом исследований и пониманием того, как это надо делать. Я это привожу как пример того, что предыдущий аргумент был не более чем фантазия автора, основаная на его богатом личном мире и не имеющая связи с действительностью. Почему кто-то вообще должен принимать во внимание сведения не имеющие подтверждения в действительности? Потому что автор этих сведений верит в свою мощь, в чем бы она не выражалась?
                                              С такими аргументами лучше идти в политику или религию. Там таких ждут с распростертыми объятиями.

                                              ЗЫ. Само исследование: http://www.ncbi.nlm.nih.gov/pubmed/690806
                                              Ответить
                                              • Результаты исследований опытных профессионалов не мешают выдвигать свои гипотезы. Результаты для каких-то там людей могут отличаться от результатов для определённой группы. Если, скажем, N% людей скажет, что пластинки не нужны, совсем не обязательно, что то же самое скажет N% диджеев.
                                                Мои фантазии могут не противоречить научным исследованиям бородатых дядь, только группу программистов-художников, которых печалит повседневность, сложно определить и отличить их от программистов-алкоголиков, программистов-хипстеров и программистов-карьеристов. Если таковой группы в чистом виде не существует, я вообще ни в чём не противоречу им: я описываю пустое множество, а они - всё остальное. И тут, Вы правы, мои выводы становятся совершенно бесполезными для общества.
                                                Ответить
                                                • > Результаты для каких-то там людей могут отличаться от результатов для определённой группы.
                                                  Все верно. Классический пример: Мы провели опрос среди пользователей интернета, и выяснили, что интернет есть у всех.
                                                  Ответить
                                                  • И что? И как это видно из этого исследования? Может сначала имеет смылс прочитать перед тем, как осуждать?
                                                    Ответить
                                                • Свои гипотезы нужно подверждать. Выдвигать нет смысла, если подтверждать нечем.
                                                  Ответить
                        • Хорошая реклама никому не повредит. Даже мне.
                          Ответить
                      • > язык сообщает больше информации компилятору
                        Ага, если программист сподобится приписать типы переменных :) Ну кстати sbcl оптимизирует годно, если эти типы указать.
                        Ответить
          • Это вклеивание в тело шаблона. Код по ссылке не функция, а шаблон, который потом используется как-то так:
            (i++ (for next-permuatation permute [1 2 3 4])
              (print next-permuatation))
            Ответить
            • i++?
              Ответить
              • Это была попытка написать аналог iterate для Эмакс Лиспа. Но через какое-то время я понял, что пошел по неправильному пути, и систему нужно было строить по-другому, так вот оно и осталось. Хотя большая часть работает, и даже иногда мой код компилируется лучше, чем cl-loop.
                Главная неприятность cl-loop заключается в том, что макросы внутри цикла не раскрываются до того, как он обрабатывает свое содержание, и это сильно сужает область применения. iterate, напротив, раскрывает все макросы до того, как интерпретирует сам iterate макрос. Т.е. я, например, добавлял цикл по дереву в iterate, и это совсем не сложно, а с loop так не получится.
                Ответить
                • (defmacro-clause (FOR var IN-TREE tree)
                    "Iterates over all nodes of the TREE"
                    (let ((stack (gensym)) (head (gensym)))
                      `(progn
                         (with ,head := ,tree)
                         (with ,stack := ,nil)
                         (with ,var := ,nil)
                         (while (or ,head ,stack))
                         (cond
                           ((and (null ,head) ,stack)
                            (setf ,head (cdr (pop ,stack)))
                            (next-iteration))
                           ((consp (car ,head))
                            (push ,head ,stack)
                            (setf ,head (car ,head))
                            (next-iteration)))
                         (setf ,var (car ,head) ,head (cdr ,head)))))
                  
                  (defun minmax (tree)
                    (iter
                      (for leaf :in-tree tree)
                      (minimize leaf :into min)
                      (maximize leaf :into max)
                      (finally (return (values min max)))))

                  Вот, например, расширение iterate, которое позволяет перечислять в цикле все листья дерева.
                  Ответить
    • Ну и еще есть алгоритм Нарайаны, который вроде как и используется в крестовом std::next_permutation().
      Ответить

    Добавить комментарий