Кресты / Говнокод #25009 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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
/*
https://habr.com/post/246009/

Это вторая статья в цикле «Теория категорий для программистов».

...

Я хотел бы сказать вам, что есть шаблон в стандартной библиотеке С++,
который принимает две функции и возвращает их композицию, но такого
нет.

Примечание переводчика: но такой не сложно написать на С++14 (я опускаю
тонны деталей владения и шаблонной магии для проверок, что эти функции
и тип аргумента действительно можно компоновать):
*/

template <typename T>
struct function_arg: public function_arg<decltype(&T::operator())> {};

template<typename ReturnType, typename Arg>
struct function_arg<ReturnType(Arg) const> {
	using type = Arg;
};

template<typename ClassType, typename ReturnType, typename Arg>
struct function_arg<ReturnType(ClassType::*)(Arg) const> {
	using type = Arg;
};

template<typename T>
using function_arg_t = typename function_arg<T>::type;

template<typename F, typename G>
auto compose(F&& f, G&& g) {
	return [f = std::forward<F>(f), g = std::forward<G>(g)]
		(function_arg_t<F>&& a) {return g(f(std::forward<function_arg_t<F>>(a)));};
}

Поэтому я за C++

Запостил: j123123 j123123, (Updated )

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

  • #include <stdio.h>
    #include <stdlib.h>
    
    float add1(int a)
    {
      return a+1.0;
    }
    
    float mul0_5(float a)
    {
      return a*0.5;
    }
    #define COMPOSE(f, g, arg_f, ret_g, funcname) ret_g funcname(arg_f in) {return g(f(in));}
    
    COMPOSE(add1, mul0_5, int, float, compose1)
    
    COMPOSE(atoi, compose1, const char *, float, compose2)
    
    
    int main()
    {
      printf("%f", compose2("1"));
      return EXIT_SUCCESS;
    }

    Поэтому я за C

    https://wandbox.org/permlink/NkjNP0ByGwPkd5yt
    Ответить
      • <?php
        
        function add1($a) {
        	return $a + 1;
        }
        
        function mul0_5($a) {
        	return $a * 0.5;
        }
        
        function COMPOSE($f, $g, $funcname) {
        	eval ("function " . $funcname . "(\$a) { return (" . $g . "(" . $f . "(\$a)));}");
        }
        
        
        COMPOSE("add1", "mul0_5", "compose1");
        COMPOSE("intval", "compose1", "compose2");
        
        printf("%f", compose2("1"));
        
        ?>
        Ответить
        • eval не нужен:
          <?php
          function COMPOSE($f, $g) {
            return function() use ($f,$g) {
              $args = func_get_args();
              return $g(call_user_func_array($f, $args));
            };
          }
           
          $compose1 = COMPOSE("add1", "mul0_5");
          $compose2 = COMPOSE("intval", $compose1);
           
          printf("%f", $compose2("1"));


          https://ideone.com/E41a8q
          Ответить
          • А ещё можно так:
            function COMPOSE($f, $g, $funcname) {
              $GLOBALS[$funcname] = function() use ($f,$g) {
                $args = func_get_args();
                return $g(call_user_func_array($f, $args));
              };
            }
            Ответить
            • Согласен. Оригинальный пример j123123 основан на использовании препроцессора. Значит, при переводе нужно тоже использовать препроцессор. Например, написа́ть программу на "PHP", которая генерирует программу на "PHP".
              Ответить
              • Не могу полностью согласиться. Всё же используемый для решения задачи инструмент — вторичен, а первичными можно считать побочные эффекты. Основной побочный эффект оригинального примера — создание в глобальной области видимости функций compose1 и compose2 с соответствующим функционалом. Поэтому приведённый j123123 перевод можно считать точным.
                Ответить
                • Понял. Я создавал переменные, хранящие замыкания, из-за чего при использовании мне приходилось их выделять явно знаком $.

                  Ну тогда чтобы создать что-нибудь в контексте функций (чтобы потом не использовать баксы), придётся использовать eval или create_function (которая фактически вызывает eval).
                  Ответить
    • компилю программку типа хелоу ворлд на С++ c использованием Boost уже 2а часа к ряду - все еще тянет депенденси а obj ки уже засрали весь мой SSD что я делаю не так?
      Ответить
  • : 1.0+
      [ 1 S>F FLITERAL ] S>F F+
    ;
    
    : 0.5*
      [ S" 0.5" >FLOAT DROP FLITERAL ] F*
    ;
    
    : COMPOSE
       >R >R : R> COMPILE, R> COMPILE, POSTPONE ;
    ;
    
    ' 1.0+ ' 0.5* COMPOSE COMPOSE1
    ' EVALUATE ' COMPOSE1 COMPOSE COMPOSE2
    
    S" 83" COMPOSE2 F.


    https://ideone.com/nU8tUC
    Ответить

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

Переведи на "PHP", guest!

    А не использовать ли нам bbcode?


    8