Hi All,
I have a function (not a method), sort_by(), in one of my packages. A
new method with the same name was introduced in the recent versions of
R (4.4.0 or 4.4.1, I forgot which one), resulting in potential
conflict in users' code.
Certainly, users can simply use pkg_name::function_name() to solve the
conflict. However, I would like to be consistent with base R and so I
am thinking about converting my function to a method for the class for
which my function is intended to work on (e.g, est_table).
However, my function has arguments different from those in the base R sort_by():
Base R:
sort_by(x, y, ...)
My function:
sort_by(
object,
by = c("op", "lhs", "rhs"),
op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
number_rows = TRUE
)
If I write the function sort_by.est_table(), I would need to match the
argument names of the base R sort_by(). However, I think it is a bad
idea to rename the arguments in my function and it will break existing
code.
Any suggestions on how I should proceed? Is keeping my function as-is
a better option? Name conflict is not unusual across packages and so
users need to learn how to solve this problem anyway. Nevertheless, if
possible, I would like to solve the conflict internally such that
users do not need to do anything.
Regards,
Shu Fai Cheung
[R-pkg-devel] A function in one of my package is now a method in base R
6 messages · Shu Fai Cheung, Duncan Murdoch, Deepayan Sarkar +1 more
On 2024-08-02 10:35 a.m., Shu Fai Cheung wrote:
Hi All,
I have a function (not a method), sort_by(), in one of my packages. A
new method with the same name was introduced in the recent versions of
R (4.4.0 or 4.4.1, I forgot which one), resulting in potential
conflict in users' code.
Certainly, users can simply use pkg_name::function_name() to solve the
conflict. However, I would like to be consistent with base R and so I
am thinking about converting my function to a method for the class for
which my function is intended to work on (e.g, est_table).
However, my function has arguments different from those in the base R sort_by():
Base R:
sort_by(x, y, ...)
My function:
sort_by(
object,
by = c("op", "lhs", "rhs"),
op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
number_rows = TRUE
)
If I write the function sort_by.est_table(), I would need to match the
argument names of the base R sort_by(). However, I think it is a bad
idea to rename the arguments in my function and it will break existing
code.
Any suggestions on how I should proceed? Is keeping my function as-is
a better option? Name conflict is not unusual across packages and so
users need to learn how to solve this problem anyway. Nevertheless, if
possible, I would like to solve the conflict internally such that
users do not need to do anything.
I think it's impossible to avoid some inconvenience to your users.
Here's what I'd suggest:
- Create a method for base::sort_by(), as you suggested you could. Use
the generic's variable names for compatibility, but also add your extra
variable names as additional arguments, e.g.
sort_by.est_table <- function(x, y, object,
by = c("op", "lhs", "rhs"),
op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
number_rows = TRUE, ...) {
# This test seems unlikely: how would we have dispatch here if we
specified object explicitly?
if (!missing(object) {
if (!missing(x))
stop("both x and object specified!")
x <- object
}
# This one is more likely to do something:
if (!missing(by)) {
if (!missing(y))
stop("both y and by specified!")
y <- by
}
# Now proceed using x and y
...
}
- Create a separate function, e.g. sort_by_old() which is exactly
compatible with your old sort_by(). For users where the above doesn't
just work, they can switch to sort_by_old().
Duncan Murdoch
I haven't thought about this carefully, but shouldn't this mostly work?
sort_by.est_table <- function(x, y = c("op", "lhs", "rhs"),
object = x,
by = y,
op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
number_rows = TRUE, ...) {
<code unchanged>
}
-Deepayan
On Sat, 3 Aug 2024 at 00:13, Duncan Murdoch <murdoch.duncan at gmail.com>
wrote:
On 2024-08-02 10:35 a.m., Shu Fai Cheung wrote:
Hi All, I have a function (not a method), sort_by(), in one of my packages. A new method with the same name was introduced in the recent versions of R (4.4.0 or 4.4.1, I forgot which one), resulting in potential conflict in users' code. Certainly, users can simply use pkg_name::function_name() to solve the conflict. However, I would like to be consistent with base R and so I am thinking about converting my function to a method for the class for which my function is intended to work on (e.g, est_table). However, my function has arguments different from those in the base R
sort_by():
Base R:
sort_by(x, y, ...)
My function:
sort_by(
object,
by = c("op", "lhs", "rhs"),
op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
number_rows = TRUE
)
If I write the function sort_by.est_table(), I would need to match the
argument names of the base R sort_by(). However, I think it is a bad
idea to rename the arguments in my function and it will break existing
code.
Any suggestions on how I should proceed? Is keeping my function as-is
a better option? Name conflict is not unusual across packages and so
users need to learn how to solve this problem anyway. Nevertheless, if
possible, I would like to solve the conflict internally such that
users do not need to do anything.
I think it's impossible to avoid some inconvenience to your users.
Here's what I'd suggest:
- Create a method for base::sort_by(), as you suggested you could. Use
the generic's variable names for compatibility, but also add your extra
variable names as additional arguments, e.g.
sort_by.est_table <- function(x, y, object,
by = c("op", "lhs", "rhs"),
op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
number_rows = TRUE, ...) {
# This test seems unlikely: how would we have dispatch here if we
specified object explicitly?
if (!missing(object) {
if (!missing(x))
stop("both x and object specified!")
x <- object
}
# This one is more likely to do something:
if (!missing(by)) {
if (!missing(y))
stop("both y and by specified!")
y <- by
}
# Now proceed using x and y
...
}
- Create a separate function, e.g. sort_by_old() which is exactly
compatible with your old sort_by(). For users where the above doesn't
just work, they can switch to sort_by_old().
Duncan Murdoch
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Thanks a lot for both suggestions! I haven't thought about these approaches, They may solve my problem without breaking existing code. I may just keep the original arguments for backward compatibility. Coincidentally, "object" and "by" have the same meanings as "x" and "y" in base::sort_by() and so the matching makes sense. Regards, Shu Fai Cheung On Sat, Aug 3, 2024 at 7:13?PM Deepayan Sarkar
<deepayan.sarkar at gmail.com> wrote:
I haven't thought about this carefully, but shouldn't this mostly work?
sort_by.est_table <- function(x, y = c("op", "lhs", "rhs"),
object = x,
by = y,
op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
number_rows = TRUE, ...) {
<code unchanged>
}
-Deepayan
On Sat, 3 Aug 2024 at 00:13, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:
On 2024-08-02 10:35 a.m., Shu Fai Cheung wrote:
Hi All,
I have a function (not a method), sort_by(), in one of my packages. A
new method with the same name was introduced in the recent versions of
R (4.4.0 or 4.4.1, I forgot which one), resulting in potential
conflict in users' code.
Certainly, users can simply use pkg_name::function_name() to solve the
conflict. However, I would like to be consistent with base R and so I
am thinking about converting my function to a method for the class for
which my function is intended to work on (e.g, est_table).
However, my function has arguments different from those in the base R sort_by():
Base R:
sort_by(x, y, ...)
My function:
sort_by(
object,
by = c("op", "lhs", "rhs"),
op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
number_rows = TRUE
)
If I write the function sort_by.est_table(), I would need to match the
argument names of the base R sort_by(). However, I think it is a bad
idea to rename the arguments in my function and it will break existing
code.
Any suggestions on how I should proceed? Is keeping my function as-is
a better option? Name conflict is not unusual across packages and so
users need to learn how to solve this problem anyway. Nevertheless, if
possible, I would like to solve the conflict internally such that
users do not need to do anything.
I think it's impossible to avoid some inconvenience to your users.
Here's what I'd suggest:
- Create a method for base::sort_by(), as you suggested you could. Use
the generic's variable names for compatibility, but also add your extra
variable names as additional arguments, e.g.
sort_by.est_table <- function(x, y, object,
by = c("op", "lhs", "rhs"),
op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
number_rows = TRUE, ...) {
# This test seems unlikely: how would we have dispatch here if we
specified object explicitly?
if (!missing(object) {
if (!missing(x))
stop("both x and object specified!")
x <- object
}
# This one is more likely to do something:
if (!missing(by)) {
if (!missing(y))
stop("both y and by specified!")
y <- by
}
# Now proceed using x and y
...
}
- Create a separate function, e.g. sort_by_old() which is exactly
compatible with your old sort_by(). For users where the above doesn't
just work, they can switch to sort_by_old().
Duncan Murdoch
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
The problem with that is a call like sort_by( object = foo, by = bar ) wouldn't be dispatched to the est_table method when foo is an est_table object, it would give a "argument 'x' is missing" kind of error. It would be fine for sort_by( foo, bar ) but would also mess up on sort_by( foo, bar, priority ) Duncan Murdoch
On 2024-08-03 7:13 a.m., Deepayan Sarkar wrote:
I haven't thought about this carefully, but shouldn't this mostly work?
? sort_by.est_table <- function(x, y = c("op", "lhs", "rhs"),
? ? object = x,
? ? by = y,
? ? op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
? ? number_rows = TRUE, ...)
<code unchanged>
}
-Deepayan
On Sat, 3 Aug 2024 at 00:13, Duncan Murdoch <murdoch.duncan at gmail.com
<mailto:murdoch.duncan at gmail.com>> wrote:
On 2024-08-02 10:35 a.m., Shu Fai Cheung wrote:
> Hi All,
>
> I have a function (not a method), sort_by(), in one of my packages. A
> new method with the same name was introduced in the recent
versions of
> R (4.4.0 or 4.4.1, I forgot which one), resulting in potential
> conflict in users' code.
>
> Certainly, users can simply use pkg_name::function_name() to
solve the
> conflict. However, I would like to be consistent with base R and so I
> am thinking about converting my function to a method for the
class for
> which my function is intended to work on (e.g, est_table).
>
> However, my function has arguments different from those in the
base R sort_by():
>
> Base R:
>
> sort_by(x, y, ...)
>
> My function:
>
> sort_by(
>? ? object,
>? ? by = c("op", "lhs", "rhs"),
>? ? op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
>? ? number_rows = TRUE
> )
>
> If I write the function sort_by.est_table(), I would need to
match the
> argument names of the base R sort_by(). However, I think it is a bad
> idea to rename the arguments in my function and it will break
existing
> code.
>
> Any suggestions on how I should proceed? Is keeping my function as-is
> a better option? Name conflict is not unusual across packages and so
> users need to learn how to solve this problem anyway.
Nevertheless, if
> possible, I would like to solve the conflict internally such that
> users do not need to do anything.
I think it's impossible to avoid some inconvenience to your users.
Here's what I'd suggest:
- Create a method for base::sort_by(), as you suggested you could.? Use
the generic's variable names for compatibility, but also add your extra
variable names as additional arguments, e.g.
? sort_by.est_table <- function(x, y, object,
? ? by = c("op", "lhs", "rhs"),
? ? op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
? ? number_rows = TRUE, ...) {
? ?# This test seems unlikely:? how would we have dispatch here if we
specified object explicitly?
? ?if (!missing(object) {
? ? ?if (!missing(x))
? ? ? ?stop("both x and object specified!")
? ? ?x <- object
? ?}
? ?# This one is more likely to do something:
? ?if (!missing(by)) {
? ? ?if (!missing(y))
? ? ? ?stop("both y and by specified!")
? ? ?y <- by
? ?}
? ?# Now proceed using x and y
? ?...
}
- Create a separate function, e.g. sort_by_old() which is exactly
compatible with your old sort_by().? For users where the above doesn't
just work, they can switch to sort_by_old().
Duncan Murdoch
______________________________________________
R-package-devel at r-project.org <mailto:R-package-devel at r-project.org>
mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel
<https://stat.ethz.ch/mailman/listinfo/r-package-devel>
Since the main problem is that in base-R's function your 'object' is called 'x', you could consider issuing an intermediate version of the package, where you strongly advise users not to name the first argument and to always name the remaining arguments. Also, make sure that your examples follow this advice. If the function is used by package authors, you could send them emails, telling them exactly what to change. After a year or so you could make the method following Duncan's advice. Since sort_by is in package 'base', packages that use your package will no longer need to import sort_by from your package. There are some further subtleties here that could be discussed if packages that import explicitly sort_by from your package exist. Georgi Boshnakov Sent from Outlook for Android<https://aka.ms/AAb9ysg>
From: R-package-devel <r-package-devel-bounces at r-project.org> on behalf of Duncan Murdoch <murdoch.duncan at gmail.com>
Sent: Friday, August 2, 2024 7:43:46 pm
To: Shu Fai Cheung <shufai.cheung at gmail.com>; r-package-devel at r-project.org <r-package-devel at r-project.org>
Subject: Re: [R-pkg-devel] A function in one of my package is now a method in base R
Sent: Friday, August 2, 2024 7:43:46 pm
To: Shu Fai Cheung <shufai.cheung at gmail.com>; r-package-devel at r-project.org <r-package-devel at r-project.org>
Subject: Re: [R-pkg-devel] A function in one of my package is now a method in base R
On 2024-08-02 10:35 a.m., Shu Fai Cheung wrote:
> Hi All,
>
> I have a function (not a method), sort_by(), in one of my packages. A
> new method with the same name was introduced in the recent versions of
> R (4.4.0 or 4.4.1, I forgot which one), resulting in potential
> conflict in users' code.
>
> Certainly, users can simply use pkg_name::function_name() to solve the
> conflict. However, I would like to be consistent with base R and so I
> am thinking about converting my function to a method for the class for
> which my function is intended to work on (e.g, est_table).
>
> However, my function has arguments different from those in the base R sort_by():
>
> Base R:
>
> sort_by(x, y, ...)
>
> My function:
>
> sort_by(
> object,
> by = c("op", "lhs", "rhs"),
> op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
> number_rows = TRUE
> )
>
> If I write the function sort_by.est_table(), I would need to match the
> argument names of the base R sort_by(). However, I think it is a bad
> idea to rename the arguments in my function and it will break existing
> code.
>
> Any suggestions on how I should proceed? Is keeping my function as-is
> a better option? Name conflict is not unusual across packages and so
> users need to learn how to solve this problem anyway. Nevertheless, if
> possible, I would like to solve the conflict internally such that
> users do not need to do anything.
I think it's impossible to avoid some inconvenience to your users.
Here's what I'd suggest:
- Create a method for base::sort_by(), as you suggested you could. Use
the generic's variable names for compatibility, but also add your extra
variable names as additional arguments, e.g.
sort_by.est_table <- function(x, y, object,
by = c("op", "lhs", "rhs"),
op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"),
number_rows = TRUE, ...) {
# This test seems unlikely: how would we have dispatch here if we
specified object explicitly?
if (!missing(object) {
if (!missing(x))
stop("both x and object specified!")
x <- object
}
# This one is more likely to do something:
if (!missing(by)) {
if (!missing(y))
stop("both y and by specified!")
y <- by
}
# Now proceed using x and y
...
}
- Create a separate function, e.g. sort_by_old() which is exactly
compatible with your old sort_by(). For users where the above doesn't
just work, they can switch to sort_by_old().
Duncan Murdoch
______________________________________________
R-package-devel at r-project.org mailing list
https://urldefense.com/v3/__https://stat.ethz.ch/mailman/listinfo/r-package-devel__;!!PDiH4ENfjr2_Jw!DMhcKnV6t06-gQP_syUMUckB9X-q2dwf-t0gwHnslUVystLyIK742SL2XYMJ-ugEvVxGfGLffUOBLR_lXvVhbltAha5tPmWPr6cdoQ$ [stat[.]ethz[.]ch]