From gmbecker at ucdavis.edu  Mon Aug 25 17:50:24 2014
From: gmbecker at ucdavis.edu (Gabriel Becker)
Date: Mon, 25 Aug 2014 08:50:24 -0700
Subject: [Rd] dubious behaviour of match.arg() with nested functions.
In-Reply-To: <CABdHhvG9eT_teREJrSUr-tkmFfrKar7a-MgzBi+-RtNAs5kX6A@mail.gmail.com>
References: <CAO1zAVb_R22qDehCxzn7WCJhbPTYw8+aWYWzqM4KZEUJaTEnpg@mail.gmail.com>
	<CABdHhvG9eT_teREJrSUr-tkmFfrKar7a-MgzBi+-RtNAs5kX6A@mail.gmail.com>
Message-ID: <CADwqtCPvfvVZP+eo4WFYTvHP4VeBGTEiBRLc5Az5+GnNX0UWkw@mail.gmail.com>

More specifically, you're satisifying and not satisfying

    if (identical(arg, choices))
        return(arg[1L])

within the definition of match.args for x, and global, respectively.

arg is what is passed to the function (outer default) but choices isn't
specified so match.args uses nonstandard evaluation to populate it with the
default value *in the the call frame from which match.args was called*,
i.e. the *inner* default value. (See the details section of ?match.args)

The take away here is that match.args without explicitly setting choices is
dangerous except in top level functions, and that more generally
non-standard evaluation is dangerous and should be used sparingly and with
care.

~G


On Mon, Aug 25, 2014 at 8:22 AM, Hadley Wickham <h.wickham at gmail.com> wrote:

> This is one of the perils of non-standard evaluation - functions are
> no longer referentially transparent.
>
> Hadley
>
> On Mon, Aug 25, 2014 at 9:27 AM, Joris Meys <jorismeys at gmail.com> wrote:
> > Dear all,
> >
> > I initially ran into this problem while rebuilding a package dependent on
> > nleqslv. I got the following error:
> >
> > Error in match.arg(global) : 'arg' must be of length 1
> >
> > This didn't occur in previous versions of nleqslv, but did in the current
> > one (2.4). I think I pinned the problem down to the following example:
> >
> > Take two functions:
> >
> > test <- function(x=c("q","r","s"),global=c("d","e","r","z","q")){
> >   x <- match.arg(x)
> >   global <- match.arg(global)
> >   return(list(x,global))
> > }
> >
> > test2 <- function(x=c("q","r","s"),global=c("d","z","q")){
> >   test(x=x,global=global)
> > }
> >
> > test2() calls an "internal" function test() that uses the same arguments.
> > Note that for x both functions have exactly the same defaults, but not
> for
> > global.
> >
> > Calling test2() gives the reported error:
> >
> >> test2()
> >  Error in match.arg(global) : 'arg' must be of length 1
> >
> > I see the point of this error (global is not seen by test2() as default
> > settings but as a character vector I presume), but I wonder why this
> isn't
> > the case for x. Is this by design? If so, is there a part of the manual I
> > overlooked?
> >
> > Cheers
> > Joris
> >
> > --
> > Joris Meys
> > Statistical consultant
> >
> > Ghent University
> > Faculty of Bioscience Engineering
> > Department of Mathematical Modelling, Statistics and Bio-Informatics
> >
> > tel : +32 9 264 59 87
> > Joris.Meys at Ugent.be
> > -------------------------------
> > Disclaimer : http://helpdesk.ugent.be/e-maildisclaimer.php
> >
> >         [[alternative HTML version deleted]]
> >
> > ______________________________________________
> > R-devel at r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
>
>
>
> --
> http://had.co.nz/
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>



-- 
Gabriel Becker
Graduate Student
Statistics Department
University of California, Davis

	[[alternative HTML version deleted]]



[Rd] dubious behaviour of match.arg() with nested functions.
Gabriel Becker