LINUX.ORG.RU

История изменений

Исправление MOPKOBKA, (текущая версия) :

С расширениями можно чуть красивее написать код на Си.

#include <stdio.h>
#include <stdlib.h>
#include <Block.h>

#define lambda(arg, body) Block_copy(^arg { body; return (void**)NULL; });
#define call(f, ...) ((void **(^)())(*f))(__VA_ARGS__)
#define let(name, value) void **name = malloc(sizeof(void*)); *name = (void*)value;

int main()
{
  let (print_sum, lambda((int x), {
      let(make, lambda((int acc), {          
          let(f, lambda((int y), {
              printf("acc(%d) + %d\n", acc, y);
              return call(make, acc + y);
            }));
          return f;
        }));
      return call(make, x);
    }));
  
  call(call(call(call(print_sum, 10), 20), 30), 40);
}
$ clang -fblocks main.c -lBlocksRuntime
$ ./a.out 
acc(10) + 20
acc(30) + 30
acc(60) + 40

Исправление MOPKOBKA, :

С расширениями можно чуть красивее написать код на С.

#include <stdio.h>
#include <stdlib.h>
#include <Block.h>

#define lambda(arg, body) Block_copy(^arg { body; return (void**)NULL; });
#define call(f, ...) ((void **(^)())(*f))(__VA_ARGS__)
#define let(name, value) void **name = malloc(sizeof(void*)); *name = (void*)value;

int main()
{
  let (print_sum, lambda((int x), {
      let(make, lambda((int acc), {          
          let(f, lambda((int y), {
              printf("acc(%d) + %d\n", acc, y);
              return call(make, acc + y);
            }));
          return f;
        }));
      return call(make, x);
    }));
  
  call(call(call(call(print_sum, 10), 20), 30), 40);
}
$ clang -fblocks main.c -lBlocksRuntime
$ ./a.out 
acc(10) + 20
acc(30) + 30
acc(60) + 40

Исходная версия MOPKOBKA, :

С расширениями можно чуть красивее.

#include <stdio.h>
#include <stdlib.h>
#include <Block.h>

#define lambda(arg, body) Block_copy(^arg { body; return (void**)NULL; });
#define call(f, ...) ((void **(^)())(*f))(__VA_ARGS__)
#define let(name, value) void **name = malloc(sizeof(void*)); *name = (void*)value;

int main()
{
  let (print_sum, lambda((int x), {
      let(make, lambda((int acc), {          
          let(f, lambda((int y), {
              printf("acc(%d) + %d\n", acc, y);
              return call(make, acc + y);
            }));
          return f;
        }));
      return call(make, x);
    }));
  
  call(call(call(call(print_sum, 10), 20), 30), 40);
}
$ clang -fblocks main.c -lBlocksRuntime
$ ./a.out 
acc(10) + 20
acc(30) + 30
acc(60) + 40