Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Operator (-) used in F# raises Specified method is not supported exception from C#

Tags:

c#

mono

f#

c#-to-f#

I have this generic function in F# that uses (-) operator:

let inline sub a b = a - b

Now I'm calling this function from C#:

int a = sub<int, int, int>(4, 1);

This raises an error:

Unhandled Exception: System.NotSupportedException: Specified method is not supported. at ProjA.MainClass.Main (System.String[] args) [0x00000] in <4f209fa43741462db3b8f73ac83c35a2>:0 [ERROR] FATAL UNHANDLED EXCEPTION: System.NotSupportedException: Specified method is not supported. at ProjA.MainClass.Main (System.String[] args) [0x00000] in <4f209fa43741462db3b8f73ac83c35a2>:0

Please note that this works fine for (+) operator or without the inline keyword.

1) Am I doing something wrong or is this a bug?

2) Is there any way to overcome this issue (but I need the inline keyword to make this function generic)?

3) Have you experienced something similar when calling f# function from c#, how did you solve it?

I'm using Mono 4.8 on macOS Sierra.

like image 544
mateuszlewko Avatar asked Nov 28 '16 18:11

mateuszlewko


People also ask

What is the symbol for F sharp?

F♯ (F-sharp; also known as fa dièse or fi) is the seventh semitone of the solfège.

What is ___ operator in JavaScript?

JavaScript +_ operator: It is a combination of the variable with symbol underscore( _ ) and unary plus ( + ) operator, + operator converts the type of _ variable to Number type for further operation. Example: The variable “_” with string type is stored in variable “r” with “number” type.


1 Answers

In general, functions declared as inline will not be usable (or will not work the same as from F#) from other languages. They are replaced at the call site as a feature of the F# compiler, which is not supported by C# and other CLR languages. This is a significant advantage of F# over these other languages.

However, there are some exceptions. It is possible to write F# inline functions which perform dispatch based on the runtime type, which is then usable from C# and other languages. Typically, these will not get the same IL when used from C# as they do from F# for certain types (the specific handlers for primitive types will not be handled). This is why (+) works - you can see this in the code for the operator, where (+) calls AdditionDynamic<(^T),(^U),(^V)> x y. Note that (-) is missing the runtime dispatched version, and is explicitly marked as [<NoDynamicInvocation>], which is why it fails to work from C#.

This is effectively the same limitation in C# that has caused people to request things like IArithmetic (*using Internet Archive since it's been hidden in Connect) for many years. F# works around this via statically resolved type parameters, but this is a feature specific to F#, and will not work from C# and other languages. Wrapping the function through F# doesn't enable it in C#.

like image 129
Reed Copsey Avatar answered Sep 25 '22 09:09

Reed Copsey