From suharto_anggono at yahoo.com  Thu Oct 29 07:35:11 2009
From: suharto_anggono at yahoo.com (suharto_anggono at yahoo.com)
Date: Thu, 29 Oct 2009 07:35:11 +0100 (CET)
Subject: [Rd] In the result of applying 'bquote' to function definition with
	2 or more arguments, first function argument disappears (PR#14031)
Message-ID: <20091029063512.0339B282EF52@mail.pubhealth.ku.dk>

Full_Name: Suharto Anggono
Version: 2.8.1
OS: Windows
Submission from: (NULL) (125.165.81.124)


Sorry for repost. There is already PR#9602, but the problem is still there.
There is also a post "Re: [R] using bquote to construct function" in R-help
2008-10-02.

This illustrates the problem.


C:\Program Files\R\R-2.8.1\bin>R --vanilla

R version 2.8.1 (2008-12-22)
Copyright (C) 2008 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> h1 <- bquote(function(x, y) {
+ })
> h1
function(, y) {
}
> print(h1, useSource=FALSE)
function(, y) {
}
> eval(h1)
Error in eval(expr, envir, enclos) :
  invalid formal argument list for "function"
> h2 <- bquote(function(x, y) {})
> h2
function(x, y) {}

> print(h2, useSource=FALSE)
function(, y) {
}
> eval(h2)
Error in eval(expr, envir, enclos) :
  invalid formal argument list for "function"
> eval(bquote(function(x) {}))
function(x) {}
> eval(bquote(function() {}))
function() {}
> eval(bquote(function(...) {}))
function(...) {}
> eval(bquote(function(x, y, z) {}))
Error in eval(expr, envir, enclos) :
  invalid formal argument list for "function"
> version
               _
platform       i386-pc-mingw32
arch           i386
os             mingw32
system         i386, mingw32
status
major          2
minor          8.1
year           2008
month          12
day            22
svn rev        47281
language       R
version.string R version 2.8.1 (2008-12-22)
> sessionInfo()
R version 2.8.1 (2008-12-22)
i386-pc-mingw32

locale:
LC_COLLATE=English_United States.1252;LC_CTYPE=English_United
States.1252;LC_MON
ETARY=English_United States.1252;LC_NUMERIC=C;LC_TIME=English_United
States.1252


attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base
>


R was installed from binary.

Above, h1 and h2 are results of applying 'bquote' to function definition with 2
arguments. Apparently, h1 and h2 are actually the same, just printed
differently. They are printed identically when useSource=FALSE. The first
argument disappears, error when 'eval'-ed.

But, apparently, if the function has one or zero argument, applying 'bquote'
results fine.


I try to debug. In the definition of 'bquote', there is 'unquote' function.


> bquote
function (expr, where = parent.frame())
{
    unquote <- function(e) {
        if (length(e) <= 1)
            e
        else if (e[[1]] == as.name("."))
            eval(e[[2]], where)
        else as.call(lapply(e, unquote))
    }
    unquote(substitute(expr))
}
<environment: namespace:base>
> unquote <- function(e) {
+ if (length(e) <= 1) e
+ else if (e[[1]] == as.name(".")) eval(e[[2]])
+ else as.call(lapply(e, unquote))
+ }
> h1e <- substitute(function(x, y) {
+ })
> unquote(h1e)
function(, y) {
}
> length(h1e)
[1] 4
> lapply(h1e, unquote)
[[1]]
`function`

[[2]]
``(y = )

[[3]]
{
}

[[4]]
"function(x, y) {"("}")

> as.call(.Last.value)
function(, y) {
}
> h1e[[2]]
$x


$y


> unquote(h1e[[2]])
``(y = )
> length(h1e[[2]])
[1] 2
> lapply(h1e[[2]], unquote)
$x


$y


> as.call(.Last.value)
``(y = )
>


After seeing the above result and reading the documentation of 'as.call', I
conclude that the first function argument (i.e. x) is missing because of
'as.call'. It should not be applied to the result for h1e[[2]]. However, it
should be applied to the result for h1e.


I don't know if this is worth to be fixed. But, if not, the documentation should
mention that 'bquote' is not to be applied to expression containing function
definition with two or more formal arguments.



[Rd] In the result of applying 'bquote' to function definition with 2 or more arguments, first function argument disappears (PR#14031)
suharto_anggono at yahoo.com