Peter Dalgaard wrote:
> Mstislav Elagin <[EMAIL PROTECTED]> writes:
>
>> Dear All,
>>
>> the last expression in the following code snippet crashes R (version
>> 2.3.1 on Windows XP) when run interactively:
>>
>> make.bad.function <- function(kind)
>> {
>> zz <- switch(kind,
>> "1" = 1,
>> "2" = 2)
>>
>> stopifnot( !is.null(zz) )
>>
>> eval( bquote( function(x)
>> {
>> x + .(zz)
>> }))
>> }
>>
>> # bad.function <- make.bad.function("5") ## error as expected
>>
>> bad.function <- make.bad.function("1")
>> print(bad.function(10)) ## -> 11
>>
>> bad.function <- make.bad.function("2")
>> print(bad.function(10)) ## -> 12
>>
>> bad.function ## this works if the code is source()'d
>> print(bad.function) ## oops!
>>
>> However, it does work (i.e. prints the body of bad.function) if run
>> non-interactively
>> (R --vanilla < bad-function.R).
>>
>> Any ideas why this happens?
>
> Well, bquote seems to be doing nasty things if passed an expression with a
> function inside:
>
>> f <- bquote(function(x) {
> + x + 1
> + }
> + )
>> f
> function(x) {
> x + 1
> }
>> eval(f)
> À
> ÈH~
>
> ÈH~
>
> Program received signal SIGSEGV, Segmentation fault.
>
>
> I think the story is that the source attribute is getting messed up.
>
>> z <- eval(f)
>> attr(z,"source")
> "function(x) {"("x+1}")
>> z
> ÈX~
> ÈX~
> ..poof..
Hallo,
after having played a bit more, I found out that the reason is not, or
at least not only the source attribute.
If we try to construct a function of more than one argument in the same
way as a function of no or one argument, we get an error message:
make.bad.function <- function()
{
zz <- 1
eval( bquote( function(x, y)
{
x*y + .(zz)
}))
}
bad.fun <- make.bad.function()
> Error in eval(expr, envir, enclos) : invalid formal argument list for
> "function"
However, if, following an older post by Brian Ripley, we specify the
list of formal arguments explicitly, everything works fine (albeit looks
uglier):
make.function <- function()
{
zz <- 1
fun <-
eval( bquote( function()
{
x*y + .(zz)
}))
formals(fun) <- alist(x=, y=)
return(fun)
}
fun <- make.function()
fun(3, 2) ## -> 7
Printing the function works, too:
fun
> function (x, y)
> {
> x * y + 1
> }
> <environment: 01A5884C>
My earlier example with the function of one argument works fine when
rewritten in the same spirit.
In my opinion, bquote behaves "inhomogeneously" in the sense that the
definition of the functions taking no of one params differs from that of
the functions taking more params. I wonder whether such behaviour of
bquote is a bug and should be reported.
Have a nice day
Mstislav Elagin
______________________________________________
[email protected] mailing list
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.