Open hadley opened 2 years ago
The discussion in #245 made me wonder if static methods/associated functions would be useful. That would allow "alternative constructors" etc. to live inside the class. No idea if this is feasible, but I was thinking like:
range <- new_class("range",
properties = list(
start = class_numeric,
end = class_numeric
)
)
range@from <- new_generic("range@from", "x")
method(range@from, class_numeric) <- function(x) {
range(min(x), max(x))
}
range@from(1:5) == range(1L, 5L)
I notice something like this has been considered based on the note about "class methods that lack self" in #191.
The above idea is interesting and probably deserves its own issue. Since classes are objects, we would probably want some other syntax than @
for accessing static members. Maybe just $
.
So, what happened to this idea? I'm coming from other languages and this "functional oop" seems bizarre to me. I was looking into converting my 7 yo R code because I couldn't make heads and tails out of it. Frankly, I don't know if I'll be gaining much by rewriting if the methods and the class are separate and all over the place. The whole point of OOP, at least to me, is intuitiveness, readability and maintainability. None of that seems to apply to S7. You already have constructor; why not have methods defined in the class as well, instead of requiring the user go through the hoops of generic() and the method(), etc, and then invoke it like a stand-alone function? x.up() is much more readable than up(x), and I'll have easier time maintaining up() if it is encapsulated within x's class.
@tkinsf this is not the place to argue about functional vs encapsulated OO, but I'd strongly encourage you to learn more about functional OOP because IMO it's a great match for the types of problems you tend to solve in data science. One place to start might be https://adv-r.hadley.nz/oo-tradeoffs.html.
I take that this idea was shelved then? Thank you, I'll move on.
On Thu, Jan 11, 2024 at 5:27 AM Hadley Wickham @.***> wrote:
@tkinsf https://github.com/tkinsf this is not the place to argue about functional vs encapsulated OO, but I'd strongly encourage you to learn more about functional OOP because IMO it's a great match for the types of problems you tend to solve in data science. One place to start might be https://adv-r.hadley.nz/oo-tradeoffs.html.
— Reply to this email directly, view it on GitHub https://github.com/RConsortium/S7/issues/202#issuecomment-1887163803, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADU7KY6MCKFEKEBPE3B2KTDYN7SFZAVCNFSM5QEZGVA2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBYG4YTMMZYGAZQ . You are receiving this because you were mentioned.Message ID: @.***>
It turns out to be trivial (#191) to add encapsulated methods to R7 (i.e. methods that belong to the class/object):
The current trivial implementation:
Handles within package inheritance of methods. Cross-package inheritance needs a little more work to ensure that we don't take a dependency at build-time, rather than load-time (so that environments of the methods match the currently installed package). Would need to adjust
super()
implementation to support method access.Doesn't have particularly good performance. Prformance will improve a little with a base C implementation of
@
, but would require byte code compiler transformation for high speed.Currently mutability "just works" if you inherit from environment:
But a full implementation would need careful consideration of how
validate()
should work to ensure that objects aren't left in an invalid state.Overall, I'm pretty neutral on this proposal. There are some big upsides, but also some big downsides. Here are a few of the pros/cons that I've considered so far:
x@up()
is actually modifyingx
in place: this is potentially extremely confusing..
would be sufficient? Since they wouldn't be documented and wouldn't be suggested by auto-complete, it would be unlikely for uses to accidentally use them.