Higher order functions in C

后端 未结 8 1608
小鲜肉
小鲜肉 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:57

    This is an answer to the question: how to compose functions in C, which is redirected here.

    You can create a data structure to implement a list data type. that structure can contain function pointers.

    #include
    #include
    
    typedef (*fun)();
    
    typedef struct funList { fun car; struct funList *cdr;} *funList;
    
    const funList nil = NULL;
    
    int null(funList fs){ return nil==fs; }
    
    fun car(funList fs)
    {
       if(!null(fs)) return fs->car; 
       else 
       {
         fprintf(stderr,"error:can't car(nil) line:%d\n",__LINE__);
         exit(1);
       }
    }
    
    funList cdr(funList ls)
    { if(!null(ls)) return ls->cdr; 
      else 
      {
        fprintf(stderr,"error:can't cdr(nil) line:%d\n",__LINE__);
        exit(1);
      }
    }
    
    funList cons(fun f, funList fs)
    {  funList ls;
    
       ls=(funList) malloc(sizeof(struct funList));
       if(NULL==ls)
       {
         fprintf(stderr,"error:can't alloc mem for cons(...) line:%d\n",__LINE__);
         exit(1);
       }
    
       ls->car=f;
       ls->cdr=fs;
    
       return ls;
    }
    

    we can write a function comp which applies a list of functions:

    type_2 comp(funList fs, type_1 x)
    {  
       return (null(fs)) ? x : car(fs)(comp(cdr(fs),x)); 
    }
    

    An example of how it works. We use (f g h) as a short notation for cons(f,cons(g,cons(h,nil))), which is applied to a given argument x:

    comp((f g h),x)
    

    =

    f(comp((g h),x))
    

    =

    f(g(comp((h),x)))
    

    =

    f(g(h(comp(nil,x))))
    

    =

    f(g(h(x)))
    

    if you had used the polymorphic list type in a typed language like SML or Haskell the type of comp should be:

    comp :: ([a -> a],a) -> a
    

    because in that context all the members in a list have the same type. C can be more flexible in this sense. Maybe something like

    typedef void (*fun)();
    

    or

    typedef (*fun)();
    

    you should see what the C manual say about this. And be sure that all contiguous functions have compatible types.

    The functions to compose should be pure, i.e. without side effects nor free variables.

提交回复
热议问题