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

    +1

    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
    constexpr int add(int a, int b) 
    {
        return a + b;
    }
    
    static_assert(1 |> add(2) == and(1, 2));
    
    FILE* file = fopen( “a.txt”, “wb” );
    if (file) {
        fputs(“Hello world”, file);
        file |> fseek(9, SEEK_SET);
        file |> fclose();
    }
    
    auto dangerous_teams(std::string const& s) -> bool {
        return s
             |> views::group_by(std::equal_to{})
             |> views::transform(ranges::distance)
             |> ranges::any_of([](std::size_t s){
                    return s >= 7;
                });
    }

    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2011r0.html

    какой C++)))

    Запостил: kcalbCube, 19 Февраля 2022

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

    • кто там у нас UCS хотел?
      Ответить
      • почему С++ только догоняют?
        Ответить
      • #define UFCS(arg,f,...) f(arg,##__VA_ARGS__)
        
        FILE* file = fopen("a.txt", "wb");
        if (file) {
            fputs("Hello world", file);
            UFCS(file, fseek, 9, SEEK_SET);
            UFCS(file, fclose);
        }
        Ответить
        • Поздравляю, ты изобрёл кривой invoke (только нахуя он в сишке? Это в крестах с указателями на члены ебаться приходится).
          Ответить
          • И чем этот "|>" лучше "invoke"? Если подумать, это какая-то бессмысленная синтаксиальная дрисня
            Ответить
    • Какой «D» )))

      Резанула глаза десятая строка, в которой нельзя вынести file.
      Ответить
      • int fputs_r(FILE* f, const char* str)
        {
            return fputs(c, str);
        }
        
        # modern C++, Ёпта
        using unique_file_t = std::unique_ptr<FILE, decltype(&fclose)>;
        auto file_guard = unique_file_t(fopen( “a.txt”, “wb” ), &fclose);
        if ( FILE* file = file_guard .get() ) {
            file |> fputs_r("Hello World");
            file |> fseek(9, SEEK_SET);
            file |> fclose();
        }
        Починил
        Ответить
        • Русский народ очень дружелюбный и многонациональный
          Ответить
        • ну что за анскилл, надо через bind
          Ответить
        • Проебался. fclose нельзя вызывать с NULL. Нужно добавить:
          else {
              file_guard.reset();
          }

          И fclose удалить из if.
          Ответить
        • Надо ещё сделать функции, которые возвращают свой первый аргумент. Тогда можно реализовать флюент-интерфейс:
          FILE* fputs2(FILE* f, const char* str) {
              fputs(str, f);
              return f;
          }
          FILE* fseek2(FILE* f, long offset, int origin) {
              fseek(f, offset, origin);
              return f;
          }

          И так далее. Тогда можно будет так:
          file |> fputs2("Hello World")
               |> fseek2(9, SEEK_SET)
               |> fclose();
          Ответить
          • Тогда мы теряем ошибки которые никто не проверяет. Нужно сделать проверку ошибок в функциях и кидать исключение.
            Ответить
            • Да. Либо добавить параметр, в котором будет возвращаться результат (но проверка результата разорвёт цепочку, так что уж лучше исключение).
              Ответить
            • Да и вообще, нахрена все эти дополнительные функции. Всё же в самом начале работало, просто автор анскильный:
              “Hello world” |> fputs( file);
              file |> fseek(9, SEEK_SET);
              file |> fclose();
              Ответить
            • нужен auto unifiedSafe(std::function<T, Args...> a, std::function<void, const T&> b) -> T
              будет возвращать функтор, что исполняет a, вызывает b с возвращенным значением от a и возвращает первый переданный аргумент
              Ответить
          • Именно поэтому я за "PHP".

            require(dplyr)
             
            foo = function(x, y, z) x + y + z
            bar = function(x, y) x + y
            pituz = function(x) x
             
            pituz(9) %>% bar(10) %>% foo(11, 12) %>% cat


            https://ideone.com/sWvrYg
            Ответить
            • Приведи реальный пример чего-нибудь, чего нет в «R».
              Ответить
              • Мы определенно для чего-то на этой планете завелись
                Ответить
                • Мы завелись, чтоб Кафку сделать былью.
                  Ответить
                  • Мы все должны заботиться о своем мозжечке, чтобы на улице не выглядеть идиотами
                    Ответить
    • Есть предложение по доработке.
      Ввести расширенную форму оператора |X#>, с необязательными Х и #
      Х — порядковый номер аргумента, в который нужно подставить выражение слева.
      # означает, что возвращаемое значение нужно отбросить и в качестве результата использовать значение выражения слева.
      Тогда строчки 10-12 можно записать как:
      file |2#> fputs(“Hello world”)
           |#>  fseek(9, SEEK_SET);
           |>   fclose();

      Я у мамы комитетчик
      Ответить
    • > fopen

      Эээ... Даже комитетчики не юзают свои стримы?
      Ответить
      • Так в стримах там >> и методы, на них не покажешь особо. Потому что если писать
        file |> mem_fn(&ofstream::close)();

        то читатели могут что-то заподозрить.
        Ответить
    • Кстати, а его можно перегружать?
      Ответить
      • нельзя.

        This paper proposes a new non-overloadable operator |> such that the expression x |> f(y) evaluates exactly as f(x, y). There would be no intermediate subexpression f(y).

        This is notably unrelated to, and quite different from, [P1282R0], which proposed an overloadable operator|>, allowing the evaluation of the above expression as operator|>(x, f(y)).
        Ответить
        • Жаль, а то можно было бы монады замутить.
          Ответить
        • Так это не первое предложение оператора |> ?
          Ответить
          • конечно. в P1282R0 было такое:
            template<typename T, typename E, typename L>
            auto map(std::expected<T, E> const& ex, L const& fun)
              -> expected<decltype(fun(*ex)), E> {
                if (ex) { return fun(*ex); }
                return std::make_unexpected(ex.error());
            }
            
            template<typename T, typename E, typename L>
            expected<T, E> join (expected<T, E> const& ex, L const& fun) {
              if (ex) { return *ex; }
              return std::make_unexpected(ex.error());
            }
            
            template<typename T, typename E, typename L>
            auto and_then( expected<T, E> const& ex, L const& fun) {
                return join(map(ex,fun));
            }
            
            namespace infix {
            
            template<typename T>
            struct map {
                T t;
                map(T const& t) : t(t) {}
            };
            
            template<typename T>
            struct and_then {
                T t;
                and_then(T const& t) : t(t) {}
            };
            
            template<typename T, typename E, typename L>
            auto operator|>(std::expected<T, E> const& ex, map const& fun) {
                return ::map(ex, fun.t);
            }
            
            template<typename T, typename E, typename L>
            auto operator|>(std::expected<T, E> const& ex, map const& fun) {
                return ::and_then(ex, fun.t);
            }
            }
            std::expected<int, string> divide (int numerator, int denominator) {
              if (denominator == 0) { return std::make_unexpected( "divide by zero" ); }
              return numerator / denominator;
            }
            
            std::expected<int, std::string> to_int(std::string const& s) {
              if (s.empty()) { return std::make_unexpected("string was empty"s); }
              int i;
              auto result = from_chars(&s.front(), &s.back(), i);
              if (result.ec or result.ptr != &s.back()) {
                return std::make_unexpected("string did not contain an int"s);
              }
              return i;
            }
            
            int main() {
              using namespace infix;
              auto result = 
                to_int("12")
                |> and_then([] (int i) { return divide(42, i ); })
                |> map([] (double d) { return d * 2; });
            ...
            }
            Ответить

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