Easy way to apply a function?

Sep 9, 2010 at 11:39 AM

I'm working on getting a language moved over to the DLR slowly, piece by piece (Scheme). I find myself with an (object) function, and any number of (object) arguments. 

I found that I can use the Invoke method of Runtime.Operations, like so:

runtime.Operations.Invoke(func);

runtime.Operations.Invoke(func, arg1);

runtime.Operations.Invoke(func, arg1, arg2);

However, that has a limit of using between 0 and 2 arguments. Also, it doesn't take params-type parameter option, so I find I need to call each of the above depending on the argument count.

Is there an easy way to call these functions using a part of the DLR or reflection?

Thanks for any pointers,

-Doug

Sep 9, 2010 at 5:11 PM

Do you have the latest DLR binaries? Invoke taking any number of parameters is available there:
public dynamic Invoke(object obj, params object[] parameters)

You can download them from IronRuby or IronPython Codeplex sites:

http://ironruby.codeplex.com/releases/view/43540

http://ironpython.codeplex.com/releases/view/42434

 

Sep 9, 2010 at 7:01 PM

Great! However, I'm using the most recent that I can use, and it must not support that.

Is there an alternate method of function invoking that works on DLR 0.9?

-Doug

 

Sep 9, 2010 at 8:27 PM

How exactly do you use these APIs? Do you have a host app that needs to invoke some objects?

Sep 9, 2010 at 9:51 PM

Yes, I have some Python and Ruby functions (and other callables) and values, and I would like to be able to reach in from Scheme and apply the functions. Once Scheme is a full-fledged DLR language, it won't be an issue, but just trying to make a hybrid version for now.

Something like this currently:

public static object clr_apply(object proc, object args) {
    int len = (int) length(args);
    if (len == 0) {
        return _dlr_runtime.Operations.Invoke(proc);
    } else if (len == 1)
        return _dlr_runtime.Operations.Invoke(proc, list_ref(args, 0));
    else if (len == 2)
        return _dlr_runtime.Operations.Invoke(proc, list_ref(args, 0), list_ref(args, 1));
}

-Doug

 

Sep 9, 2010 at 10:07 PM

So you're emitting an expression tree that calls clr_apply for applications written in Scheme? If so I would suggest using Expression.Dynamic instead.

Alternatively, you can copy code from http://github.com/ironruby/ironruby/blob/master/Runtime/Microsoft.Scripting/Runtime/DynamicOperations.cs and implement Operations.Invoke with params array on your own.

Sep 9, 2010 at 10:56 PM
TomasMatousek wrote:

So you're emitting an expression tree that calls clr_apply for applications written in Scheme? If so I would suggest using Expression.Dynamic instead.

Alternatively, you can copy code from http://github.com/ironruby/ironruby/blob/master/Runtime/Microsoft.Scripting/Runtime/DynamicOperations.cs and implement Operations.Invoke with params array on your own.

None of this Scheme's internals use the DLR yet. The first step is to be able to access the DLR global environment. Done. Next, be able to invoke DLR functions.(I'm not sure if this Scheme will ever evolve into a fast, stable system, but it is a good project for learning the ins and outs of the DLR. This Scheme was written in Scheme, and then automatically translated through a series of transformations into CSharp. It implements proper recursive tail calls and so it contains its own infrastructure for executing code paths. It is currently probably about 1.5 magnitudes slower than similarly written Iron Python code. But there are some obvious speed ups to make, so who knows!)

At this point, I will probably wait on C.J.'s team getting DLR 1.0 ready.

Thanks again!

-Doug