Hi all:
In the course of playing around with other issues, I wrote the following
little function that allows functions to keep state
and easily replay and update their state.(see comments after):
memify <- function(f)
{
if (is.primitive(f)) {
cat("Cannot memify primitive functions.\n")
return(NULL)
}
if (!inherits(f, "function"))
stop("Argument must inherit from class 'function'")
arglist <- list()
structure(
function(...) {
m <- tryCatch(
as.list(match.call(f)[-1]),
error = function(e) {
warning("Bad function call; cannot update arguments\n")
return(NULL)
}
)
nm <- names(m)
hasname <- nm != "" #logical index of named values
if (any(hasname)) {
if (anyDuplicated(nm, incomparables = ""))
warning("Duplicated names in call; only the first will be
used.")
arglist <<- modifyList(arglist, m[hasname]) ## this is what
does the job
}
do.call(f, modifyList(m, arglist))
},
class = c("memified", class(f)))
}
Examples:
x <- 1:9; y <- runif(9)
plt <- memify(plot)
x <- 1:9; y <- runif(9)
plt(x,y, col = "blue") ## plt "remembers" these arguments;
i.e. keeps
state
plt( type = "b") ## all other arguments as previous
plt(col = "red") ## ditto
So my question is: Beyond allowing one to easily change/add argument values
and replay when there are lots of arguments floating around, which we often
use an IDE's editor to do, is there any real use for this? I confess that,
like Pygmalion, I have been charmed by this idea, but it could well be
useless, By all means feel free to chastise me if so.
1. I am aware that many functions already have "update" methods to
"update"
their results without re-entering all arguments -- e.g. lattice graphics,
glm, etc.
2. Several packages -- rlang and R6 anyway -- but very likely more, do this
sort of thing and way more; the price is added complexity, of course.
3. I realize also that keeping state would be a bad idea in many
circumstances, e.g. essentially changing documented defaults.
Reply privately to praise or bury if you do not think this is of any
interest to readers of this list. Publicly is fine, too. If it's dumb
it's
dumb.
Cheers and best wishes for a better new year for us all,
Bert Gunter
[[alternative HTML version deleted]]
I'm not enthusiastic about nonstandard evaluation and allowing
functions to change state data.
Currently, I use some of this in my own packages, but I'm planning to
remove most of it.
But I did have some fun with your function.
----------
plt <- memify (plot)
x <- 1:12
y1 <- seq (0, 18,, 12)
y2 <- c (
16.88, 16.04, 13.23, 13.88, 11.85, 9.61,
9.28, 5.81, 7.52, 3.40, 3.37, 0.07)
#test 1
plt (x, y1, type="l")
#test 2
plt (ylim = c (18, 0) )
#important econometric timeseries analysis
plt (y=y2, main="Monthly NZ GDP (Millions)")
----------
Note:
This data is not accurate.
On Sat, Jan 2, 2021 at 9:20 AM Bert Gunter <bgunter.4567 at gmail.com>
wrote:>
> Hi all:
>
> In the course of playing around with other issues, I wrote the following
> little function that allows functions to keep state
> and easily replay and update their state.(see comments after):
>
> memify <- function(f)
> {
> if (is.primitive(f)) {
> cat("Cannot memify primitive functions.\n")
> return(NULL)
> }
> if (!inherits(f, "function"))
> stop("Argument must inherit from class 'function'")
> arglist <- list()
> structure(
> function(...) {
> m <- tryCatch(
> as.list(match.call(f)[-1]),
> error = function(e) {
> warning("Bad function call; cannot update
arguments\n")
> return(NULL)
> }
> )
> nm <- names(m)
> hasname <- nm != "" #logical index of named values
> if (any(hasname)) {
> if (anyDuplicated(nm, incomparables = ""))
> warning("Duplicated names in call; only the first will
be
> used.")
> arglist <<- modifyList(arglist, m[hasname]) ## this is
what
> does the job
> }
> do.call(f, modifyList(m, arglist))
> },
> class = c("memified", class(f)))
> }
>
> Examples:
>
> x <- 1:9; y <- runif(9)
> plt <- memify(plot)
> x <- 1:9; y <- runif(9)
> plt(x,y, col = "blue") ## plt "remembers" these
arguments; i.e. keeps
> state
> plt( type = "b") ## all other arguments as previous
> plt(col = "red") ## ditto
>
> So my question is: Beyond allowing one to easily change/add argument values
> and replay when there are lots of arguments floating around, which we often
> use an IDE's editor to do, is there any real use for this? I confess
that,
> like Pygmalion, I have been charmed by this idea, but it could well be
> useless, By all means feel free to chastise me if so.
>
> 1. I am aware that many functions already have "update" methods
to "update"
> their results without re-entering all arguments -- e.g. lattice graphics,
> glm, etc.
> 2. Several packages -- rlang and R6 anyway -- but very likely more, do this
> sort of thing and way more; the price is added complexity, of course.
> 3. I realize also that keeping state would be a bad idea in many
> circumstances, e.g. essentially changing documented defaults.
>
> Reply privately to praise or bury if you do not think this is of any
> interest to readers of this list. Publicly is fine, too. If it's dumb
it's
> dumb.
>
> Cheers and best wishes for a better new year for us all,
>
> Bert Gunter
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
This would certainly simplify and make more readable some of my code where I create multiple versions of the same plot calling the same function with minor variations of a few of many arguments. Thanks! Peter On Fri, Jan 1, 2021 at 12:20 PM Bert Gunter <bgunter.4567 at gmail.com> wrote:> Hi all: > > In the course of playing around with other issues, I wrote the following > little function that allows functions to keep state > and easily replay and update their state.(see comments after): > > memify <- function(f) > { > if (is.primitive(f)) { > cat("Cannot memify primitive functions.\n") > return(NULL) > } > if (!inherits(f, "function")) > stop("Argument must inherit from class 'function'") > arglist <- list() > structure( > function(...) { > m <- tryCatch( > as.list(match.call(f)[-1]), > error = function(e) { > warning("Bad function call; cannot update arguments\n") > return(NULL) > } > ) > nm <- names(m) > hasname <- nm != "" #logical index of named values > if (any(hasname)) { > if (anyDuplicated(nm, incomparables = "")) > warning("Duplicated names in call; only the first will be > used.") > arglist <<- modifyList(arglist, m[hasname]) ## this is what > does the job > } > do.call(f, modifyList(m, arglist)) > }, > class = c("memified", class(f))) > } > > Examples: > > x <- 1:9; y <- runif(9) > plt <- memify(plot) > x <- 1:9; y <- runif(9) > plt(x,y, col = "blue") ## plt "remembers" these arguments; i.e. keeps > state > plt( type = "b") ## all other arguments as previous > plt(col = "red") ## ditto > > So my question is: Beyond allowing one to easily change/add argument values > and replay when there are lots of arguments floating around, which we often > use an IDE's editor to do, is there any real use for this? I confess that, > like Pygmalion, I have been charmed by this idea, but it could well be > useless, By all means feel free to chastise me if so. > > 1. I am aware that many functions already have "update" methods to "update" > their results without re-entering all arguments -- e.g. lattice graphics, > glm, etc. > 2. Several packages -- rlang and R6 anyway -- but very likely more, do this > sort of thing and way more; the price is added complexity, of course. > 3. I realize also that keeping state would be a bad idea in many > circumstances, e.g. essentially changing documented defaults. > > Reply privately to praise or bury if you do not think this is of any > interest to readers of this list. Publicly is fine, too. If it's dumb it's > dumb. > > Cheers and best wishes for a better new year for us all, > > Bert Gunter > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]