Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting OCaml to F#: Is there a simple way to simulate OCaml top-level #trace in F#

I am converting several modules based on OCaml to F#. I have the code converted and running in F#, however the result of the final function in F# is not the same as the result of the final function in OCaml. So obviously I have to follow the function calls to figure out which function is returning the wrong result.

OCaml has a nice top-level directive for tracing the input and output of a function, i.e. #trace .

I have searched F#'s debug and trace methods and the closest I get is to instrument the code using Trace.Write methods but it takes several lines for each method.

e.g.

Original

let fun001 parm001 =
  parm001 * 10

Instrumented

let fun001 parm001 =
  // For VS 2010, this trace output will be sent to Output window.
  System.Diagnostics.Trace.WriteLine("function001 <--");      
  System.Diagnostics.Trace.WriteLine(sprintf "%A" parm001);      
  let result = parm001 * 10
  System.Diagnostics.Trace.WriteLine("function001 -->");
  System.Diagnostics.Trace.WriteLine(sprintf "%A" result);
  result

Does F# have the same functionality as OCaml #trace that I missed when searching?

If you are sure the answer is no, that's all I need. I know people frown on short answers, but that is all I need if the answer is no.

EDIT

For more complex methods where capturing the result would evolve extensive modification to the code

Original

let func001 parm001 parm002 =
    match parm001 with
    | pattern001 -> func002 parm002
    | head :: tail -> 
        func003 head
        func001 tail
    | [] -> failwith "failed"

Instrumented

let func001org parm001 parm002 =
    match parm001 with
    | pattern001 -> func002 parm002
    | head :: tail -> 
        func003 head
        func001 tail
    | [] -> failwith "failed"
and fun001 parm001 parm002 =
  // For VS 2010, this trace output will be sent to Output window.
  System.Diagnostics.Trace.WriteLine("function001 <--");      
  System.Diagnostics.Trace.WriteLine(sprintf "%A, %A" parm001 parm002 );      
  let result = func001org parm001 parm002 
  System.Diagnostics.Trace.WriteLine("function001 -->");
  System.Diagnostics.Trace.WriteLine(sprintf "%A" result);
  result

EDIT

PostSharp does not support F#. See: Using PostSharp with F# - Need documentation with working example

like image 220
Guy Coder Avatar asked Sep 07 '12 19:09

Guy Coder


2 Answers

There is no built-in feature for this in F#, but I believe you can achieve that using a third-party tool.

One approach might be to use PostSharp. This is a tool for aspect-oriented programming (which is a style where you attach some additional operation to certain methods). It is implemented as a post-processor that takes a compiled assembly and adds some operation to each method. I'm not sure if it has been tested with F#, but I believe it should work.

Using PostSharp, you can implement aspect that logs information about method calls (just like the #trace command in OCaml) and then use a global configuration to attach it to all methods. The article Non-Invasive Tracing & Logging on their web site implements exactly this (and in a much more flexible and powerful way).

like image 62
Tomas Petricek Avatar answered Nov 17 '22 22:11

Tomas Petricek


No (although I would love to have such a facility in F#).

like image 40
pad Avatar answered Nov 17 '22 23:11

pad