Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Debugging

When debugging, it is often helpful to output the value of an expression or variable.

We might try something like:

def sum(x: Int32, y: Int32): Int32 =
    let result = x + y;
    println("The sum of ${x} and ${y} is ${result}");
    result

Unfortunately this does not work:

❌ -- Type Error -------------------------------------------------- Main.flix

>> Unable to unify the effect formulas: 'IO' and 'Pure'.

1 |> def sum(x: Int32, y: Int32): Int32 =
2 |>     let result = x + y;
3 |>     println("The sum of ${x} and ${y} is ${result}");
4 |>     result

The problem is that println has the IO. Hence, we cannot use it to for print debugging inside pure functions. We could make our sum function have the IO effect, but that is rarely what we want. Instead, Flix has a built-in debugging facility that allows us to do print-line debugging.

The Debug.dprintln Function

Instead, we can use the Debug.dprintln function and write:

use Debug.dprintln;

def sum(x: Int32, y: Int32): Int32 =
    let result = x + y;
    dprintln("The sum of ${x} and ${y} is ${result}");
    result

Inside the sum function, the dprintln has the effect Debug, but due to its special nature, the Debug effect "disappears" once we exit the function, i.e. it is not part of its type and effect signature.

Debugging with Source Locations

We can use the special debug string interpolator to add source locations to our print statements:

use Debug.dprintln;

def sum(x: Int32, y: Int32): Int32 =
    let result = x + y;
    dprintln(d"The sum of ${x} and ${y} is ${result}");
    result

A longer introduction to dprintln is available in the blog post Effect Systems vs Print Debugging: A Pragmatic Solution