Skip to content
perrydv edited this page Aug 16, 2017 · 1 revision

Here is a first draft of the idea of having model macros (formerly discussed as "BUGS modules")

This idea was originally drafted on branch BUGSmodules and will be pull-requested on BUGSmodules2.

What follows is now out of date (as of 8/16/17). See instead test-macros.R and the roxygen entry for make_model_macros.

A working demo is here

How does it work:

  1. A function like nim_lm is registered as a BUGSmodule using makeBUGSmodule (See nim_lm right below this).

    • This could expand to manage / store additional information.
  2. In the second step of process BUGS (after handling if), codeProcessBUGSmodules looks for any BUGSmodules and calls them to replace the declaration.

    • As drafted, the LHS and RHS of the declaration are passed as arguments.
    • The operator (~ or <-, or at this stage anything really) should also be passed.
    • As drafted, the BUGSmodule function (e.g. lmPred) is responsible for pulling apart RHS arguments itself via match.call, match.arg, etc.
  3. The BUGSmodule function returns arbitrary lines of BUGS code it has constructed, wrapped in {.

  4. codeProcessBUGSmodules is called on the returned lines. This means one BUGS module can return code that relies on another BUGS module.

  5. A user could provide a new BUGS module. They would have to be adept at constructing code. If the system has legs, we could build some tools to help do that.

What design questions does it raise?

Where does data come in? Without data, how are factors and lengths indicated?

  • In R's lm-style functions, the data are provided, so expansion of terms can look at see what is what.

  • We normally process BUGS code without knowing what the data are, but knowing any provided constants and dimensions.

  • We could make it possible for any data, constants, and dimensions to be provided to BUGS modules during expansion. But it would have to be clear to a user if data is required.

  • And/or we could have modules that use calls use predY[1:n] <- lmPred( factor(A[1:num.blocks]) * X[1:n] ) or lmPred( A[1:num.blocks] * X[1:n], types = list(A = 'factor')) or similar. (In this example, we want an interaction between a factor and numeric explanatory variable.

    • In the preceding examples, a programmer would have to ensure n and num.blocks are provided as constants, similar to what they have to do now.
    • This could draw in some related issues, but I'll stop there.

How are new variables named?

  • From Y[1:n] ~ nim_glm(X[1:n]), a programmer might need to know about predY and X_coeff and want control over their naming.

  • It could entirely up to the BUGS module programmer to address this need:

    • They could document a fixed naming convention.
    • They could allow arguments to control the naming, up to full flexibility of accepting an arbitrary function to construct names.

Clone this wiki locally