5

OK, so that's what I need :

  • Let's say we've got a string variable, e.g. func with some value, given by the user (not a constant)
  • How could we call a function which name is the value of func?

UPDATE:

Perhaps thought that what I needed was pretty self-explanatory, but since I'm noticing many downvotes, here you are :

string func = "myfunc";

I need something like call(func), which will call myfunc. Like PHP's call_user_func_array()


Any ideas?

I had a look at mixins but this doesn't look like what I'd need.


P.S. I'm tagging the question with c and c++ too, since a universal solution could be theoretically possible, given the similarities among the languages.

Antoine
  • 13,494
  • 6
  • 40
  • 52
Dr.Kameleon
  • 22,532
  • 20
  • 115
  • 223
  • 3
    The best way I can interpret your question is "how to call a function with a parameter". Which would be, `functionName(func)`. I guess this must not be what you're asking, so please clarify the question. – Vladimir Panteleev Mar 12 '14 at 17:41
  • Can you attempt to give an example? The wording of your question is very confusing. – Cory Kramer Mar 12 '14 at 17:42
  • 2
    @CyberShadow - I read it as "user enters a value into a string, that string is a function name, how do I call that function". – Mike Mar 12 '14 at 17:43
  • 3
    Make a hashtable of names => function pointers, look up the string in the table and call the result. – user3286380 Mar 12 '14 at 17:43
  • 1
    Oh... in that case, good luck! Especially in C++ since the function names are mangled – Cory Kramer Mar 12 '14 at 17:43
  • @Mike Yep, Mike got it right! That's what I need. Please refer to the update in the original question. :-) – Dr.Kameleon Mar 12 '14 at 17:44
  • While a "universal solution" may be possible, writing code to the commonalities is generally not going to be idiomatic in at least one of the languages (unless you want a pseudo-code *algorithm*. – crashmstr Mar 12 '14 at 17:45
  • @crashmstr Well, as inferred by the title, my primary language of interest is D and since I'm not yet that familiar with its peculiarities, I'm trying to verify that there is no such thing already built-in in the language. – Dr.Kameleon Mar 12 '14 at 17:46
  • 1
    check this answer http://stackoverflow.com/a/1118808/2549281 , but i guess it only work for `C`, and only for functions defined in your executable – Dabo Mar 12 '14 at 17:48
  • Perhaps you should try a move dynamic language such as Ruby, Javascript, or Python to name a few. All of these offer metaprogramming, which is what you're wanting to do. – Vortico Mar 12 '14 at 17:49
  • @Vortico I'm writing an interpreter. So using an... interpreted language as the basis of it is out of the question. ;-) – Dr.Kameleon Mar 12 '14 at 17:53
  • @Dabo Thanks, quite a useful one! ;-) – Dr.Kameleon Mar 12 '14 at 17:54
  • In that case, I'll offer an alternative solution I haven't seen on here. You could compile your named functions into a dynamic library and use [dlopen()](http://pubs.opengroup.org/onlinepubs/009695399/functions/dlopen.html), although name mangling in D may be an issue. You should use statically generated hash tables if you can though. – Vortico Mar 12 '14 at 21:58

6 Answers6

4

Programming languages generally do not provide a way to access function names during runtime, as those names are usually stripped out by the linker, leaving behind only machine code.

As user3286380 suggested, one way to tackle this problem, which would work in all languages, is to make a table which cross-references function names and pointers to the respective functions. Then, your program can look up this table during run time.

If the language in question allows introspection (either run-time or compile-time), you can enumerate the functions in your module or program, and find the function whose name the user entered. In D, you can do this by using the allMembers trait on a module. This will give you an array of all declarations in the module; the next step would be to filter out functions, check that the function signature matches, then generate a switch statement which calls the respective function. You can use CTFE and string mixins to achieve the above.

Vladimir Panteleev
  • 24,651
  • 6
  • 70
  • 114
  • Yep, that's the type of answer I expected! Thanks a lot! (I'm currently looking into it, and it looks like it *is* what I need; and imagine I thought I had gone through most of the documentation!...) – Dr.Kameleon Mar 12 '14 at 17:51
  • 1
    @Dr.Kameleon if you could put your function in a class, you could use `Object.factory` to create one and call the function on it (for D). – user3286380 Mar 12 '14 at 18:12
  • @user3286380 Hmm... I think I get what you mean. Rather interesting approach! ;-) – Dr.Kameleon Mar 12 '14 at 18:23
1

Create an array of pairs with the first element of each pair being the string function name and the second being the pointer to the function. Search the array and when the name is found, call it using the pointer. Note that Python has a dictionary class that enables you to do this as key:value pairs.

sabbahillel
  • 4,357
  • 1
  • 19
  • 36
  • For this kind of data structure, hash tables (`std::unordered_map` in C++, builtin in D, similar to Python's dict) or binary trees (`std::map` in C++) are much more effient than arrays of pairs. – Antoine Mar 12 '14 at 17:55
1

I see 3 ways of doing that:

  • If you know in advance a collection of functions from which to choose, you could register an associative table of string -> functor where functor records both the function address and signature, something like std::function in C++

  • Otherwise, a more complex solution is to inspect the debug symbols of your own executable and build your table from that. You could also use pre-processors (like Qt's MOC) to build this table, or in the case of D use the builtin compile-time reflexivity.

  • If you really need flexibility use an interpreter instead of a compiler. Cling is a nice LLVM based C++ interpreter with just-in-time compilation.

Antoine
  • 13,494
  • 6
  • 40
  • 52
1

The only way I've ever done this before was to have the functions in your executable be linked to a string that "names" that function, then do a comparison.

I thought I would throw on a simple (1 function) example in C for you, I have to assume this works in D as well:

typedef struct {
    char * func_name;
    void (* fptr)();
} myS;

void print(){
    printf("hello world\n");
}

int main()
{ 
    myS Ex;
    char str[100] = "";

    // Obviously you can fill these in a more intelligent manner, use an array, etc
    Ex.func_name = malloc(strlen("print")+1);
    strcpy(Ex.func_name, "print");
    Ex.fptr = print;

    printf("Enter the function name\n");
    scanf("%99s", str);

    // and of course with a number of functions to examine you could use a switch
    if(!strcmp(str, Ex.func_name))
        Ex.fptr();
    else
        printf("Didn't find a function to call\n");

    return 0;
}
Mike
  • 47,263
  • 29
  • 113
  • 177
0

The way I do is using associative arrays. An example would be:

module main;

import std.stdio;

class Tqfuncs{
private:
    void qwrite(string arg){
        write(arg);
    }
    void delegate(string)[string] pList;//store name & pointer to functions here
public:
    this(){
        pList = [
            "qwrite":&qwrite,//add the qwrite function
        ];
    }
    void call(string name, string arg){
        if (name in pList){
            pList[name](arg);//call the function
        }else{
            throw new Exception("unrecognized function call "~name);
        }
    }
}

void main(string[] args){
    Tqfuncs scrF = new Tqfuncs;
    scrF.call("qwrite","This will be written");
}

I've created a dynamic scripting language using this approach, you can know more using the source https://github.com/Nafees10/qscript .
However, there are some limits using this method:

  • All functions must be in a certain "format". Like I've used void functionName(string arg). But there is a workaround, if you're interested, you can check it in QScript (my project).
Nafees
  • 509
  • 4
  • 16
0

No - you do not need that in a statically-typed language! Period.

Why? - Because the compiler can't know ahead the value (changed at runtime) of the variable holding the name of the function you want to run so when it encounters funcname(myvar) what machine code should it generate there?

Imagine for a second what you want works:

string funcname;
// here some initialisation code that modifies the funcname
int someVal = funcall(funcname);

What happens when the funcall() gets a name of a function that returns, say, an object Person (a user-defined type)??

Also, what happens when there is no function with name funcname?? A runtime error? No error? What?

What you want is in the domain of dynamic languages where type-safety is entirely ignored (which is unfortunately most of them).

HOWEVER... If your functions are all wrapped in a struct for an example, then D provides an elegant way of doing what you want through the forwarding (function dispatch). Read more about it here: https://dlang.org/spec/operatoroverloading.html#dispatch

DejanLekic
  • 18,787
  • 4
  • 46
  • 77