chapel-lang / chapel

a Productive Parallel Programming Language
https://chapel-lang.org
Other
1.78k stars 418 forks source link

Call methods from method name in string #8326

Open marcoscleison opened 6 years ago

marcoscleison commented 6 years ago

We are coding a REST framework for Chapel. Our framework aims to route requests to methods in Controller classes. I would like to know if it is possible to call a method from an object from its name in a string using reflexion? Ex.

class Controller{
    proc index(){
       writeln("Hi Index");
  }
}

var method_name ="index";
var obj = new Controller();

call_method_from_name(obj,method_name);// this calls the method from its name inside string;

Thanks.

buddha314 commented 6 years ago

This ticket supports https://github.com/chapel-lang/chapel/issues/7884 and https://github.com/chapel-lang/chapel/issues/7584

mppf commented 6 years ago

The Reflection module doesn't have this capability today. It can query if a param method name is available, but not actually call it. The thing is, overload resolution happens at compile-time, and so it'd be hard to make something that used a run-time method name to decide which method to call. That said, it might be possible in limited cases. For example, if we had a way to call a method with a param name, one might be able to generate a function that tried calling all of the methods. But what if they have different argument types?

Probably the pattern I'd expect you to use is to use a base class with some set of functions on it & then overload to get dynamic typing.

buddha314 commented 6 years ago

I'm following this, too. Would you be able to be a bit more specific about the base class? I'm not sure what you mean.

mppf commented 6 years ago

So, in dynamically typed languages, there is some table somewhere that translates from method name -> method implementation. In a statically typed language like Chapel, the language doesn't provide such a table. If you want to have a table of methods, you'd have to implement it yourself.

At the same time, probably the safest way to create types that vary at run-time in Chapel is to use inheritance of classes. Here is an example:

class BaseHandler {
  // consider these as "pure virtual" functions
  proc name():string { halt("base name called"); }
  proc greet() { halt("base greet called"); }
}
class HelloHandler : BaseHandler {
  proc name():string { return "hello"; }
  proc greet() { writeln("Hello"); }
}
class CiaoHandler : BaseHandler {
  proc name():string { return "ciao"; }
  proc greet() { writeln("Ciao"); }
}

proc test() {
  // create an array of handlers
  var handlers:[1..0] BaseHandler;
  handlers.push_back(new HelloHandler());
  handlers.push_back(new CiaoHandler());

  // now dispatch to the right handler based upon string name
  var chosenHandler = "ciao";
  for h in handlers {
    if h.name() == chosenHandler {
      h.greet();
    }
  }
}

test();
mppf commented 6 years ago

BTW this comment might be relevant: https://github.com/chapel-lang/chapel/issues/7495#issuecomment-332646799