MiP
MiP

Reputation: 6462

Continuously logging in F#

I'm trying to create 2 logging functions: one is to directly print to stdout, another is to print with an antecedent string [Error].

let log message =
    printfn message

let twError (tw:System.IO.TextWriter) message =
    tw.Write("[Error] {0}", message)

let error (message:Printf.StringFormat<_>) =
    let format = Printf.TextWriterFormat<_>(sprintf "[Error] %A" message)
    log format

let date = System.DateTime.Now
log "%A" twError date
error "%s" <| date.ToString()

As you can see, in the error function I need to make a new string, then convert it to a TextWriterFormat type. But this will be less efficient than writing directly to the stream, how should I change the error function to make it more efficient?

Upvotes: 3

Views: 272

Answers (1)

rmunn
rmunn

Reputation: 36738

You want the Printf.kprintf family of functions. Their documentation is very hard to understand, but the concept is simple:

  • printf takes a format string (and arguments), formats it, and then prints it to the console
  • sprintf takes a format string (and arguments), formats it, and then returns it as a string
  • kprintf takes a format string (and arguments), formats it, and then passes it (as a string) to a function that you provide. That function should take in a string and do whatever you want with it.

For example:

open Printf

let addDateTime (s : string) =
    sprintf "%A: %s" DateTime.UtcNow s

sprintf "%A" [1; 2; 3]  // Returns "[1; 2; 3]"
kprintf addDateTime "%A" [1; 2; 3]  // Returns "2017-05-26 06:05:00: [1; 2; 3]"

let printDateTime (s : string) =
    printfn "%A: %s" DateTime.UtcNow s

printfn "%A" [1; 2; 3]  // Prints "[1; 2; 3]"
kprintf printDateTime "%A" [1; 2; 3]  // Prints "2017-05-26 06:05:00: [1; 2; 3]"

So your error function could simply become:

let errorLogger (s : string) = printfn "[Error] %s" s
let error msg = kprintf errorLogger msg

error "Oops: %A" [1; 2; 3]   // Prints "[Error] Oops: [1; 2; 3]"

Experiment with kprintf a bit more and see what you can do with it. It's a very powerful function, and it's a shame that more people don't know about it.

Upvotes: 3

Related Questions