Higher order functions in C

后端 未结 8 1587
小鲜肉
小鲜肉 2020-12-05 19:31

Is there a \"proper\" way to implement higher order functions in C.

I\'m mostly curious about things like portability and syntax correctness here and if there are mo

相关标签:
8条回答
  • 2020-12-05 19:39

    It's very difficult to do in straight C. It's more possible in C++ (see functors tutorial or Boost's bind and function libraries). Finally, C++0x adds native support for lambda functions, which takes care for you of capturing in closure all of the variables that your funcion depends on.

    0 讨论(0)
  • 2020-12-05 19:39

    If you want to create higher order functions, don't use C. There are C solutions to your problem. They may not be elegant, or they may be more elegant that you realize.

    [Edit] I suggested that the only way to achieve this was to use a scripting language. Others have called me out on it. So, I'm replacing that suggestion with this: [/Edit]

    What are you trying to achieve? If you want to mimic closures, use a language that supports them (you can tie into Ruby, lua, javascript, etc through libraries). If you want to use callbacks, function pointers are ok. Function pointers combine the most dangerous areas of C (pointers and the weak type system), so be careful. Function pointer declarations are not fun to read, either.

    You find some C libraries using function pointers because they have to. If you're writing a library, maybe you need to use them, too. If you're just using them within your own code, you're probably not thinking in C. You're thinking in lisp or scheme or ruby or ... and trying to write it in C. Learn the C way.

    0 讨论(0)
  • 2020-12-05 19:42

    If you're keen on doing this in plain C, you need to remember to include the option to pass in a context pointer from the caller of the functor (the higher-order function) to the function passed in. This lets you simulate enough of a closure that you can make things work easily enough. What that pointer points to... well, that's up to you, but it should be a void* in the functor's API (or one of the many aliases for it, such as gpointer in the GLib world or ClientData in the Tcl C API).

    [EDIT]: To use/adapt your example:

    typedef gpointer (converter_func_type)(gpointer,PyObject *)
    
    gpointer converter_function(gpointer context_ptr,PyObject *obj)
    {
        int *number_of_calls_ptr = context_ptr;
        *number_of_calls_ptr++;
        // do som stuff and return a struct cast into a gpointer (which is a void *)
    }
    
    GList *pylist_to_clist(PyObject *obj, converter_func_type f, gpointer context_ptr)
    {
       GList *some_glist;
       for each item in obj
       {
           some_glist = g_list_append(some_glist, f(context_ptr,item));
       }
       return some_glist;
    }
    
    void some_function_that_executes_a_python_script(void)
    {
       int number_of_calls = 0;
       PyObject *result = python stuff that returns a list;
       GList *clist = pylist_to_clist(result, converter_function, &number_of_calls);
       // Now number_of_calls has how often converter_function was called...
    }
    

    This is a trivial example of how to do it, but it should show you the way.

    0 讨论(0)
  • 2020-12-05 19:43

    The big problem with implementing higher-order functions in C is that to do anything non-trivial you need closures, which are function pointers augmented with data structures containing local variables they have access to. Since the whole idea behind closures is to capture local variables and pass those along with the function pointer, it's hard to do without compiler support. And even with compiler support it's hard to do without garbage collection because variables can exist outside of their scope, making it hard to figure out when to free them.

    0 讨论(0)
  • 2020-12-05 19:46

    Technically, higher-order functions are just functions that take or return functions. So things like qsort are already higher-order.

    If you mean something more like the lambda functions found in functional languages (which is where higher order functions really become useful), those are quite a bit harder and can't be done naturally in current standard C. They're just not part of the language. Apple's blocks extension is the best candidate. It only works in GCC (and LLVM's C compiler), but they are really useful. Hopefully something like that will catch on. Here's a few relevant resources:

    • Apple's documentation on the feature (references some Apple-specific technologies and also addresses Objective-C, but the core block stuff is part of their extensionto C)
    • Here's a good intro on blocks
    • Cocoa for Scientists' overview of C blocks
    0 讨论(0)
  • 2020-12-05 19:51

    Practically any interesting higher order function application requires closures, which in C entails the laborous and error-prone routine of manually defining and filling struct function arguments.

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