[R] printing a generated function crashes R

Gabor Grothendieck ggrothendieck at gmail.com
Tue Sep 19 15:03:06 CEST 2006


In fact, in this example its not really even necessary to manipulate
the function since the new function will find z in its environment
(which is the body of make.function3):

make.function3 <- function() {
	z <- 1
	function(x, y) x*y+z
}

g <- make.function2()
g(3,2) # 7


On 9/19/06, Gabor Grothendieck <ggrothendieck at gmail.com> wrote:
> You could alternately use substitute:
>
>
> make.function2 <- function() {
>        fun <- function(x, y) x*y+z
>        body(fun) <- do.call(substitute, list(body(fun), list(z = 1)))
>        fun
> }
>
> ff <- make.function2()
> ff(3,2) # 7
>
>
> On 9/19/06, Mstislav Elagin <elagin at wias-berlin.de> wrote:
> > 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
> >
> > ______________________________________________
> > R-help at stat.math.ethz.ch 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.
> >
>



More information about the R-help mailing list