How does F# inline work?
With F# it is my understanding that you can use the inline keyword to perform type specialization at the call site. That is::
val inline (+) : ^a -> ^b -> ^c
when (^a or ^b) : (static member (+) : ^a * ^b -> ^c)
Constrains that ^a
or ^b
must have a static member like op_Addition
, or one of the built in primitives, that can be used to fill in the gap.
So if you have a method that has a + and you pass in an int and a short as parameters it unwraps + to an instruction to use the built in primitive for int, and if you pass in a float and a byte it uses the float primitive addition opcode.
How exactly is this done at compile time? How can you have a method in the CLR that switches what opcode or method it uses based on the type?
Is this behavior possibl开发者_如何学Goe with Reflection.Emit? I understand that the inlining is performed at the call-site, does that mean that the code does not work with C#?
As suggested by inline
, the code is inlined at the call site. At every call site, you know the concrete type parameter ^T
, so the specific code for that type is inserted there.
This is done by the F# compiler, you can't easily do it in other context (like C# or Ref.Emit).
The F# library has some inline functions that can still be called by other languages, the runtime for those implementations does dynamic dispatch based on the runtime type, see e.g. the code for AdditionDynamic
in prim-types.fs
in the F# Core library code to get a feel.
精彩评论