ramnathv/htmlwidgets — pull request #22 by jjallaire (2014-08-11 14:10:39+00:00)
Title: Refactor shiny output/render functions to use delegation rather than returning functions

We've had some discussions internally about how functions which return closures from within packages can cause breakage when package B is built against one version of package A (which returns it a closure) and is then run against a different version of package A. The issues seems to have to do with package namespaces being included within closures that are returned.

This change reverts to the original "delegating" model for shiny output/render functions. The one twist is that as a result of how quoting is handled there is one additional line of boilerplate required when defining a shiny render function for a widget. Here's what the new boilerplate looks like:

```S
simpleNetworkOutput <- function(outputId, width = "100%", height = "500px") {
shinyWidgetOutput(outputId, "simpleNetwork", width, height, package = "networkD3")
}

renderSimpleNetwork <- function(expr, env = parent.frame(), quoted = FALSE) {
if (!quoted) { expr <- substitute(expr) } # force quoted
shinyRenderWidget(expr, simpleNetworkOutput, env, quoted = TRUE)
}
```

Original source here: https://github.com/christophergandrud/networkD3/blob/feature/shiny-function-delegation/R/simpleNetwork.R#L100-L111

While I think this extra line of boilerplate is regrettable, I think that (a) shielding ourselves from hard to diagnose package versioning issues is well worth it; and (b) this is code that will be seen only by widget developers rather than end users.

@jcheng5 or @hadley, curious if you think there is a way to eliminate the boilerplate without reverting to the "factory function" approach (thus exposing us to the package versioning issues).