Skip to content

Commit c4a8e9b

Browse files
committed
implement deferred evaluation pipe %>>%
1 parent a50f576 commit c4a8e9b

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ S3method(print,nanoObject)
1818
S3method(print,nanoSocket)
1919
S3method(print,recvAio)
2020
S3method(print,sendAio)
21+
S3method(print,unresolvedExpr)
2122
S3method(print,unresolvedValue)
2223
S3method(setopt,nanoContext)
2324
S3method(setopt,nanoDialer)
2425
S3method(setopt,nanoListener)
2526
S3method(setopt,nanoSocket)
2627
S3method(start,nanoDialer)
2728
S3method(start,nanoListener)
29+
export("%>>%")
2830
export(.mirai_scm)
2931
export(call_aio)
3032
export(context)

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
* Aio values `$result`, `$data` and `$raw` now resolve automatically without requiring `call_aio()`. Access the values directly and an 'unresolved' logical NA will be returned if the Aio operation is yet to complete.
66
* `unresolved()` added as an auxiliary function to query whether an Aio is unresolved, for use in control flow statements.
7+
* Implements the Deferred Evaluation Pipe `%>>%` for working with potentially unresolved values.
78
* Integer error values generated by receive functions are now classed 'errorValue'. `is_error_value()` helper function included.
89
* `is_nul_byte()` added as a helper function for request/reply setups.
910
* `survey_time()` added as a convenience function for surveyor/respondent patterns.

R/utils.R

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,66 @@ ncurl <- function(http, ...) {
217217

218218
}
219219

220+
#' Deferred Evaluation Pipe
221+
#'
222+
#' Pipe a possibly unresolved value forward into a function. [experimental]
223+
#'
224+
#' @param x a value that is possibly an 'unresolvedValue'.
225+
#' @param f a function that accepts 'x' as its first argument.
226+
#'
227+
#' @return The evaluated result, or if x is an 'unresolvedValue', an
228+
#' 'unresolvedExpr' encapsulating the eventual evaluation result. Query its
229+
#' \code{$data} field for resolution.
230+
#'
231+
#' @details Supports stringing together a series of piped expressions (as per
232+
#' the below example).
233+
#'
234+
#' This function is marked [experimental], which means it is currently
235+
#' under development. Please note that the final implementation is likely to
236+
#' differ from the current version.
237+
#'
238+
#' @examples
239+
#' if (interactive()) {
240+
#' # Only run examples in interactive R sessions
241+
#'
242+
#' s1 <- socket("pair", listen = "inproc://nanonext")
243+
#' s2 <- socket("pair", dial = "inproc://nanonext")
244+
#'
245+
#' msg <- recv_aio(s2)
246+
#' b <- msg$data %>>% c(2, 3) %>>% as.character()
247+
#' b
248+
#' res <- send_aio(s1, 1)
249+
#' b$data
250+
#'
251+
#' close(s1)
252+
#' close(s2)
253+
#' }
254+
#'
255+
#' @export
256+
#'
257+
`%>>%` <- function(x, f) {
258+
if (unresolved(x)) {
259+
mc <- match.call()
260+
data <- NULL
261+
env <- `class<-`(new.env(), c("unresolvedExpr", "unresolvedValue"))
262+
makeActiveBinding(sym = "data", fun = function(x) {
263+
if (is.null(data)) data <- eval(mc, envir = parent.frame(), enclos = baseenv())
264+
data
265+
}, env = env)
266+
env
267+
} else {
268+
x <- substitute(x)
269+
y <- substitute(f)
270+
f <- y[[1L]]
271+
y[[1L]] <- NULL
272+
eval(as.call(c(f, x, y)), envir = parent.frame(2L), enclos = baseenv())
273+
}
274+
}
275+
276+
#' @export
277+
#'
278+
print.unresolvedExpr <- function(x, ...) {
279+
cat("< unresolvedExpr >\n - $data for evaluated expression\n", file = stdout())
280+
invisible(x)
281+
}
282+

man/grapes-greater-than-greater-than-grapes.Rd

Lines changed: 47 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)