Brian's answer is more efficient: IIRC, the whole call to log will just disappear, including the arguments.

Another approach is to make the log function take a () -> string parameter, then call that if you want to log:

1
2
3
 let loggingOn = false
let log (s:Lazy<_>) = if loggingOn then printfn "LOG: %s" (s.Force())
log (lazy sprintf "hi %s" "bye")

The downside here is that'll still construct a lazy value.

By on 8/26/2009 6:51 PM ()

If the compiler is smart, i.e. has constant propagation and dead code elimination, laziness is

unnecessary. Otherwise, even with lazy, you could end up with a function calls inside of tight loops.

By on 8/26/2009 7:42 PM ()

yanov good point. You're right, as far as I can tell, the compiler won't eliminate creation of the lazy value. However, it will elimiate the function here:

1
2
3
 let loggingOn = false
let log f = if loggingOn then printfn "%s" <| f() 
log (fun () -> sprintf "hi %d" 123)

When built with loggingOn = false, the lambda isn't emitted.

By on 8/26/2009 11:43 PM ()

Yes, see

[link:msdn.microsoft.com]

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 

open System.Diagnostics

type MyType() =
    [<Conditional("DEBUG")>]
    static member Log s = printfn "%s" s

let F x =
    MyType.Log (sprintf "Input was %d" x)
    let r = x + 1
    MyType.Log (sprintf "Result was %d" r)
    r

printfn "%d" (F 42)

(Try running after compiling in both 'Debug' and 'Release' modes.)

By on 8/26/2009 9:11 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper