Skip to content

report should be NOINLINE and lazy in a #1

@nfrisby

Description

@nfrisby

Initially, I had thought it would be more expressive to let the user choose between seq, pseq, etc when adding reports to their code.

However, I think the fundamental idea of report spy a `seq` x is that the spy reports when x is evaluated. Much like Debug.Trace.trace string x.

For that to be true, there is no option other than a small definition that couples the reporting and the evaluation and is marked NOINLINE and is lazy in the pure argument, just like trace.

report :: HasCallStack => Spy a -> a -> a
{-# NOINLINE report #-}
report spy a = unsafePerformIO $ do reportIO spy a; return a    -- NB reportIO does not force a

This might not be the only reason, but my compelling realization about why it must be NOINLINE is that if this were to be inlined, then subsequent Simplification of the expression might mean that the reporting side-effect and the evaluation of a no longer happen "at the same time" -- GHC makes no promises about the order of "pure" computations.

I'm saddened that report will therefore interfere with optimizations (I had been hoping it could be used to observe the effects of various optimizations... it probably still can, but not all, or at least only carefully), but report's intended semantics simply seems incompatible with inlining. It may be possible to compromise less, but not without futzing at the RTS-level, I don't think.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions