Skip to content

Instantly share code, notes, and snippets.

@mpjdem
Created September 18, 2019 21:22
Show Gist options
  • Save mpjdem/38ad07bae86c2884e250c3ebdc87f96b to your computer and use it in GitHub Desktop.
Save mpjdem/38ad07bae86c2884e250c3ebdc87f96b to your computer and use it in GitHub Desktop.
'State' design pattern in R
# General functions
atom <- function(obj) {
atom <- new.env()
atom$obj <- obj
atom
}
deref <- function(atom) {
atom$obj
}
swap <- function(atom, fn, ...) {
atom$obj <- do.call(fn, c(list(atom$obj), list(...)))
}
multimethod <- function(dispatch_fn, ...) {
args <- list(...)
dispatch_values <- args[seq(1, length(args), 2)]
functions <- args[seq(2, length(args), 2)]
function(obj) {
functions[[which(dispatch_values == dispatch_fn(obj))]](obj)
}
}
# Implementation of example
subscribe <- function(user) {
if (deref(user)$user_state == "not_subscribed") {
swap(user, purrr::list_modify, user_state = "subscribed")
}
}
greet <-
multimethod(function(x) x$user_state,
"subscribed", function(x) paste0("Greetings, ", x$name, "!!!"),
"not_subscribed", function(x) paste0("Greetings, ", x$name, "."))
# Run the example
user <- atom(list(name = "John Doe", user_state = "not_subscribed"))
greet(deref(user))
subscribe(user)
greet(deref(user))
@mpjdem
Copy link
Author

mpjdem commented Sep 18, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment