Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to call Rx extension methods with lambdas from inside an IronPython script?

Can someone please explain me this really weird observation?

I've been trying to call Rx extension methods from inside IronPython and it is turning out to be simply impossible. I've boiled it down to this simple example:

import clr
clr.AddReference("System.Core")
from System.Linq import Enumerable

def process(value):
  return Enumerable.Select(value, lambda x:x)

In this case we start with normal LINQ. If I call the process function from my hosting environment with an array or any other IEnumerable object, it works totally fine.

So then I tried to simply replace the references to use the Observable extension methods like so:

import clr
clr.AddReference("System.Reactive.Linq")
from System.Reactive.Linq import Observable

def process(value):
  return Observable.Select(value, lambda x:x)

In this case, if I call the process function with an IObservable object, the call crashes with an ugly error message:

expected IObservable[object], got Select[int, int]

Has anyone hit upon something like this? Have I missed something? Is there some special case hack to make Enumerable work with lambda delegates that Observable is missing? I have to admit I'm completely baffled here.

By the way, just as a sanity check, the following example works just fine:

import clr
clr.AddReference("System.Reactive.Linq")
from System.Reactive.Linq import Observable

def process(value):
  return Observable.Sum(value)

I wanted to leave it out there just to make it clear that the problem really is in the method call to Observable.Select.

like image 398
glopes Avatar asked Jan 14 '17 16:01

glopes


1 Answers

Part of the problem I suspect is that the methods are overloaded. The IronPython runtime will do its best to find the best overload to use but it can get things wrong occasionally. You may have to help with the disambiguation of the overloads.

From the error message, it seems like you're trying to call it on an IObservable<int>. It seems like overload resolution is failing here and is trying to call it as Observable.Select<object, object>(). You'll need to provide some hints to what overload you want to use.

def process(value):
    return Observable.Select[int,int](value, Func[int,int](lambda x:x))
like image 156
Jeff Mercado Avatar answered Nov 15 '22 10:11

Jeff Mercado