-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base_ops
are empty - arithmetic fails e.g. when extending class_double
#320
Comments
What would you expect the default method to do? |
The same it does e.g. for
|
Should the result still have an S7 class? I assume not. |
Yes, I think it should, when we are talking about the "default" method: It does keep the class in S3 and S4, too, when combined with a simple numeric
Interestingly, that changes when the other vector is of different length, in the same way for S3 and S4:
and ditto for S3:
|
I think this is something that's worth more discussion in a call. It's not clear to me that preserving the existing class (and properties) is the right default because the transformation might break expected relationships between the data and the attributes. There's some question of whether we want to provide a default implementation that's sometimes wrong (forcing the implementor to carefully consider all existing generics and whether the behaviour is correct) or never provide a default so that the implementor is forced to. Either way, we should consider this with the behaviour for generics like |
I think this puts all the current inconsistencies in one place: library(S7)
foo_S3 <- structure(1, class = "foo")
class(foo_S3 + 1)
#> [1] "foo"
class(foo_S3 + c(1, 2))
#> [1] "numeric"
class(sin(foo_S3))
#> [1] "foo"
foo_S7 <- new_class("foo", parent = class_double)(1)
class(foo_S7 + 1)
#> Error: Can't find method for generic `+(e1, e2)`:
#> - e1: <foo>
#> - e2: <double>
class(foo_S7 + c(1, 2))
#> Error: Can't find method for generic `+(e1, e2)`:
#> - e1: <foo>
#> - e2: <double>
class(sin(foo_S7))
#> [1] "foo" "double" "S7_object" Created on 2023-10-13 with reprex v2.0.2 |
Probably easiest to argue that it should be consistent with S3. You are inheriting from an base type so that you are choosing the chaos. If you don't want the chaos then:
|
A simple class & object
x
extending double does work insin(x)
but not withx + 1
orx < 3
, because the (internal)base_ops
all have no methods defined.It is easiest to see in an example {latest version of
S7
}:Via
traceback()
we are quickly lead that it is caused by the S7-internalbase_ops
being "empty", i.e., not having any methods defined.whereas evidently sin() or sinpi() etc are all defined correctly.
The text was updated successfully, but these errors were encountered: