Contributing to OCaml recipes: Debug Print a Value

I previously posted Invitation to a new Ocaml tutorial - Imperative, Logic, Javascript but considering the status of OCaml Cookbook, I believe the latter is priority.

Let’s start with Debug a print value. I figured the following tricks:

integer
let show_int : int -> string = [%show: int]

a list of strings
let show_string_list : string list -> string = [%show: string list]

a list of tuple
let show_event_list : (int * string) list -> string = [%show: (int * string) list]

user-defined type

type tree =
    | Leaf of float
    | Node of float * tree * tree
    [@@deriving show]

excluding root path in printing

type tree =
    | Leaf of float
    | Node of float * tree * tree
    [@@deriving show { with_path = false }]

I want to submit a quality recipe; Would you assist?

  • Do you suggest any other common printing problem? even if you don’t have its solution, mention it please.
  • Recommend both basic and intermediary documentation sections, helping to understand the snippets, and writing new ones.
  • Look for a related asked question, like print titled, and raise a useful point related to printing.

The goal of any community is not “solve my problem” but building collaboratively, a sustainable and scalable impact. Shout out to Sabine’s post :grinning:.

1 Like

I would be happy to help! What exactly are we looking for?

Is it like using Format or using ppx_deriving for debugging value?

Would you recommend more data structures, values, and types, to print debug?

I think if you propose beginner to use a ppx (or anything that isnt in the stdlib), you need to explain how to install the dependency (with opam, but the package names should be given), and also how to build your project with it. Maybe also explain the difference between adding the dep to a dune file and adding the dep to a .opam file. This should be in a section that is easy to ignore if you know how to do this (maybe at the end ?)

Good point. Let’s do a separate cookbook page for dependencies installation, and cite it.
Also we need a brief explanation of ppx, and recommended readings from the documentation.

More than once while using printf-debugging in the past I’ve been bitten by OCaml’s buffered output. As a consequence I now always flush, to make sure the output is printed - and not sending me on a wild goose chase:

let i = 20 in
Printf.printf "At line 20 - and variable i is %i\n%!" i

(you can also use flush stdout rather than the %! specifier)

I believe this is a relatively common tripwire and hence should be included.

When debugging I typically don’t add ppx-dependencies to print values, but maybe thats just me… :person_shrugging:

2 Likes

does it work with other data structures and types?

This issue can arise whenever you use printf.

If you use print_endline to output a string that was computed by show, you will be fine.

Also if you are using Format, the directive to use is "@." or "@?" (for a direct equivalent of "%!").

Also I’d just mention that there have been a lot of discussions upstream on making stderr unbuffered by default. But I think the change hasn’t been made so far. The last occurence may be have been this PR.

Would you recommend sections from the documentation about this?

does it work with other data structures and types?

Sorry, I don’t understand your question.

[@@deriving show] will auto-generate a “to-string” function for you. It doesn’t print anything by itself. To “debug print a value” you will need something like print_string, print_endline or Printf.printf to pass the resulting string to.

When I debug I tend to either print simpler values, already have a “to-string” function available for more complex types, or quickly cook one up out of combinators from QCheck’s Print module (but that’s probably a consequence of my current activities…)

This issue can arise whenever you use printf.

Yes, print_endline does a flush stdout at the end, so that is a good choice. However something like print_string doesn’t flush either - so it is not just a printf issue. I believe we agree to recommend using a flushing printer (either print_endline, printf "...%!", or …) when printf debugging… :slightly_smiling_face:

Thanks. The confusion was my bad.
Would you recommend sections from the doc related to the discussion?

Flushing is mentioned in the Stdlib section under the relevant functions.
Buffering and flushing of out_channels is also explained in this page - using out_channels for writing to a file rather than stdout.

1 Like

One thing to note about Format and flushing is that functions that accept a formatter as an argument should generally not do any flushing. Instead, the final call where e.g. Format.err_formatter is passed in should include a final flush. Flushing force-closes any open formatting boxes, so functions that accept a formatter and flush it are not usable in any context intended to produce formatted output.

I mean this only as a gentle suggestion:

Instead of documenting Format, I would like to suggest documenting Fmt: it’s much more accessible, and the many different type-combinators are really useful for making debug-printing easy. And since one already must have ppx_deriving loaded, it’s not much to have fmt also.

1 Like

I would suggest Fmt.Dump because it’s meant for exactly the use case of debug printing values and outputs values formatted very similarly to OCaml literal syntax. Eg dream-html/test/dream_html_test.expected.txt at main · yawaramin/dream-html · GitHub

1 Like

Thank you for the suggestion. Write the tutorial you suggest, and I shall organize everyone’s comments into a single thread.

Thank you. Would you please write an outline, examples, or recommended resources to check? I am happy to learn from you.

You can see my article How to print anything in OCaml - DEV Community

And the documentation of Fmt.Dump Dump (fmt.Fmt.Dump)

3 Likes