visify: Make a function autoprint all its doings

visifyR Documentation

Make a function autoprint all its doings

Description

Occasionally you want a function to do a whole bunch of things, and print the results as it goes along; you might be thinking about executing its code directly in a "script", but you don't want to be cluttering up the workspace. If so, you can wrap the body of your function in a call to visify, and R will act as if you source the corresponding script. The output isn't particularly beautiful, but it's jolly handy for eg routine diagnostics when fitting a series of models.

You can also use visify inside a function, to just display certain bits. (Well, not entirely; as of 2.9.18, any code before visify always seems to be shown. But at least you can hide the return value.) For example, it's sometimes useful to not visify the entire return-value of a function, even though you want to "show the rest of your working". In that case, you can just not return the value within the visify block, but separately afterwards; see Examples.

visify is experimental as of package mvbutils v2.9.228, and I might add features over time, eg to make output look prettier and give better options for hiding things. At present, it deliberately strips all continuation lines of input, so you only see the first line of each statement (a blessing IME so far). More could be done; but I don't yet understand how all the options to source and withAutoprint work, and this is really a convenience function rather than something intended for producing report-quality output.

To do

As of package mvbutils v 2.9.23 and package debug v 1.4.18, the latter does not currently handle visify nicely (in contrast to eg evalq, which is operationally very similar except WRTO output). What you have to do for now, is manually replace the call to visify with a call to evalq (and remove any extraneous arguments).

This kinda thing comes up often. I really need a general mechanism in the debug package, for any other package (or the user) to supply an mtrace-able version of their pet function.

Usage

# Never use it like this...
visify(exprs, local = parent.frame(), prompt.echo='', ...)
# ... always like this, for an entire function:
# my_autoprinting_function <- function(<args>) visify( {<body>})
# ... or just as part of one:
# my_part_apf <- function( <args>){ visify({<shown>}); <posthoc-and-returns>}

Arguments

exprs

The body of your function

local

Normally leave this alone; it's the environment to run exprs in

prompt.echo

what to print at the start of each line. Default is nothing.

...

other args to withAutoprint, such as max.deparse.length or width.cutoff.

Details

Compound statements, such as if and for, are not printed "internally", only the final outcome (which is NULL for for). The first line of the compound code is still printed, though.

If you want certain statements in your function to execute without autoprinting their output (eg because it is an enormous and cluttery intermediate calculation), wrap it or them in curlies, a la { <dont; show; these; outputss>; NULL}. Again, the first line of code will be printed regardless— so you could just make into a "Hide me!" comment, as per Examples.

The trick behind visify is to use withAutoprint, but it's not obvious exactly how to do so. I was encouraged by:

https://stackoverflow.com/questions/58285497

However, I did not use exactly the solutions there, because I wanted a slightly different "flow".

See Also

withAutoprint

Examples

# Basic: show it all
tv1 <- function( xx) visify({
  yy <- xx + 1
  # Comments show up, too...
  for( i in 1:5) yy <- yy + 1
  # ... but loops only show end result; ditto ifs
  # and other compound statements
  xx <- xx+1
  xx <- xx + 2
  xx*yy
})
tv1( 3)
# Note the use of max.deparse.length param. Also try width.cutoff
tv2 <- function( xx, MDL=Inf) visify( max.deparse.length=MDL, {
  yy <- xx + 1
  # Comments show up, too...
  for( i in 1:5) yy <- yy + 1
  # Dont' want to show gory details of next "block"
  { # HIDE ME!
    xx <- xx+1
    xx <- xx + 2
    NULL # that's all you'll see
  }
  xx*yy
})
tv2( 3)
tv2( 3, MDL=100)
tv2( 3, MDL=50) # too terse
# Hide boring stuff
tv2 <- function( xx){
  # I don't understand why this bit _before_ visify() is shown
  yy <- xx + 1
  for( i in 1:5) yy <- yy + 1
  visify({
    xx <- xx+1
    xx <- xx + 2
    NULL # that's all you'll see
  })
  # At least the return-value isn't!
invisible( rep( xx*yy, 9999)) # don't wanna show this!
}
tv2( 3)

mvbutils documentation built on May 25, 2026, 5:09 p.m.

Related to visify in mvbutils...