What tools are there for functional programming in C?

后端 未结 13 812
长情又很酷
长情又很酷 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 17:58

    Hartel & Muller's book, Functional C, can nowadays (2012-01-02) be found at: http://eprints.eemcs.utwente.nl/1077/ (there is a link to PDF version).

    0 讨论(0)
  • 2021-01-29 18:00

    You can use GCC's nested functions to simulate lambda expressions, in fact, I have a macro to do it for me:

    #define lambda(return_type, function_body) \
      ({ \
        return_type anon_func_name_ function_body \
        anon_func_name_; \
      })
    

    Use like this:

    int (*max)(int, int) = lambda (int, (int x, int y) { return x > y ? x : y; });
    
    0 讨论(0)
  • 2021-01-29 18:00

    Functional programming is not about lambdas, it is all about pure functions. So the following broadly promote functional style:

    1. Only use function arguments, do not use global state.

    2. Minimise side effects i.e. printf, or any IO. Return data describing IO which can be executed instead of causing the side effects directly in all functions.

    This can be achieved in plain c, no need for magic.

    0 讨论(0)
  • 2021-01-29 18:00

    What is it about C that you want to make functional, the syntax or the semantics? The semantics of functional programming could certainly be added to the C compiler, but by the time you were done, you'd essentially have the equivalent of one of the existing functional languages, such as Scheme, Haskell, etc.

    It would be a better use of time to just learn the syntax of those languages which directly support those semantics.

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2021-01-29 18:06

    The Felix language compiles to C++. Maybe that could be a step stone, if you don't mind C++.

    0 讨论(0)
提交回复
热议问题