> is.reactive(renderText("hi"))
[1] FALSE
> is.function(renderText("hi"))
[1] TRUE
So this actually works, though we don't recommend this syntax:
output$foo <- function() {
input$x
}
This works too and is (I think) more readable, hence recommended, but isn't technically necessary:
output$foo <- reactive({
input$x
})
In a way, outputs/renderXXX are really their own thing. They're similar to reactive expressions except that you can't use them in other reactive expressions or other outputs (i.e. they don't compose). And they're similar to observers except that you don't actually do side-effecty things inside of them.
Inside of Shiny there's a method called defineOutput, and output$x<-y is actually a call to defineOutput(x, y). It looks essentially like this (OK not really but this gives you the basic idea):
defineOutput <- function(name, renderFunc) {
observe({
value <- renderFunc()
browser$updateOutput(name, value)
})
}
So the renderXXX functions take a code chunk, and return a function that is used as the "renderFunc" in the code snippet above.