More work on being easily used by/incorporated into applications written in other languages, would perhaps be a more impactful thing to work on.
Personally I find it more expressive for general-purpose computation than Python. The "fs" library is much better at working with files and paths than Python "os" and the multiple other modules that can be needed to work with with typical filesystem operations -/ especially if you are working with more than one file at a time.
I would even say that each of the R object systems is more expressive and more flexible than the Python one. I suspect lazy evaluation is a part of this.
I’ve seen comics depicting the learning curve for R as having local minima beyond which there are further peaks and troughs of knowledge. A beginner might learn enough to get by, but find the code of someone on the other side of one of those peaks to be a foreign language.
Having your coders not understand each other is problematic in a production environment.
It could still be better, and sadly being in the stdlib means it probably won't be improved.
For example, we still need shutil.rmtree to recursively nuke a directory. The pathlib way of doing it is laborious and error prone: https://stackoverflow.com/questions/13118029/deleting-folder...
I had no idea R was lazy. Makes me wanna learn it now.
When you have an object, like `model <- lm(x~y)` or `my_hist <- hist(df$foo)`, you expected to be able to `plot` it or get a `summary`; you don't call `my_hist.summary`, you call `summary(my_hist)` and `plot(model)`. Many users never look further under the hood than this. And this fits nicely into piped workflows -- `lm(x~y) |> summary()` ends up being very natural, and when you fit in the tidyverse operators many very complex workflows end up being very easy to digest.
But when you do pull back the kimono it gets ugly fast. The teams involved in this are the right people who have been working to make R an amazing language mostly through enhancements to libraries, and now they're trying to push some of that functionality back into core R, which I think is fantastic.
R's mess of OOP systems works great, S3 is "fine" for just dispatching 'methods' based on attributes, one doesn't even know it's happening in base R ALL the time.
R flexibility also makes it possible to build your own class system. i.e. modern ggplot2 has its own ggproto object system.
R, like Common Lisp, uses an OOP system based on generic functions (well, one of many OOP systems in R, but that's a different topic), where the function handles dispatching to match the object.
Effectively instead of:
object.method()
you have: method(object)
So it works perfectly with the functional paradigm while still being capable of everything an object system is.The most obvious example of this in R is the `plot` function. You as the programmer don't have to know exactly how to plot an instance of a class, you just pass it into `plot` and it will be handled correctly. If you create a new class you just have to extend the definition of plot in a standard way and it will also be handled for you.
It's a shame that the many flavors of OOP remain relatively unknown to most programmers, and in many of the cases where they're tried (JavaScript's prototype system for example) people have essentially replaced them with more familiar systems.
This reflects a very deep misunderstanding of the distinctive characteristics of each paradigm. It's so far off that it's "not even wrong".
Functional programming is much more about things like purity and referential transparency, about composing functions and/or combinators, about a particular way of managing or modelling effects, about a way of thinking, about using certain kinds of data structures and algorithms.
It's not a syntactical difference.
That's basically a solved problem. For instance, RInside opens a C interface that can be called by any language that can call C functions, which is basically every language. It's efficient, too, because you're only passing pointers around. Here's an example in Ruby (disclaimer that I wrote it): https://github.com/eddelbuettel/rinside/blob/master/inst/exa...
1. Basic users don't even know it's there, they're just calling regular functions.
2. S3 in base is super simple to understand and easy to extend the first time you need to implement your own summary.
3. Full blown OOP with slots and methods is available when you really need it (rare for a user and not library author imo, lists and S3 are sufficient for most things).
The big issue I see is the incompatibilities in the various systems making this "ramp up" not so smooth. But it looks like that's what S7 is trying to address so that's cool.
1. It's a combination of S3 and S4 obviously.
2. It's also linked to another OOP system called R6. Interesting how it's a step forward one way (6->7) and a step 'backwards' in another way (S->R).
To me it shows the philosophy of not creating something entirely new but improving the existing systems quite nicely!
It then goes on to describe what that means in depth.
It describes 3 new generics in base R that help their new S7 system.
It all seems motivated by better interop with python which is 'neat' but really doesn't seem like a critical necessity of the language. I guess it's more of a tactical thing where they're trying to make it easier for python users to eventually try R. Or for R users that work alongside python users to not abandon R.
First, R definitely needs at least two, one for functional OOP (Common Lisp style) and one for class-based OOP (Java style). The latter is _much_ less important for everyday R users but as a package author it's extremely helpful for modeling certain types of resources. (Interestingly, Python also ships with two: @singledispatch and classes; and multimethod/multidispatch also exist.)
Second, because R's basic language building blocks are so flexible, it's relatively easy to build new OOP systems, resulting in more diversity.
Third, I believe it's actually been close to thirty years since S4 was introduced, which was the last functional OOP system until S7. I don't think that's a terrible track record, compared to how much variety you see in equally fundamental systems in other language communities (just off the top of my head, Python: packaging standards, environment management, data frames; JavaScript: module systems, runtimes, package managers).
I would have liked to see a better S4 - fixing some of its issues and adding things like before/after/around method - and I’m not sure this goes in that direction. It can still be an improvement in practice over the rarely-used S4 though.