Re: [R] A technical question on methods for "+"
On Fri, Dec 3, 2021 at 3:14 AM Bert Gunter wrote: > > Those are both helpful comments. Would it not be useful to say > something along these lines in ?class. ? > The key point I missed is that there often(but not always) must be an > *explicit* class **attribute** for method dispatch; and class() does > not indicate whether its value is explicit or not (just recapitulating > what you both said). Ops methods are such a case (for anything but > classes inheriting from numeric?), and perhaps a mention there might > be useful, too. ?Ops already says Note that a method will be used for one of these groups or one of its members _only_ if it corresponds to a '"class"' attribute, as the internal code dispatches on 'oldClass' and not on 'class'. This is for efficiency: having to dispatch on, say, 'Ops.integer' would be too slow. Can you suggest some text to make this clearer? FWIW, the following seems to work as you would want (at the cost of global inefficiency): `+` <- function(e1, e2) UseMethod("+") `+.default` <- function(e1, e2 = 0) .Primitive("+")(e1, e2) and then "+.character" <- function(e1, e2) paste0(e1, e2) > "jan" + "feb" [1] "janfeb" > Reduce("+", letters) [1] "abcdefghijklmnopqrstuvwxyz" -Deepayan > Again, thanks for the help. > > Bert > > On Thu, Dec 2, 2021 at 12:40 PM Duncan Murdoch > wrote: > > > > The reason for this behaviour is that finding methods is a lot slower > > than just evaluating the built-in function. So R takes the time to > > determine if there's an attribute named "class" attached, but doesn't go > > searching further if there isn't one. > > > > Duncan Murdoch > > > > On 02/12/2021 3:10 p.m., Andrew Simmons wrote: > > > This is because + dispatches on the class attribute, which a string like > > > "test" has set to NULL, so it doesn't dispatch. You can add the class > > > yourself like structure("test", class = "character") and that should work. > > > > > > I'm not sure where it's explained, but most primitive functions dispatch > > > on > > > the class attribute, which is different from UseMethod which calls class() > > > if the class attribute is NULL. > > > > > > I think if you want to define something like what you have written, you > > > could write a function `%+%` use that instead > > > > > > On Thu, Dec 2, 2021, 14:32 Bert Gunter wrote: > > > > > >> ... and probably a dumb one and almost certainly not of interest to > > >> most R users. But anyway... > > >> > > >> ?"+" says: > > >> "The unary and binary arithmetic operators are generic functions: > > >> methods can be written for them individually or via the Ops group > > >> generic function. " > > >> > > >> So: > > >> "+.character" <- function(e1, e2) paste0(e1, e2) > > >> ## but this doesn't 'work': > > >>> "a" + "b" > > >> Error in "a" + "b" : non-numeric argument to binary operator > > >> > > >> ## but explicitly invoking the method does 'work' : > > >>> "+.character"('a','b') > > >> [1] "ab" > > >> > > >> ##Note also: > > >>> methods("+") > > >> [1] +.character +.Date +.IDate*+.POSIXt+.trellis* > > >> > > >> So what am I failing to understand? > > >> Thanks. > > >> > > >> Bert Gunter > > >> > > >> __ > > >> R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see > > >> 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. > > >> > > > > > > [[alternative HTML version deleted]] > > > > > > __ > > > R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see > > > 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. > > > > > > > __ > R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see > 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. __ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see 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.
Re: [R] A technical question on methods for "+"
Those are both helpful comments. Would it not be useful to say something along these lines in ?class. ? The key point I missed is that there often(but not always) must be an *explicit* class **attribute** for method dispatch; and class() does not indicate whether its value is explicit or not (just recapitulating what you both said). Ops methods are such a case (for anything but classes inheriting from numeric?), and perhaps a mention there might be useful, too. Again, thanks for the help. Bert On Thu, Dec 2, 2021 at 12:40 PM Duncan Murdoch wrote: > > The reason for this behaviour is that finding methods is a lot slower > than just evaluating the built-in function. So R takes the time to > determine if there's an attribute named "class" attached, but doesn't go > searching further if there isn't one. > > Duncan Murdoch > > On 02/12/2021 3:10 p.m., Andrew Simmons wrote: > > This is because + dispatches on the class attribute, which a string like > > "test" has set to NULL, so it doesn't dispatch. You can add the class > > yourself like structure("test", class = "character") and that should work. > > > > I'm not sure where it's explained, but most primitive functions dispatch on > > the class attribute, which is different from UseMethod which calls class() > > if the class attribute is NULL. > > > > I think if you want to define something like what you have written, you > > could write a function `%+%` use that instead > > > > On Thu, Dec 2, 2021, 14:32 Bert Gunter wrote: > > > >> ... and probably a dumb one and almost certainly not of interest to > >> most R users. But anyway... > >> > >> ?"+" says: > >> "The unary and binary arithmetic operators are generic functions: > >> methods can be written for them individually or via the Ops group > >> generic function. " > >> > >> So: > >> "+.character" <- function(e1, e2) paste0(e1, e2) > >> ## but this doesn't 'work': > >>> "a" + "b" > >> Error in "a" + "b" : non-numeric argument to binary operator > >> > >> ## but explicitly invoking the method does 'work' : > >>> "+.character"('a','b') > >> [1] "ab" > >> > >> ##Note also: > >>> methods("+") > >> [1] +.character +.Date +.IDate*+.POSIXt+.trellis* > >> > >> So what am I failing to understand? > >> Thanks. > >> > >> Bert Gunter > >> > >> __ > >> R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see > >> 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. > >> > > > > [[alternative HTML version deleted]] > > > > __ > > R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see > > 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. > > > __ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see 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.
Re: [R] A technical question on methods for "+"
The reason for this behaviour is that finding methods is a lot slower than just evaluating the built-in function. So R takes the time to determine if there's an attribute named "class" attached, but doesn't go searching further if there isn't one. Duncan Murdoch On 02/12/2021 3:10 p.m., Andrew Simmons wrote: This is because + dispatches on the class attribute, which a string like "test" has set to NULL, so it doesn't dispatch. You can add the class yourself like structure("test", class = "character") and that should work. I'm not sure where it's explained, but most primitive functions dispatch on the class attribute, which is different from UseMethod which calls class() if the class attribute is NULL. I think if you want to define something like what you have written, you could write a function `%+%` use that instead On Thu, Dec 2, 2021, 14:32 Bert Gunter wrote: ... and probably a dumb one and almost certainly not of interest to most R users. But anyway... ?"+" says: "The unary and binary arithmetic operators are generic functions: methods can be written for them individually or via the Ops group generic function. " So: "+.character" <- function(e1, e2) paste0(e1, e2) ## but this doesn't 'work': "a" + "b" Error in "a" + "b" : non-numeric argument to binary operator ## but explicitly invoking the method does 'work' : "+.character"('a','b') [1] "ab" ##Note also: methods("+") [1] +.character +.Date +.IDate*+.POSIXt+.trellis* So what am I failing to understand? Thanks. Bert Gunter __ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see 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. [[alternative HTML version deleted]] __ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see 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. __ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see 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.
Re: [R] A technical question on methods for "+"
class() does not always return the class attribute, try something more like attr(, "class"), you'll see what I mean On Thu, Dec 2, 2021, 15:23 Bert Gunter wrote: > "This is because + dispatches on the class attribute, which a string > like "test" has set to NULL" > Not true. > > > class('test') > [1] "character" > > But apparently, as Denes and Jeff said, the class must be explicitly > set, rather than relying on its built-in/implicit type. > > With the above hint, I looked up what ?class had to say. It is: > > "Note that for objects x of an implicit (or an S4) class, when a (S3) > generic function foo(x) is called, method dispatch may use more > classes than are returned by class(x), e.g., for a numeric matrix, the > foo.numeric() method may apply. The exact full character vector of the > classes which UseMethod() uses, is available as .class2(x) since R > version 4.0.0. (This also applies to S4 objects when S3 dispatch is > considered, see below.)" > > I think this is the "official" explanation, but I find it rather opaque. > > Thanks to all for your Help in finding the explanation. Much appreciated. > > Bert > > On Thu, Dec 2, 2021 at 12:10 PM Andrew Simmons wrote: > > > > This is because + dispatches on the class attribute, which a string like > "test" has set to NULL, so it doesn't dispatch. You can add the class > yourself like structure("test", class = "character") and that should work. > > > > I'm not sure where it's explained, but most primitive functions dispatch > on the class attribute, which is different from UseMethod which calls > class() if the class attribute is NULL. > > > > I think if you want to define something like what you have written, you > could write a function `%+%` use that instead > > > > On Thu, Dec 2, 2021, 14:32 Bert Gunter wrote: > >> > >> ... and probably a dumb one and almost certainly not of interest to > >> most R users. But anyway... > >> > >> ?"+" says: > >> "The unary and binary arithmetic operators are generic functions: > >> methods can be written for them individually or via the Ops group > >> generic function. " > >> > >> So: > >> "+.character" <- function(e1, e2) paste0(e1, e2) > >> ## but this doesn't 'work': > >> > "a" + "b" > >> Error in "a" + "b" : non-numeric argument to binary operator > >> > >> ## but explicitly invoking the method does 'work' : > >> > "+.character"('a','b') > >> [1] "ab" > >> > >> ##Note also: > >> > methods("+") > >> [1] +.character +.Date +.IDate*+.POSIXt+.trellis* > >> > >> So what am I failing to understand? > >> Thanks. > >> > >> Bert Gunter > >> > >> __ > >> R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see > >> 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. > [[alternative HTML version deleted]] __ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see 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.
Re: [R] A technical question on methods for "+"
"This is because + dispatches on the class attribute, which a string like "test" has set to NULL" Not true. > class('test') [1] "character" But apparently, as Denes and Jeff said, the class must be explicitly set, rather than relying on its built-in/implicit type. With the above hint, I looked up what ?class had to say. It is: "Note that for objects x of an implicit (or an S4) class, when a (S3) generic function foo(x) is called, method dispatch may use more classes than are returned by class(x), e.g., for a numeric matrix, the foo.numeric() method may apply. The exact full character vector of the classes which UseMethod() uses, is available as .class2(x) since R version 4.0.0. (This also applies to S4 objects when S3 dispatch is considered, see below.)" I think this is the "official" explanation, but I find it rather opaque. Thanks to all for your Help in finding the explanation. Much appreciated. Bert On Thu, Dec 2, 2021 at 12:10 PM Andrew Simmons wrote: > > This is because + dispatches on the class attribute, which a string like > "test" has set to NULL, so it doesn't dispatch. You can add the class > yourself like structure("test", class = "character") and that should work. > > I'm not sure where it's explained, but most primitive functions dispatch on > the class attribute, which is different from UseMethod which calls class() if > the class attribute is NULL. > > I think if you want to define something like what you have written, you could > write a function `%+%` use that instead > > On Thu, Dec 2, 2021, 14:32 Bert Gunter wrote: >> >> ... and probably a dumb one and almost certainly not of interest to >> most R users. But anyway... >> >> ?"+" says: >> "The unary and binary arithmetic operators are generic functions: >> methods can be written for them individually or via the Ops group >> generic function. " >> >> So: >> "+.character" <- function(e1, e2) paste0(e1, e2) >> ## but this doesn't 'work': >> > "a" + "b" >> Error in "a" + "b" : non-numeric argument to binary operator >> >> ## but explicitly invoking the method does 'work' : >> > "+.character"('a','b') >> [1] "ab" >> >> ##Note also: >> > methods("+") >> [1] +.character +.Date +.IDate*+.POSIXt+.trellis* >> >> So what am I failing to understand? >> Thanks. >> >> Bert Gunter >> >> __ >> R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see >> 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. __ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see 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.
Re: [R] A technical question on methods for "+"
This is because + dispatches on the class attribute, which a string like "test" has set to NULL, so it doesn't dispatch. You can add the class yourself like structure("test", class = "character") and that should work. I'm not sure where it's explained, but most primitive functions dispatch on the class attribute, which is different from UseMethod which calls class() if the class attribute is NULL. I think if you want to define something like what you have written, you could write a function `%+%` use that instead On Thu, Dec 2, 2021, 14:32 Bert Gunter wrote: > ... and probably a dumb one and almost certainly not of interest to > most R users. But anyway... > > ?"+" says: > "The unary and binary arithmetic operators are generic functions: > methods can be written for them individually or via the Ops group > generic function. " > > So: > "+.character" <- function(e1, e2) paste0(e1, e2) > ## but this doesn't 'work': > > "a" + "b" > Error in "a" + "b" : non-numeric argument to binary operator > > ## but explicitly invoking the method does 'work' : > > "+.character"('a','b') > [1] "ab" > > ##Note also: > > methods("+") > [1] +.character +.Date +.IDate*+.POSIXt+.trellis* > > So what am I failing to understand? > Thanks. > > Bert Gunter > > __ > R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see > 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. > [[alternative HTML version deleted]] __ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see 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.
Re: [R] A technical question on methods for "+"
I think the fact that character is a built-in type rather than an S3 class has something to do with it. On December 2, 2021 11:31:47 AM PST, Bert Gunter wrote: >... and probably a dumb one and almost certainly not of interest to >most R users. But anyway... > >?"+" says: >"The unary and binary arithmetic operators are generic functions: >methods can be written for them individually or via the Ops group >generic function. " > >So: >"+.character" <- function(e1, e2) paste0(e1, e2) >## but this doesn't 'work': >> "a" + "b" >Error in "a" + "b" : non-numeric argument to binary operator > >## but explicitly invoking the method does 'work' : >> "+.character"('a','b') >[1] "ab" > >##Note also: >> methods("+") >[1] +.character +.Date +.IDate*+.POSIXt+.trellis* > >So what am I failing to understand? >Thanks. > >Bert Gunter > >__ >R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see >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. -- Sent from my phone. Please excuse my brevity. __ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see 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.
[R] A technical question on methods for "+"
... and probably a dumb one and almost certainly not of interest to most R users. But anyway... ?"+" says: "The unary and binary arithmetic operators are generic functions: methods can be written for them individually or via the Ops group generic function. " So: "+.character" <- function(e1, e2) paste0(e1, e2) ## but this doesn't 'work': > "a" + "b" Error in "a" + "b" : non-numeric argument to binary operator ## but explicitly invoking the method does 'work' : > "+.character"('a','b') [1] "ab" ##Note also: > methods("+") [1] +.character +.Date +.IDate*+.POSIXt+.trellis* So what am I failing to understand? Thanks. Bert Gunter __ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see 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.