Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top