Skip to content

Instantly share code, notes, and snippets.

@klmr
Last active June 15, 2022 12:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klmr/9d63ed118cfd59bae9d4d6be12b7ad78 to your computer and use it in GitHub Desktop.
Save klmr/9d63ed118cfd59bae9d4d6be12b7ad78 to your computer and use it in GitHub Desktop.
Version of “Nested function structure” from https://coolbutuseless.github.io/2022/06/15/nesting-functions/ without NSE
doc = function (...) {
doc = new.env(parent = emptyenv())
doc$words = lapply(list(...), add_node, doc = doc)
doc
}
par = function (...) {
structure(list(...), class = c("par", "docnode"))
}
sentence = function (words) {
structure(words, class = c("sentence", "docnode"))
}
# Note: for this simple example the `doc` argument to `add_node` is unused but
# for a real document API that allows nessted structures it becomes
# indispensable.
add_node = function (node, doc) {
UseMethod('add_node')
}
add_node.par = function (node, doc) {
lapply(node, add_node, doc = doc)
}
add_node.sentence = function (node, doc) {
unclass(node)
}
doc = function (expr) {
parent = parent.frame()
parent$`__doc__` = new.env(parent = emptyenv())
on.exit(rm(`__doc__`, envir = parent))
parent$`__doc__`$words = list()
expr
parent$`__doc__`
}
par = function (expr) {
parent = parent.frame()
parent$`__par__` = c()
on.exit(rm(`__par__`, envir = parent))
expr
parent$`__doc__`$words = c(parent$`__doc__`$words, list(parent$`__par__`))
}
sentence = function (words) {
parent = parent.frame()
parent$`__par__` = c(parent.frame()$`__par__`, words)
}
my_doc = doc({
par({
sentence("Hello there.")
sentence("My name is Greg.")
})
par({
sentence("Start of second par.")
})
})
print_doc(my_doc)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment