What tools are there for functional programming in C?

后端 未结 13 811
长情又很酷
长情又很酷 2021-01-29 17:18

I\'ve been thinking a lot lately about how to go about doing functional programming in C (not C++). Obviously, C is a procedural language and doesn\'t really support f

13条回答
  •  孤街浪徒
    2021-01-29 18:04

    Prerequisite for functional programming style is a first class function. It could be simulated in portable C if you tolerate next:

    • manual management of lexical scope bindings, aka closures.
    • manual management of function variables lifetime.
    • alternative syntax of function application/call.
    /* 
     * with constraints desribed above we could have
     * good approximation of FP style in plain C
     */
    
    int increment_int(int x) {
      return x + 1;
    }
    
    WRAP_PLAIN_FUNCTION_TO_FIRST_CLASS(increment, increment_int);
    
    map(increment, list(number(0), number(1)); // --> list(1, 2)
    
    
    /* composition of first class function is also possible */
    
    function_t* computation = compose(
      increment,
      increment,
      increment
    );
    
    *(int*) call(computation, number(1)) == 4;
    

    runtime for such code could be as small as one below

    struct list_t {
      void* head;
      struct list_t* tail;
    };
    
    struct function_t {
       void* (*thunk)(list_t*);
       struct list_t* arguments;
    }
    
    void* apply(struct function_t* fn, struct list_t* arguments) {
      return fn->thunk(concat(fn->arguments, arguments));
    }
    
    /* expansion of WRAP_PLAIN_FUNCTION_TO_FIRST_CLASS */
    void* increment_thunk(struct list_t* arguments) {
      int x_arg = *(int*) arguments->head;
      int value = increment_int(x_arg);
      int* number = malloc(sizeof *number);
    
      return number ? (*number = value, number) : NULL;
    }
    
    struct function_t* increment = &(struct function_t) {
      increment_thunk,
      NULL
    };
    
    /* call(increment, number(1)) expands to */
    apply(increment, &(struct list_t) { number(1), NULL });
    

    In essence we imitate first class function with closures represented as pair of function/arguments plus bunch of macroses. Complete code could be found here.

提交回复
热议问题