Learn R Programming

catchr (version 0.2.31)

catchr-DSL: The language of catchr

Description

catchr implements a small but helpful "domain-specific language" (DSL) to make building condition-handling functions simpler to read and type. Essentially, catchr reserves special 'terms' that mean something different than they do in the rest of R. When given as part of the input for a catchr plan, these terms will be substituted for special catchr functions used to handle conditions.

These special terms can be inputted as strings (e.g., warning = list('collect', 'muffle')) or as unquoted terms (e.g., warning = c(collect, muffle)); catchr internally converts the unquoted terms to strings regardless, but being able to input them unquoted saves keystrokes and can highlight their special meanings for code readability.

Arguments

Special reserved terms

The following are the special terms and what they do. Note that there are also some special condition names, but those are different from the following.

  • tomessage, towarning, toerror: these terms will become functions that will convert captured conditions into a message, warning, or error, respectively, and raise them. The original classes of the condition will be lost.

  • beep: if the beepr package is installed, this will play a sound via beepr::beep.

  • display: the purpose of this term is to immediately display information about the captured condition on the output terminal without raising additional conditions (as would be done with tomessage). Currently, it attempts to display this information with bold, turquoise-blue text if the crayon package is installed. In future versions of catchr, this default styling (and other display options) may be able to be changed by the user.

  • muffle: this term will be substituted for a function that 'muffles' (i.e., 'suppresses', 'catches', 'hides'---whatever you want to call it) the captured condition, preventing it from being raised to higher levels or subsequent plans. Anything in a plan after muffle will be ignored, so put it last. The function muffle is built on, first_muffle_restart(), searches for the first available restart with "muffle" in its name (the two typical ones are "muffleMessage" and "muffleWarning") and calls invokeRestart with it. If the captured condition is an error, which can't be muffled, it will exit the evaluation and give NULL for the returned value of the evaluated expression.

  • exit: when encountered, this will exit the evaluation of the expression immediately and by default muffle the captured condition (use raise in the plan if to ensure this doesn't happen). Any instructions after exit in the input will be ignored, so put it last.

  • collect: this term will store the captured conditions and append them to the output of the evaluated expression. See the collecting conditions help topic for a full explanation.

  • raise: this term will raise the captured condition "as is". The only real use for this term is when you want to use exit to stop the evaluation, but to still raise the condition past that as well (in which case, put raise in the plan before exit). The behavior of this raising might be slightly unpredictable for very odd edge-cases (e.g., if a condition were both a warning and an error).

Masking

catchr will turn unquoted special terms into functions, but what happens if these unquoted terms are identical to variables previously declared?

If muffle is the name of a user-defined function, e.g., muffle <- function(x) print("Wooo!"), in normal R we would expect warning = muffle to make function(x) print("Wooo!") the warning handler.

However, catchr's DSL "masks" any symbol that matches one of its reserved terms, and when it evaluates these symbols, they are converted into strings. For the most part, catchr will warn you when this happens.

Importantly, catchr does not mask reserved terms when:

  • the reserved names are being used as calls, e.g., warning = collect(foo). In these cases, it will attempt to use a previously defined function collect on foo, and will attempt to use whatever that evaluates to. The reserved terms are all strings/unquoted bare symbols, so it is never a problem anyway.

  • the input specifically references a namespace/package, such as warning = dplyr::collect. When the symbol of a special terms is preceded by :: or :::, it will be seen as the function of that package, and not as the special term collect.

  • the reserved terms are used inside a previously defined function. For example, if the user had defined muffle <- function(x) print("not special"), and fn <- function(x) muffle, using the argument warning = fn() would not use the special term of muffle.