I'm writing some extensions for the FunScript project (F# to Javascript compiler). If you're interested you can find the source here.
I was trying to emulate the AwaitObservable extension by Tomas Petricek. However, if I use overloaded methods like AwaitObservable(w), AwaitObservable(w1,w2)...
I get the following error when I try to compile a project to Javascript:
An unhandled exception of type 'System.Reflection.AmbiguousMatchException' occurred in FSharp.Core.dll
Additional information: Ambiguous match found.
FunScript keeps a cache dictionary of the reflected definitions in the project, and this error occurs when it tries to add a new one to the cache using Expr.TryGetReflectedDefinition
. The error disappears if I use different names instead of overloads (AwaitObservable2, AwaitObservable3...
). That's the workaround I'm using now, but I would like to know more about the problem and whether is possible to fix it so the users of the extensions can use overloaded methods normally.
I can imagine that Reflected Definitions in F# don't support overloaded methods and cannot distinguish methods just by the number of arguments (I couldn't check that because I didn't find the implementation of Expr.TryGetReflectedDefinition
in the fsharp GitHub source repository). However, what puzzles me is that the error doesn't happen when looking for AwaitObservable but the following method:
{System.IDisposable System-IObservable
1-Subscribe(System.IObserver
1[FunScript.TypeScript.MouseEvent])} System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}
So my questions are:
Expr.TryGetReflectedDefinition
failing with IObservable.Subscribe
instead of Async.AwaitObservable
?Expr.TryGetReflectedDefinition
throwing an exception instead of returning None?Thanks a lot in advance for your help!
Ok, it seems this has no easy answer so I'll try to reply my own question. After further investigation...
Async.AwaitObservable
overloads the stored Reflected Definitions somehow (this 'somehow' is what remains unexplained) lose track of the type implementing IObservable
, and that's why they do not know which implementation of Subscribe
should be used.None
means the Reflected Definition has not been found, but here there was an ambiguous match so it's a different case.CompiledName
attribute and giving a different name to each overload. Now everything works fine :)I hope next time I post a question that can actually be answered ;) Thanks to everybody who took the time to read this.