F# function is very different from normal CLR method because of currying support. For example function
let inc a = a + 1
Will have type Microsoft.FSharp.Core.FSharpFunc<int,int>. It creates problems with C# interoperability. Functions must be designed specially to be easily called from C#.
What is the rationale behind this design? I believe that the reason is currying support. But currying can be implemented using closures. For example this code:
let add a b = a + b
let inc = add 1
can be easily transformed into this by the compiler:
let add a b = a + b
let inc = fun x -> add 1 + x
both add and inc in this case can be normal System.Func objects. I believe that there is some interesting reasons behind this design decision.
As far as I remember, the motivation for having a separate type for functions in F# was performance (in earlier versions FSharpFunc<...> was actually called FastFunc<...>). I'm not entirely sure about the recent developments (I'm sure the F# team did some tests to find out whether delegates would work in Visual Studio 2010), but here is how I understood the problem:
If you have a function add : int -> int -> int then the function could be represented as a delegate Func<int, Func<int, int>> (using the curried representation). The problem is that very often you will want to call it with both parameters like add 1 2.
Using the representation with nested Func types, this would compile to add.Invoke(1).Invoke(2).
However, when compiling function like add, the F# compiler actually creates a new class, say, AddClass which inherits from FSharpFunc<int, FSharpFunc<int, int>> and adds an additional Invoke overload with two arguments. This means that, in most of the cases, add 1 2 can be compiled to just a single call add.Invoke(1, 2).
This design makes F# code faster. It complicates the interoperability slightly, but not too much. It is fairly easy to write an F# member or function that takes a delegate:
let foo (inc : Func<int, int>) = inc.Invoke(41)
(You just need to add type annotations and then call f.Invoke - but you can also use f.Inokve as a first-class value and pass it to other functions)
My guess is that the F# representation supports big step semantics whereas System.Func does not.
The best way to interop with C# is to wrap everything in class/members. C# never has to see the inner workings of the member.
Related
What's the advantage of having a type represent a function?
For example, I have observed the following snippet:
type Soldier = Soldier of PieceProperties
type King = King of PieceProperties
type Crown = Soldier -> King
Is it just to support Partial Application when additional args have yet to be satisfied?
As Fyodor Soikin says in the comments
Same reason you give names to everything else - values, functions,
modules, etc.
In other words, think about programming in assembly which typically does not use types, (yes I am aware of typed assembly) and all of the problems that one can have and then how many of those problems are solved or reduced by adding types.
So before you programmed with a language that supported functions but that used static typing, you typed everything. Now that you are using F# which has static typing and functions, just extend what you have been using typing for but now add the ability to type the functions.
To quote Benjamin C. Pierce from "Types and Programming Languages"
A type system is a tractable syntactic method for proving the absence
of certain program behaviors by classifying phrases according to the
kinds of values they compute.
As noted in "Types and Programming Languages" Section 1.2
What Type Systems Are Good For
Detecting Errors
Abstraction
Documentation
Language Safety
Efficiency
TL;DR
One of the places that I find named type function definitions invaluable is when I am building parser combinators. During the construction of the functions I fully type the functions so that I know what the types are as opposed to what type inferencing will infer they are which might be different than what I want. Since the function types typically have several parameters it is easier to just give the function type a name, and then use that name everywhere it is needed. This also saves time because the function definition is consistent and avoid having to debug an improperly declared function definition; yes I have made mistakes by doing each function type by hand and learned my lesson. Once all of the functions work, I then remove the type definitions from the functions, but leave the type definition as comments so that it makes the code easier to understand.
A side benefit of using the named type definitions is that when creating test cases, the typing rules in the named function will ensure that the data used for the test is of the correct type. This also makes understanding the data for the test much easier to understand when you come back to it after many months.
Another advantage is that using function names makes the code easier to understand because when a person new to the code looks at if for the first time they can spot the consistency of the names. Also if the names are meaningful then it makes understanding the code much easier.
You have to remember that functions are also values in F#. And you can do pretty much the same stuff with them as other types. For example you can have a function that returns other functions. Or you can have a list that stores functions. In these cases it will help if you are explicit about the function signature. The function type definition will help you to constrain on the parameters and return types. Also, you might have a complicated type signature, a type definition will make it more readable. This maybe a bit contrived but you can do fun(ky) stuff like this:
type FuncX = int -> int
type FuncZ = float -> float -> float
let addxy (x:int) :FuncX = (+) x
let subxy :FuncX = (-) x
let addz (x:float) :FuncZ =
fun (x:float) -> (fun y -> x + y)
let listofFunc = [addxy 10;addxy 20; subxy 10]
If you check the type of listofFunc you will see it's FuncX list. Also the :FuncX refers to the return type of the function. But we could you use it as an input type as well:
let compFunc (x:FuncX) (z:FuncX) =
[(x 10);(z 10)]
compFunc (addxy 10) (addxy 20)
There is need for tracing. The decorator should print function name, parameters values and return value. Instead of writing each time a decorator for each function, it would be terrific if it could be possible to do this programmatically.
The current function name can be discovered using reflection via MethodBase.GetCurrentMethod. Functions could be easily decorated with an inline function for logging:
let inline log args f =
let mi = System.Reflection.MethodBase.GetCurrentMethod()
let result = f ()
printf "%s %A -> %A" mi.Name args result
let add a b = log (a,b) (fun () -> a + b)
add 1 1
Which prints: add (1, 1) -> 2
EDIT: Another option would be to create a wrap function, i.e.:
let inline wrap f =
fun ps ->
let result = f args
printfn "%A -> %A" args result
result
let add (a,b) = a + b
wrap add (1,1)
However in this case there is not an easy way to programmatically retrieve the function name.
Yet another option might be to develop a Type Provider that takes an assembly path as a parameter and provides wrapped versions of all members.
I had the same desire previously and found that there are no current automated solutions for F#.
See: Converting OCaml to F#: Is there a simple way to simulate OCaml top-level #trace in F#
While OCaml's trace facility with time travel is the most useful debugging feature of comparison to what is desired, it is not an exact fit; but when I use OCaml it is the first inspection tool I use.
See: Using PostSharp with F# - Need documentation with working example
Also the suggestion of using AOP, i.e. PostSharp, was another good suggestion, as the response from Gael Fraiteur, the Principal Engineer of PostSharp points out:
PostSharp does not officially support F#.
Other than using reflection as suggested by Phillip Trelford, which I have not tried, the best solution I have found is to manually modify each function to be traced as I noted in Converting OCaml to F#: Is there a simple way to simulate OCaml top-level #trace in F# and save the results to a separate log file using NLog.
See: Using NLog with F# Interactive in Visual Studio - Need documentation
Another route to pursue would be check out the work of F# on Mono as there is a lot of work being done there to add extra tooling for use with F#.
Basically what I have found is that as my F# skills increase my need
to use a debugger or tracing decrease.
At present when I do run into a problem needing this level of inspection, adding the inspection code as noted in Converting OCaml to F#: Is there a simple way to simulate OCaml top-level #trace in F# helps to resolve my misunderstanding.
Also of note is that people who come from the C# world to the F# world tend to expect a debugger to be just as useful. Remember that imperative languages tend to be about manipulating data held in variables and that the debugger is used to inspect the values in these variables, while with functional programming, at least for me, I try to avoid mutable values and so the only values one needs to inspect are the values being passed to the function and no other values, thus reducing or obviating the need for a debugger or inspection beyond that of the function of question.
I'm started to learn F#, and I noticed that one of the major differences in syntax from C# is that type inference is used much more than in C#. This is usually presented as one of the benefits of F#. Why is type inference presented as benefit?
Imagine, you have a class hierarchy and code that uses different classes from it. Strong typing allows you quickly detect which classes are used in any method.
With type inference it will not be so obvious and you have to use hints to understand, which class is used. Are there any techniques that exist to make F# code more readable with type inference?
This question assumes that you are using object-oriented programming (e.g. complex class hierarchies) in F#. While you can certainly do that, using OO concepts is mainly useful for interoperability or for wrapping some F# functionality in a .NET library.
Understanding code. Type inference becomes much more useful when you write code in the functional style. It makes code shorter, but also helps you understand what is going on. For example, if you write map function over list (the Select method in LINQ):
let map f list =
seq { for el in list -> f el }
The type inference tells you that the function type is:
val map : f:('a -> 'b) -> list:seq<'a> -> seq<'b>
This matches our expectations about what we wanted to write - the argument f is a function turning values of type 'a into values of type 'b and the map function takes a list of 'a values and produces a list of 'b values. So you can use the type inference to easily check that your code does what you would expect.
Generalization. Automatic generalization (mentioned in the comments) means that the above code is automatically as reusable as possible. In C#, you might write:
IEnumerable<int> Select(IEnumerable<int> list, Func<int, int> f) {
foreach(int el in list)
yield return f(el);
}
This method is not generic - it is Select that works only on collections of int values. But there is no reason why it should be restricted to int - the same code would work for any types. The type inference mechanism helps you discover such generalizations.
More checking. Finally, thanks to the inference, the F# language can more easily check more things than you could if you had to write all types explicitly. This applies to many aspects of the language, but it is best demonstrated using units of measure:
let l = 1000.0<meter>
let s = 60.0<second>
let speed = l/s
The F# compiler infers that speed has a type float<meter/second> - it understands how units of measure work and infers the type including unit information. This feature is really useful, but it would be hard to use if you had to write all units by hand (because the types get long). In general, you can use more precise types, because you do not have to (always) type them.
Looking at the source in FSharp.Core and PowerPack, I see that a lot of higher-order functions that accept a function with two or more parameters use FSharpFunc.Adapt. For example:
let mapi f (arr: ResizeArray<_>) =
let f = FSharpFunc<_,_,_>.Adapt(f)
let len = length arr
let res = new ResizeArray<_>(len)
for i = 0 to len - 1 do
res.Add(f.Invoke(i, arr.[i]))
res
The documentation on FSharpFunc.Adapt is fairly thin. Is this a general best practice that we should be using any time we have a higher-order function with a similar signature? Only if the passed-in function is called multiple times? How much of an optimization is it? Should we be using Adapt everywhere we can, or only rarely?
Thanks for your time.
That's quite interesting! I don't have any official information (and I didn't see this documented anywhere), but here are some thoughts on how the Adapt function might work.
Functions like mapi take curried form of a function, which means that the type of the argument is compiled to something like FSharpFunc<int, FSharpFunc<T, R>>. However, many functions are actually compiled directly as functions of two arguments, so the actual value would typically be FSharpFunc<int, T, R> which inherits from FSharpFunc<int, FSharpFunc<T, R>>.
If you call this function (e.g. f 1 "a") the F# compiler generates something like this:
FSharpFunc<int, string>.InvokeFast<a>(f, 1, "a");
If you look at the InvokeFast function using Reflector, you'll see that it tests if the function is compiled as the optimized version (f :? FSharpFunc<int, T, R>). If yes, then it directly calls Invoke(1, "a") and if not then it needs to make two calls Invoke(1).Invoke("a").
This check is done each time you call a function passed as an argument (it is probably faster to do the check and then use the optimized call, because that's more common).
What the Adapt function does is that it converts any function to FSharpFunc<T1, T2, R> (if the function is not optimized, it creates a wrapper for it, but that's not the case most of the time). The calls to the adapted function will be faster, because they don't need to do the dynamic check every time (the check is done only once inside Adapt).
So, the summary is that Adapt could improve the performance if you're calling a function passed as an argument that takes more than 1 argument a large number of times. As with any optimizations, I wouldn't use this blindly, but it is an interesting thing to be aware of when tuning the performance!
(BTW: Thanks for a very interesting question, I didn't know the compiler does this :-))
Been grokking F# coming from a C# background.
In C# there is a clear difference in deciding when to use interfaces and when to use abstract classes. In F# I see the two blurring almost into one. I understand under the hood that the same is being done in F# as c# as far as the CLR is concerned, but what is the "best practise" when programming in F# to use?
Should I avoid class inheritance altogether?
I think that interfaces tend to be used much more frequently than abstract classes (compared to object-oriented languages like C#).
In many cases, you don't need any of the two, because you can just write higher-order function (that takes a function as an argument, instead of taking an interface as an argument). However, sometimes you may have two functions that are always used together - in that case, you can group two functions into an interface:
// Instead of using higher-order function
val foo : (int -> string) -> (string -> int) -> ...
// ..we can define an interface
type TwoWayConversion =
abstract ToString : int -> string
abstract FromString : string -> int
val foo : TwoWayConversion -> ...
I think that this is quite useful F# programming pattern that uses interfaces in a perfectly functional style.
On the other hand, I would use abstract classes only when writing object-oriented code that is supposed to be used from C# (e.g. C# code implementing your F# abstract class) - because that's a natural extensibility point from the C# point of view. However, I think that idiomatic F# code uses different extensibility points than C# (e.g. taking function/interface as an argument), so you don't really need abstract classes.
Well, if you're debating between abstract classes and interfaces, I think your reasons for one or the other would be the same as in C#.
Maybe you should consider using functions, functional data types and modules as units of abstraction though.
If you need to write an F# library to be used in C#, then you'll probably want to use interfaces etc for your exported types.