[R] printing a generated function crashes R

Mstislav Elagin elagin at wias-berlin.de
Tue Sep 19 09:37:46 CEST 2006


Peter Dalgaard wrote:
> Mstislav Elagin <elagin at wias-berlin.de> 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



More information about the R-help mailing list