4

I have a struct that takes a function pointer, like this:

typedef int (*node_transition_func)( wint_t );

typedef struct lex_dfa_arc_t {

    node_transition_func func;
    int expected_return_val;
    struct lex_dfa_node_t * node;

} LEX_DFA_ARC_T;

And now I want to create a function that returns a function of the prototype "int func( wint_c );" For example:

node_transition_func input_equals( wint_t input, wint_t desired ) { ... }

Is it possible in C to have the function above actually work? I'm trying to avoid having to define a function for each letter (e.g. input_equals_letter_a, input_equals_letter_b, input_equals_letter_c, etc).

My other approach would be to just have the node_transition_func take in a wint_t and a wchar_t* of desired characters, but I was curious if my first approach would work.

Thanks!

Scott
  • 10,407
  • 13
  • 37
  • 35
  • I wasn't aware of the term 'currying' until now, and I found this thread that explains a lot about it: http://stackoverflow.com/questions/1023261/is-there-a-way-to-do-currying-in-c – Scott Dec 13 '10 at 17:47

5 Answers5

4

You could basically emulate closures & currying by instead of "returning a function" you return a struct that has the function pointer plus the bound variables. With a couple of #defines it may even look halfway sane.

OTOH, when you use a particular language, you should stick to its idioms. Closures are not the strong point of C. I suggest that you don't try to be overly generic in C code, if in doubt just use a switch(){}.

Ferruccio
  • 98,941
  • 38
  • 226
  • 299
edgar.holleis
  • 4,803
  • 2
  • 23
  • 27
3

You cannot dynamically create new functions in C. Since it's a compiled language, and the compiler is not part of the standard runtime, all code must be statically defined at compile-time.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Actually that's not 100% true. You could have your own mini-compiler generate compiled code (maybe from pre-defined building blocks of compiled code), stick it in memory somewhere and then call it. Depending on kernel restrictions on use of memory of course. However if you want to write self-altering code, maybe another language like LISP might be more appropriate. – AlastairG Dec 13 '10 at 15:29
1

It looks like you're trying to do currying in C (cue clippy :-). I think this is technically possible in C. You're not trying to create new functions. You're trying to create alternative bindings to an existing function. It's pretty simple in C++, but without the syntactic sugar made possible by template metaprogramming (specifically functors and bindings), you would have to do all that stuff manually. Your other approach seems more reasonable.

Ferruccio
  • 98,941
  • 38
  • 226
  • 299
0

I'm guessing this function of yours would traverse a list of LEX_DFA_ARC_T and return the "func" member of a matching element?

There's no reason why that shouldn't work. After all a function pointer such as node_transition_func is still just a pointer. That said it may not be the best solution.

However I am a little confused as to whether my guess is correct because of the other things you say. Perhaps a little more context might help us answer you.

AlastairG
  • 4,119
  • 5
  • 26
  • 41
0

This might be the closest you can get to doing currying in C:

    int input_equals_with_type(wint_t Input, wint_t desired) {
        // Do some stuff with regard to different type of "desired"
        return 1;
    }

    #define MAKE_NODE_TRANS_FUNC(type, wint_t desired) \
        int node_transition_func_##type(wint_t input) { \
            return input_equals_with_type(input, desired); \
        }

    MAKE_NODE_TRANS_FUNC(letter_a, letter_a_disired)
    MAKE_NODE_TRANS_FUNC(letter_b, letter_b_desired)
    // and so on...

The limitation here is of course that this is not "real" currying since the functions are created at compile time, not run time. But if you are just trying to make a few types of functions then this works.

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
dividebyzero
  • 1,243
  • 2
  • 9
  • 17