1. C++ / Говнокод #14175

    +9

    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
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    // fib.h
    #pragma once
    using ull = unsigned long long;
    
    inline constexpr ull fib(size_t n, ull first, ull second) {
      return n == 0 ? first : fib(n - 1, second, first + second);
    }
    
    inline constexpr ull fib(size_t n) {
      return fib(n, 0, 1);
    }
    // fibs.h
    #pragma once
    #include "fib.h"
    #include <array>
    
    enum class fibs : ull {
    #define FIB(i, val) fib##i = val,
    #define COUNT(val) COUNT = val
    #include "fibs.inl"
    #undef COUNT
    #undef FIB
    };
    
    std::array<ull, static_cast<size_t>(fibs::COUNT)> const & fibs_values() {
      static std::array<ull, static_cast<size_t>(fibs::COUNT)> values = {
    #define FIB(i, val) val,
    #define COUNT(val)
    #include "fibs.inl"
    #undef COUNT
    #undef FIB
      };
      return values;
    }
    // main.cpp
    #include "fibs.h"
    #include <iostream>
    
    int main() {
      using namespace std;
      for (auto fib : fibs_values()) {
        cout << fib << "," << endl;
      }
      return 0;
    }
    // fibs.inl = gen.exe > fibs.inl
    // gen.cpp
    #include "fib.h"
    #include <iostream>
    
    int main() {
      using namespace std;
      size_t i;
      for (i = 0; i < 94; i++) {
        cout << "FIB(" << i << ", " << fib(i) << ")" << endl;
      }
      cout << "COUNT(" << i << ")";
      return 0;
    }

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

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

    • Когда Брендан Айк хотел внести в Java Script очередную фичу, Расмус Лердорф говорил: «Если тебе нужен PHP, ты знаешь, где его взять.» Видимо, автор кода не знал, где взять PHP.
      Ответить
      • JS и PHP появились в одном году, в 1995
        Ответить
      • Изначально вроде как цитата была про K&R и Сиплюструпа.
        Ответить
        • Когда Керниган хотел внести фичу в С, Ричи отвечал "если тебе нужен С++ ты знаешь где его взять"? Но как, С++ же еще не было!
          Ответить
          • Когда Вирт хотел убрать из Модулы очередной сахар, Урбан Мюллер сказал "если тебе нужен брейнфак ты знаешь где его взять".
            >> Но как, С++ же еще не было!
            Открою страшную тайну: язык развивается и периодически появляются новые версии стандарта. Вот уже С11. K&R успели увидеть в какое чудовище превратились кресты.
            Ответить
            • и ведь убрал же!
              Ответить
            • Насчет выделенного белым - конечно меняется, они еще успели удивиться когда вместо их стиля объявления функций появились какие-то h-файлы с прототипами. Но развитие языка они вроде уже не определяли, так что добавлять фичи оглядываясь на С++ не могли.
              Ответить
          • „Однажды в беседе о конструировании самолётов, писатель, искатель приключений, художник и авиаинженер Антуан де Сент-Экзюпери подчеркнул: «Совершенство достигается не в тот момент, когда более нечего добавить, а тогда, когда нечего более удалить».

            Ритчи и Томпсон жили по этому принципу. Долгое время после того как ресурсные ограничения на ранних Unix-программах были смягчены, они работали над тем, чтобы поддерживать С в виде настолько тонкого уровня над аппаратным обеспечением, насколько это возможно.

            Когда я просил о какой-либо особенно экстравагантной функции в С, Деннис обычно говорил мне: «Если тебе нужен PL/I, ты знаешь, где его взять». Ему не приходилось общаться с каким-либо маркетологом, утверждающим: «На диаграмме продаж нам нужна галочка в рамочке!»“
            Ответить
            • Ответить
            • Из той же книги.
              Компактность — свойство, которое позволяет конструкции поместиться в памяти человека. Для того чтобы проверить компактность, используем тест:нуждается ли обычно опытный пользователь в руководстве для работы с данной программой. Если нет, то конструкция (ее подмножество, которое охватывает обычное использование) является компактной.
              Компактные программные средства обладают всеми достоинствами удобных физических инструментов. Их приятно использовать и они не препятствуют работе.
              Компактность-не синоним слабости. Конструкция может обладать мощностью и гибкостью, оставаясь при этом компактной, если она построена на абстракциях, которые просты в осмыслении и хорошо взаимосвязаны. Компактность не эквивалентна "простоте обучения". Некоторые компактные конструкции являются весьма сложными для понимания до тех пор, пока пользователь не овладеет основополагающей концептуальной моделью настолько, что его мировоззрение изменится, благодаря чему компактность станет для него простой.

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

              Очень немногие программные конструкции являются компактными, однако многие являются полукомпактными . Они имеют подмножество возможностей, подходящее для решения >=80% типичных задач. На практике для таких конструкций обычно требуется памятка, но не руководство.

              Библиотека С включает в себя сотни входных точек, которые не поместятся в памяти программиста.
              Статья Magical Number Seven, Plus/Minus Two показывает, что количество дискретных блоков информации, которое человек способен удерживать в краткосрочной памяти, равно 7±2. Из этого следует хорошее правило для оценки компактности API-интерфейсов: необходимо ли помнить более семи входных точек?
              Среди универсальных языков программирования С и Python являются полукомпактными, a Perl, Java, Emacs Lisp и shell — нет.
              С++ — антикомпактный язык — его разработчик признал, что вряд ли какой-либо один программист когда-нибудь поймет его полностью.
              Ответить
              • в shell-то чего такого некомпактного?
                Ответить
                • Пришлось вырезать несущественные части цитаты из-за оверквотинга .
                  особенно ввиду того, что серьезное shell-программирование требует от разработчика знаний нескольких других средств, таких как sed и awk
                  Ответить
              • Зато можно выделить в С++ компактное подмножество, пригодное для написания программ, такое, что не существует более компактного подмножества С, пригодного для написания подобных программ.
                Ответить
                • точная нижняя грань?
                  Степанов на лекции в яндексе в 2011 году о подобном говорил, когда пиарил свою тоскливую Elements of Programming. Типа он плюсов не знает, пишет самые примитивные конструкции.
                  Ответить
                  • Нас на лекциях учили, что код чаще читается, чем пишется. Так вот, если ты не используешь лишние конструкции, это не значит, что тебе не придется читать код, в котором они есть.
                    Ответить
                    • везучий
                      вас ещё полезному чему-то учили.
                      Ответить
                      • А у вас не учат? Скажите, как сейчас выглядит обучение IT в вузах экс-ссср?
                        Ответить
                    • > код чаще читается
                      Программист - творец, компилятор - критик.
                      Ответить
                      • Критик - программист же, а компилятор - проверка синтаксиса, рачок.
                        Ответить
              • его разработчик признал, что вряд ли какой-либо один программист когда-нибудь поймет его полностью.
                вывод ц ++ изучать можно бесконечно долго. Т.е. дзена не постичь, а оно нада?
                Ответить
                • в любой профессиональной области невозможно знать 100%
                  и да, всё тщетно, мы все умрём
                  Ответить
                  • Есть айкидо, где нужно учиться 8 лет, чтобы что-то из себя представлять, а есть АРБ. Есть протоссы в Starcraft 1, а есть терры и зерги - в топах статистика похожая, а вот в низах, говорят, протосси имба.
                    Ответить
                    • допустим, ты достиг просветления, получил мсмк и "знаешь" "единоборство" на 100% - каковы твои шансы, что ты не отхватишь насмерть ломом в подъезде?

                      спроецируй на многогранность профессиональной области "разработка ПО"

                      кому интересно посмотреть свое знание в попугаях - на брейнбенче вполне показательные тесты. где при этом 100 баллов знания синтаксиса нихуя не помогут в написании идеальной программы с идеальной рахитектурой

                      не найдешь человека, который на 100% знает "разработку ПО", имеет опыт и навык и понимание абсолютно всех подводных камней одновременно в разработке ПО для микроконтроллеров, телефонов, десктопов, серверов, кластеров, умеет работать максимально эффективно с любой субд и даже напишет свою, перепишет ядро ос, доработает драйвер видеокарты, напишет компилятор, разработает новый алгоритм сортировки, а затем сделает с нуля опенофис, пакет нелинейного видеомонтажа, распознавание лиц, предсказание курса валют и непобедимого биржевого робота, управление ядерным щитом страны и твд, шахматного монстра, гуглопоиск...
                      а потом скажет, что это был скучный вторник и c++ ему надоел
                      Ответить
                      • > каковы твои шансы, что ты не отхватишь насмерть ломом в подъезде?
                        Гораздо лучше, чем без этого.

                        Есть вещи более простые, а есть более сложные. Неужели это так тяжело понять?
                        Ответить
        • нет, K&R и PL/1
          Ответить
          • Ну никто ведь не будет спорить, что при замене PL/1 на С++ цитата начинает звучать очень злободневно.
            Ответить
            • Очень символично заменить Паладина в блестящих латах на рытьцаря-Крестаносца в белой мантии.
              Ответить
    • Паrни, а вот если объективно, может крестокод перед компиляцией через PHP прогонять, если много кодогенерировать?
      Ответить
      • Через m4, он укуренней, а значит круче ;)
        Ответить
        • Для промышленного может лучше пхп? Всё-таки проверенный временем инструмент кодогенерации.
          Ответить
          • m4 тоже проверенный (все никсовые configure им сгенерены), да еще и более старый ;)
            Ответить
            • В m4 даже циклов нет, их приходится эмулировать через рекурсивный вызов функции. Поэтому чтобы было красиво, придётся использовать препроцессор для самого m4.
              Ответить
              • > В m4 даже циклов нет, их приходится эмулировать через рекурсивный вызов функции.
                В эрланге тоже нет циклов, и ничего, пишут. А тут даже макрос для цикла можно замутить.

                > использовать препроцессор для самого m4.
                Да вроде бы не надо юзать препроцессор для самого м4, достаточно рекурсивный макрос поюзать.
                Ответить
                • Недавно узнал, как организовывать циклы в mysql без хранимок. Можно, конечно, сделать вложенные запросы с переменными... а можно и без переменных.

                  Чтобы сделать цикл без переменных, нужно пробежать селектом по таблице, содержащей все натуральные (целые) числа. А чтобы получить псевдотаблицу всех натуральных (целых) чисел, нужно читать далее >>>
                  http://use-the-index-luke.com/blog/2011-07-30/mysql-row-generator
                  Ответить
              • если мыслить сугубо в рамках машины тьюринга, но да, отсутствие циклов - это ужасно. А с точки зрения лямбда исчисления - каких циклов?)
                Ответить
          • А что, мне понравилась идея с PHP :) Треугольные скобки шаблонов так красиво сочетаются с пыховскими...
            <?php for ($i=0; $i<20; ++$i) { ?>
                template <<?php $a=array(); for ($j=0; $j<=$i; ++$j) $a[] = "class T$j"; echo implode(', ', $a); ?>>
                void test(<?php $a=array(); for ($j=0; $j<=$i; ++$j) $a[] = "T$j arg$j"; echo implode(', ', $a); ?>) {
                    <?php for ($j=0; $j<=$i; ++$j) { ?>
                    std::cout << <?php echo "arg$j" ?>;
                    <?php } ?>
                }
            <?php } ?>
            Ответить
            • Больше ёлочек!
              <?php $s = array('cout', 'cerr', 'clog'); ?>
              <?php for ($j = 0; $j < 5; $j++) { ?>
              for (int j = 0; j < BITS_IN_BYTE; j++) {
              <?php foreach ($s as $i) { ?>
              std::<?=$i?>>><?="arg$j"?>>>j>>endl;
              <?php } ?>
              }
              <?php } ?>
              Ответить
            • Идея совсем не новая. Я когда-то на ПХП генерировал ДАО классы для ЭкшнСкрипта.
              Ответить
          • Проверенный временем инструмент дегенерации.
            Ответить
    • Кстати парни, проблема в функциональных языках (да и вообще в языках) всё ещё есть, что нужно всегда писать хвостовую рекурсию? Язык не важен - можно на любом. Хвостовая запись обычно сильно портит красоту кода. Как избавится от этого уродства? Какие формы записи ещё есть, которые в итоге с большой вероятностью будут развернуты в цикл компилятором? Правильно ли я понимаю, что если писать на хаскеле, то там больше способов избавления от рекурсии за счет лени и бесконечности списка? Например если я буду использовать только стандартные функции высшего порядка, то хвостовая рекурсия в подарок совершенно бесплатно, верное?
      Ответить
      • > Какие формы записи ещё есть, которые в итоге с большой вероятностью будут развернуты в цикл компилятором?
        ФВП ;) По крайней мере рекурсия будет инкапсулирована в реализацию этих ФВП.
        Ответить
      • Хвостовая рекурсия не типична для haskell. Она предполагает eager вычисления в цикле, когда все вычисления по умолчанию ленивы, часто удобнее использовать бесконечные списки и функции высшего порядка - память для вычислений будет выделяться по мере необходимости.
        В eager языках вроде Ocaml есть обычные циклы, типичная сишка. Но от этого языка меня воротит. Уж лучше на плюсах писать.
        В erlang нету циклов, только tail recursion и list comprehensions.
        В целом, да, стандартная библиотека языков с eager-вычислениями обычно предлагает HO-функции, скрывающие хвостовую рекурсию.
        Ответить
      • Какой вообще смысл взбираться на непостижимый уровень абстракции, чтобы уйти от низкоуровневых проблем.
        А потом с заоблачных вершин гадать о том куда и с какой вероятностью попадет кинутый сверху код? И никогда точно не угадаешь волю силы тяготения (компилятора или jit).

        Наверное стоит вспомнить заветы дедушки Кнута и писать как нравится. А допиливать уже по необходимости - с профилировщиком и ассемблерным выводом.
        Или писать на том же С++ и явно указывать что нужен цикл, а не рекурсия.
        guest
        Ответить

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