For example, I have 2 additive functions:
module Add
let add2 a =
let innerFn a = a + 2
innerFn a
let add2' a =
let innerFn' () = a + 2
innerFn' ()
let res1 = add2 0
let res2 = add2' 1
From what I known, both innerFn
s will be compiled to FSharpFunc<int,int>
and FSharpFunc<unit,int>
respectively, and will be initialized everytime the add2
or add2'
is called.
How can I rewrite the code to transform them to static local functions of the static class (thus no FSharpFunc initialization), like in C# 7?
You probably don't have to worry about this. In a Debug build, every local function becomes a delegate. In a Release build, the functions are either inlined or do become static methods in the static class.
By building and decompiling the question's code in a Debug build, you get :
public static int add2(int a)
{
return 5 + (new Program.innerFn@5()).Invoke(a);
}
public static int add2'(int a)
{
return (new Program.innerFn'@8(a)).Invoke(null);
}
Which does show a delegate initialization each time.
In Release though, this becomes :
public static int add2(int a)
{
return a + 2;
}
public static int add2'(int a)
{
return a + 2;
}
The functions were inlined and no delegate was generated.
To avoid indlining, I made add2
a bit more complex :
let add2 a =
let innerFn a = if a < 3 then a+1 else a + 2
5 + innerFn a
let add2' a =
let innerFn' () = a + 2
innerFn' ()
In this case, the Release build generated a static method in the class :
public static int add2(int a)
{
return 5 + Program.innerFn@5(a);
}
public static int add2'(int a)
{
return a + 2;
}
internal static int innerFn@5(int a)
{
if (a < 3)
{
return a + 1;
}
return a + 2;
}
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