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 possible 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#?
The slope of a linear function is calculated by rearranging the equation to its general form, f(x) = mx + c; where m is the slope. The vertex of a quadratic function is calculated by rearranging the equation to its general form, f(x) = a(x – h)2 + k; where (h, k) is the vertex.
more ... A special relationship where each input has a single output. It is often written as "f(x)" where x is the input value.
The domain of a function The function f(t)=(t,t2) is defined over all real numbers R, i.e., the domain of the function is R. Sometimes a function of one variable may be defined over a subset of real numbers, say some set U⊂R; in this case, the domain of the function is U.
We can then define a function that maps every point x to the value of the derivative of f at x. This function is written f′ and is called the derivative function or the derivative of f. Sometimes f has a derivative at most, but not all, points of its domain.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With