From henrik.bengtsson at gmail.com  Sun Sep 25 21:38:27 2016
From: henrik.bengtsson at gmail.com (Henrik Bengtsson)
Date: Sun, 25 Sep 2016 12:38:27 -0700
Subject: [Rd] withAutoprint({ .... }) ?
In-Reply-To: <22503.64353.207088.597099@stat.math.ethz.ch>
References: <ce4bc223-12d1-2618-aa43-cd12c11396eb@gmail.com>
	<CAPPM_gSzW37A9xQn1qrTEqd6jWx-mE-cOq2i7zEqU08THqJn7A@mail.gmail.com>
	<20160902115636.4C6BE1A75DF@lynne.stat.math.ethz.ch>
	<CAF8bMcaOVsUsdSUN0GE+1COsb4hYBRaD7qdFcadY--PXB_bJaQ@mail.gmail.com>
	<22502.33207.568185.181074@stat.math.ethz.ch>
	<CAFDcVCSYsxk5QVqU_6GtWqET=nbqqcMCakhDbx2nDhAhr5C7xg@mail.gmail.com>
	<22503.64353.207088.597099@stat.math.ethz.ch>
Message-ID: <CAFDcVCQSyLuza-zEtr6ZvHr0QPdYkjppBCRmge5LNfhRuT0y9w@mail.gmail.com>

On Sun, Sep 25, 2016 at 9:29 AM, Martin Maechler
<maechler at stat.math.ethz.ch> wrote:
>>>>>> Henrik Bengtsson <henrik.bengtsson at gmail.com>
>>>>>>     on Sat, 24 Sep 2016 11:31:49 -0700 writes:
>
>     > Martin, did you post your code for withAutoprint() anywhere?
>     > Building withAutoprint() on top of source() definitely makes sense,
>     > unless, as Bill says, source() itself could provide the same feature.
>
> I was really mainly asking for advice about the function name
> .. and got none.

I missed that part.  I think the name is good.  A shorter alternative
would be withEcho(), but could be a little bit misleading since it
doesn't reflect 'print=TRUE' to source().

>
> I'm now committing my version (including (somewhat incomplete)
> documentation, so you (all) can look at it and try / test it further.
>
>     > To differentiate between withAutoprint({ x <- 1 }) and
>     > withAutoprint(expr) where is an expression / language object, one
>     > could have an optional argument `substitute=TRUE`, e.g.
>
>     > withAutoprint <- function(expr, substitute = TRUE, ...) {
>     >    if (substitute) expr <- substitute(expr)
>     >    [...]
>     > }
>
> I think my approach is nicer insofar it does not seem to need
> such an argument.... I'm sure you'll try to disprove that ;-)

Nah, I like that you've extended source() with the 'exprs' argument.

May I suggest to add:

svn diff src/library/base/R/
Index: src/library/base/R/source.R
===================================================================
--- src/library/base/R/source.R (revision 71357)
+++ src/library/base/R/source.R (working copy)
@@ -198,7 +198,7 @@
      if (!tail) {
     # Deparse.  Must drop "expression(...)"
     dep <- substr(paste(deparse(ei, width.cutoff = width.cutoff,
-                                                control = "showAttributes"),
+  control = c("keepInteger", "showAttributes")),
  collapse = "\n"), 12L, 1e+06L)
     dep <- paste0(prompt.echo,
   gsub("\n", paste0("\n", continue.echo), dep))

such that you get:

> withAutoprint(x <- c(1L, NA_integer_, NA))
> x <- c(1L, NA_integer_, NA)

because without it, you get:

> withAutoprint(x <- c(1L, NA_integer_, NA))
> x <- c(1, NA, NA)

Thanks,

Henrik


>
> Martin
>
>     > Just some thoughts
>     > /Henrik
>
>
>     > On Sat, Sep 24, 2016 at 6:37 AM, Martin Maechler
>     > <maechler at stat.math.ethz.ch> wrote:
>     >>>>>>> William Dunlap <wdunlap at tibco.com>
>     >>>>>>> on Fri, 2 Sep 2016 08:33:47 -0700 writes:
>     >>
>     >> > Re withAutoprint(), Splus's source() function could take a expression
>     >> > (literal or not) in place of a file name or text so it could support
>     >> > withAutoprint-like functionality in its GUI.  E.g.,
>     >>
>     >> >> source(auto.print=TRUE, exprs.literal= { x <- 3:7 ; sum(x) ; y <- log(x)
>     >> > ; x - 100}, prompt="--> ")
>     --> x <- 3:7
>     --> sum(x)
>     >> > [1] 25
>     --> y <- log(x)
>     --> x - 100
>     >> > [1] -97 -96 -95 -94 -93
>     >>
>     >> > or
>     >>
>     >> >> expr <- quote({ x <- 3:7 ; sum(x) ; y <- log(x) ; x - 100})
>     >> >> source(auto.print=TRUE, exprs = expr, prompt="--> ")
>     --> x <- 3:7
>     --> sum(x)
>     >> > [1] 25
>     --> y <- log(x)
>     --> x - 100
>     >> > [1] -97 -96 -95 -94 -93
>     >>
>     >> > It was easy to implement, since exprs's default value is parse(file) or
>     >> > parse(text=text), which source is calculating anyway.
>     >>
>     >>
>     >> > Bill Dunlap
>     >> > TIBCO Software
>     >> > wdunlap tibco.com
>     >>
>     >> Thank you, Bill  (and the other correspondents); that's indeed a
>     >> very good suggestion :
>     >>
>     >> I've come to the conclusion that Duncan and Bill are right:  One
>     >> should do this in R (not C) and as Bill hinted, one should use
>     >> source().  I first tried to do it separately, just "like source()",
>     >> but a considerable part of the source of source()  {:-)} is
>     >> about using src attributes instead of deparse() when the former
>     >> are present,  and it does make sense to generalize
>     >> withAutoprint() to have the same feature, so after all, have it
>     >> call source().
>     >>
>     >> I've spent a few hours now trying things and variants, also
>     >> found I needed to enhance source()  very slightly also in a few
>     >> other details, and now (in my uncommitted version of R-devel),
>     >>
>     >> withAutoprint({ x <- 1:12; x-1; (y <- (x-5)^2); z <- y; z - 10 })
>     >>
>     >> produces
>     >>
>     >>> withAutoprint({ x <- 1:12; x-1; (y <- (x-5)^2); z <- y; z - 10 })
>     >>> x <- 1:12
>     >>> x - 1
>     >> [1]  0  1  2  3  4  5  6  7  8  9 10 11
>     >>> (y <- (x - 5)^2)
>     >> [1] 16  9  4  1  0  1  4  9 16 25 36 49
>     >>> z <- y
>     >>> z - 10
>     >> [1]   6  -1  -6  -9 -10  -9  -6  -1   6  15  26  39
>     >>>
>     >>
>     >> and is equivalent to
>     >>
>     >> withAutoprint(expression(x <- 1:12, x-1, (y <- (x-5)^2), z <- y, z - 10 ))
>     >>
>     >> I don't see any way around the "mis-feature" that all "input"
>     >> expressions are in the end shown twice in the "output" (the
>     >> first time by showing the withAutoprint(...) call itself).
>     >>
>     >> The function *name* is "not bad" but also a bit longish;
>     >> maybe there are better ideas?  (not longer, no "_" - I know this
>     >> is a matter of taste only)
>     >>
>     >> Martin
>     >>
>     >> > On Fri, Sep 2, 2016 at 4:56 AM, Martin Maechler <maechler at stat.math.ethz.ch>
>     >> > wrote:
>     >>
>     >> >> On R-help, with subject
>     >> >> '[R] source() does not include added code'
>     >> >>
>     >> >> >>>>> Joshua Ulrich <josh.m.ulrich at gmail.com>
>     >> >> >>>>>     on Wed, 31 Aug 2016 10:35:01 -0500 writes:
>     >> >>
>     >> >> > I have quantstrat installed and it works fine for me.  If you're
>     >> >> > asking why the output of t(tradeStats('macross')) isn't being
>     >> >> printed,
>     >> >> > that's because of what's described in the first paragraph in the
>     >> >> > *Details* section of help("source"):
>     >> >>
>     >> >> > Note that running code via ?source? differs in a few respects from
>     >> >> > entering it at the R command line.  Since expressions are not
>     >> >> > executed at the top level, auto-printing is not done.  So you will
>     >> >> > need to include explicit ?print? calls for things you want to be
>     >> >> > printed (and remember that this includes plotting by ?lattice?,
>     >> >> > FAQ Q7.22).
>     >> >>
>     >> >>
>     >> >>
>     >> >> > So you need:
>     >> >>
>     >> >> > print(t(tradeStats('macross')))
>     >> >>
>     >> >> > if you want the output printed to the console.
>     >> >>
>     >> >> indeed, and "of course"" ;-)
>     >> >>
>     >> >> As my subject indicates, this is another case, where it would be
>     >> >> very convenient to have a function
>     >> >>
>     >> >> withAutoprint()
>     >> >>
>     >> >> so the OP could have (hopefully) have used
>     >> >> withAutoprint(source(..))
>     >> >> though that would have been equivalent to the already nicely existing
>     >> >>
>     >> >> source(.., print.eval = TRUE)
>     >> >>
>     >> >> which works via the  withVisible(.) utility that returns for each
>     >> >> 'expression' if it would auto print or not, and then does print (or
>     >> >> not) accordingly.
>     >> >>
>     >> >> My own use cases for such a withAutoprint({...})
>     >> >> are demos and examples, sometimes even package tests which I want to print:
>     >> >>
>     >> >> Assume I have a nice demo / example on a help page/ ...
>     >> >>
>     >> >> foo(..)
>     >> >> (z <- bar(..))
>     >> >> summary(z)
>     >> >> ....
>     >> >>
>     >> >> where I carefully do print parts (and don't others),
>     >> >> and suddenly I find I want to run that part of the demo /
>     >> >> example / test only in some circumstances, e.g., only when
>     >> >> interactive, but not in BATCH, or only if it is me, the package maintainer,
>     >> >>
>     >> >> if( identical(Sys.getenv("USER"), "maechler") ) {
>     >> >> foo(..)
>     >> >> (z <- bar(..))
>     >> >> summary(z)
>     >> >> ....
>     >> >> }
>     >> >>
>     >> >> Now all the auto-printing is gone, and
>     >> >>
>     >> >> 1) I have to find out which of these function calls do autoprint and wrap
>     >> >> a print(..) around these, and
>     >> >>
>     >> >> 2) the result is quite ugly (for an example on a help page etc.)
>     >> >>
>     >> >> What I would like in a future R, is to be able to simply wrap the "{
>     >> >> .. } above with an 'withAutoprint(.) :
>     >> >>
>     >> >> if( identical(Sys.getenv("USER"), "maechler") ) withAutoprint({
>     >> >> foo(..)
>     >> >> (z <- bar(..))
>     >> >> summary(z)
>     >> >> ....
>     >> >> })
>     >> >>
>     >> >> Conceptually such a function could be written similar to source() with an R
>     >> >> level for loop, treating each expression separately, calling eval(.) etc.
>     >> >> That may cost too much performnace, ... still to have it would be better
>     >> >> than
>     >> >> not having the possibility.
>     >> >>
>     >> >> ----
>     >> >>
>     >> >> If you read so far, you'd probably agree that such a function
>     >> >> could be a nice asset in R,
>     >> >> notably if it was possible to do this on the fast C level of R's main
>     >> >> REPL.
>     >> >>
>     >> >> Have any of you looked into how this could be provided in R ?
>     >> >> If you know the source a little, you will remember that there's
>     >> >> the global variable  R_Visible  which is crucial here.
>     >> >> The problem with that is that it *is* global, and only available
>     >> >> as that; that the auto-printing "concept" is so linked to "toplevel
>     >> >> context"
>     >> >> and that is not easy, and AFAIK not so much centralized in one place in the
>     >> >> source. Consequently, all kind of (very) low level functions manipulate
>     >> >> R_Visible
>     >> >> temporarily.... and so a C level implementation of  withAutoprint() may
>     >> >> need considerable more changes than just setting R_Visible to TRUE in one
>     >> >> place.
>     >> >>
>     >> >> Have any efforts / experiments already happened towards providing such
>     >> >> functionality ?
>     >> >>
>     >> >> ______________________________________________
>     >> >> R-devel at r-project.org mailing list
>     >> >> https://stat.ethz.ch/mailman/listinfo/r-devel
>     >>
>     >> > [[alternative HTML version deleted]]
>     >>
>     >> ______________________________________________
>     >> R-devel at r-project.org mailing list
>     >> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] withAutoprint({ .... }) ?
Henrik Bengtsson