Re: [R-pkg-devel] R feature suggestion: Duplicated function arguments check

2021-11-08 Thread Avi Gross via R-package-devel
Vincent,

But is the second being ignored the right result?

In many programming situations, subsequent assignments replace earlier ones.
And consider the way R allows something like this:

func(a=2, b=3, a=4, c=a*b)

Is it clear how to initialize the default for c as it depends on one value
of "a" or the other?

Of course, you could just make multiple settings an error rather than
choosing an arbitrary fix.

R lists are more like a BAG data structure than a SET.

-Original Message-
From: R-package-devel  On Behalf Of
Vincent van Hees
Sent: Monday, November 8, 2021 11:25 AM
To: Duncan Murdoch 
Cc: r-package-devel@r-project.org
Subject: Re: [R-pkg-devel] R feature suggestion: Duplicated function
arguments check

Thanks Duncan, I have tried to make a minimalistic example:

myfun = function(...) {
  input = list(...)
  mysum = function(A = c(), B= c()) {
return(A+B)
  }
  if ("A" %in% names(input) & "B" %in% names(input)) {
print(mysum(A = input$A, B = input$B))
  }
}

# test:
> myfun(A = 1, B = 2, B = 4)
[1] 3

# So, the second B is ignored.



On Mon, 8 Nov 2021 at 17:03, Duncan Murdoch 
wrote:

> On 08/11/2021 10:29 a.m., Vincent van Hees wrote:
> > Not sure if this is the best place to post this message, as it is 
> > more
> of a
> > suggestion than a question.
> >
> > When an R function accepts more than a handful of arguments there is 
> > the risk that users accidentally provide arguments twice, e.g 
> > myfun(A=1, B=2, C=4, D=5, A=7), and if those two values are not the 
> > same it can have frustrating side-effects. To catch this I am 
> > planning to add a check for duplicated arguments, as shown below, in 
> > one of my own functions. I am
> now
> > wondering whether this would be a useful feature for R itself to 
> > operate
> in
> > the background when running any R function that has more than a 
> > certain number of input arguments.
> >
> > Cheers, Vincent
> >
> > myfun = function(...) {
> >#check input arguments for duplicate assignments
> >input = list(...)
> >if (length(input) > 0) {
> >  argNames = names(input)
> >  dupArgNames = duplicated(argNames)
> >  if (any(dupArgNames)) {
> >for (dupi in unique(argNames[dupArgNames])) {
> >  dupArgValues = input[which(argNames %in% dupi)]
> >  if (all(dupArgValues == dupArgValues[[1]])) { # double
> arguments,
> > but no confusion about what value should be
> >warning(paste0("\nArgument ", dupi, " has been provided 
> > more
> than
> > once in the same call, which is ambiguous. Please fix."))
> >  } else { # double arguments, and confusion about what value
> should
> > be,
> >stop(paste0("\nArgument ", dupi, " has been provided more 
> > than once in the same call, which is ambiguous. Please fix."))
> >  }
> >}
> >  }
> >}
> ># rest of code...
> > }
> >
>
> Could you give an example where this is needed?  If a named argument 
> is duplicated, R will catch that and give an error message:
>
>> f(a=1, b=2, a=3)
>Error in f(a = 1, b = 2, a = 3) :
>  formal argument "a" matched by multiple actual arguments
>
> So this can only happen when it is an argument in the ... list that is 
> duplicated.  But usually those are passed to some other function, so 
> something like
>
>g <- function(...) f(...)
>
> would also catch the duplication in g(a=1, b=2, a=3):
>
>> g(a=1, b=2, a=3)
>Error in f(...) :
>  formal argument "a" matched by multiple actual arguments
>
> The only case where I can see this getting by is where you are never 
> using those arguments to match any formal argument, e.g.
>
>list(a=1, b=2, a=3)
>
> Maybe this should have been made illegal when R was created, but I 
> think it's too late to outlaw now:  I'm sure there are lots of people 
> making use of this.
>
> Or am I missing something?
>
> Duncan Murdoch
>

[[alternative HTML version deleted]]

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] R feature suggestion: Duplicated function arguments check

2021-11-08 Thread Avi Gross via R-package-devel
Duncan,

This may not be the place to discuss this so I will be brief.

The question is whether it should be some kind of error to call a function
with two named arguments that are the same.

I can think of a perhaps valid use when a function expects to take the first
few arguments for personal use and then uses ... to pass the rest along to
other functions it calls.

so in your case, slightly extended:

f(a=1, b=2, a=3, c=-5)

The function might pass along to another function:
other(arg, ...)
which would be seen as:
other(arg, a=3, c=-5)

There can of course be other ways to get this result but probably not as
simple. And note this can go several layers deep as various functions call
each other and each has a different need and even meaning for a=something.

Avi
-Original Message-
From: R-package-devel  On Behalf Of
Duncan Murdoch
Sent: Monday, November 8, 2021 11:04 AM
To: Vincent van Hees ;
r-package-devel@r-project.org
Subject: Re: [R-pkg-devel] R feature suggestion: Duplicated function
arguments check

On 08/11/2021 10:29 a.m., Vincent van Hees wrote:
> Not sure if this is the best place to post this message, as it is more 
> of a suggestion than a question.
> 
> When an R function accepts more than a handful of arguments there is 
> the risk that users accidentally provide arguments twice, e.g 
> myfun(A=1, B=2, C=4, D=5, A=7), and if those two values are not the 
> same it can have frustrating side-effects. To catch this I am planning 
> to add a check for duplicated arguments, as shown below, in one of my 
> own functions. I am now wondering whether this would be a useful 
> feature for R itself to operate in the background when running any R 
> function that has more than a certain number of input arguments.
> 
> Cheers, Vincent
> 
> myfun = function(...) {
>#check input arguments for duplicate assignments
>input = list(...)
>if (length(input) > 0) {
>  argNames = names(input)
>  dupArgNames = duplicated(argNames)
>  if (any(dupArgNames)) {
>for (dupi in unique(argNames[dupArgNames])) {
>  dupArgValues = input[which(argNames %in% dupi)]
>  if (all(dupArgValues == dupArgValues[[1]])) { # double 
> arguments, but no confusion about what value should be
>warning(paste0("\nArgument ", dupi, " has been provided 
> more than once in the same call, which is ambiguous. Please fix."))
>  } else { # double arguments, and confusion about what value 
> should be,
>stop(paste0("\nArgument ", dupi, " has been provided more 
> than once in the same call, which is ambiguous. Please fix."))
>  }
>}
>  }
>}
># rest of code...
> }
> 

Could you give an example where this is needed?  If a named argument is
duplicated, R will catch that and give an error message:

   > f(a=1, b=2, a=3)
   Error in f(a = 1, b = 2, a = 3) :
 formal argument "a" matched by multiple actual arguments

So this can only happen when it is an argument in the ... list that is
duplicated.  But usually those are passed to some other function, so
something like

   g <- function(...) f(...)

would also catch the duplication in g(a=1, b=2, a=3):

   > g(a=1, b=2, a=3)
   Error in f(...) :
 formal argument "a" matched by multiple actual arguments

The only case where I can see this getting by is where you are never using
those arguments to match any formal argument, e.g.

   list(a=1, b=2, a=3)

Maybe this should have been made illegal when R was created, but I think
it's too late to outlaw now:  I'm sure there are lots of people making use
of this.

Or am I missing something?

Duncan Murdoch

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] [External] Re: What is a "retired"package?

2021-09-22 Thread Avi Gross via R-package-devel
Philosophy aside, albeit not uninteresting, I am wondering about the
etiquette of developing a package and then years later dealing with how to
have it replaced carefully. Do creators and maintainers have any obligation
and especially when there is a large remaining embedded base of users. We
may have quite a few Y2K type problems in the sense that some people cannot
easily change what is being used. Other languages, like Python, have been
dealing with how the newer language features (version 3) have serious
incompatibilities with earlier versions and yet some stay with what they
have.

Hadley Wickham for example, has been involved in multiple packages including
cases like ggplot where it was replaced by another package with enough
incompatibilities that it might merit another name. I am not sure what
exactly was in plyr when it stopped being changed but in some ways the dplyr
package seems to focus on data.frames and plyr was more general. And, I
suspect, dplyr also tried to do things consistent with new design approaches
such as standardizing where arguments to a function go. It may well be
faster when used as planned.

But as a possibility, I suspect you could theoretically take the source code
for a package that has largely been replaced by others and sometimes make a
sort of compatibility version that consists largely of pointers to other
packages.

Specifically, the documentation could contain a section that suggests
alternatives to use. I suspect quite a few of the included functions may be
available in base R or another commonly used package (such as the tidyverse
collection) and just using the new one, perhaps with some alteration in how
it is called, might help guide existing users away to something more likely
to be maintained.

And sometimes, it might be weirdly possible to have a volunteer do something
a tad odd and set up a way to replace the functions in the package. A
function call like f(z, data) might simply be mapped into a call to
other::g(data, z, flag=FALSE) if that made sense. Other fairly small
wrappers might do more such re-direction. Obviously, this would be of
limited use if other packages would need to be loaded. I can imagine leaving
a package intact and adding a new function with a name like supercede() that
would make such a re-arrangement when asked to.

The user would normally call:

library(plyr)
plyr::supercede()

Without that additional line, nothing changes. But after calling it, you may
now be in a partial compatibility mode.

I now retire without being superseded.

-Original Message-
From: R-package-devel  On Behalf Of
Martin Maechler
Sent: Wednesday, September 22, 2021 3:39 AM
To: Lenth, Russell V 
Cc: r-package-devel@r-project.org
Subject: Re: [R-pkg-devel] [External] Re: What is a "retired"package?

> Lenth, Russell V 
> on Tue, 21 Sep 2021 18:43:07 + writes:

> As I suspected, and a good point. But please note that the term
"retired" causes angst, and it may be good to change that to "superceded" or
something else.

well,  some of us will  become "retired" somewhere in the future rather than
"superseded" .. ;-)

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel