5 ms·
To be honest, OOP never really seemed like a good fit for R. Functional programming is a much more natural fit, given that both it and R come from a mathematic
by rossdavidh 2y ago
To be honest, OOP never really seemed like a good fit for R. Functional programming is a much more natural fit, given that both it and R come from a mathematical point of view. R is a great language for the mathematical/statistical stuff it was invented to do, but I don't think it will ever be a general-purpose language, and it probably would become worse at its core purpose if it tried to.
More work on being easily used by/incorporated into applications written in other languages, would perhaps be a more impactful thing to work on.
- bachmeier 2y ago> More work on being easily used by/incorporated into applications written in other languages, would perhaps be a more impactful thing to work on. 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/examples/c_interface/passdata.rb https://github.com/eddelbuettel/rinside/blob/master/inst/exa...
- orhmeh09 2y agoOOP has been a critical part of real-life R for a long time, especially in complex implementations of classes of kernels, algorithms, and so on with S4, and more general-purpose with R6. Without these frameworks it would be difficult to implement them. 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.
- fire_lake 2y agoI too much prefer R to Python (it’s far more expressive, for one) however it’s clear now that Python has “won” in this space and R is a tough sell to a wider team.
- bachmeier 2y ago> it’s clear now that Python has “won” in this space and R is a tough sell to a wider team R has always been a language for academics, and it continues to be popular in that domain, with no compelling reason to switch. It has seen usage in the private sector, but that has never been the driving force behind R's development or ecosystem, and I doubt it ever will be. For academics, even if a particular function is only available for Python, it's easy enough to call it from R and do everything else in R.
- orhmeh09 2y agoOh, I agree on that, and I know that most of the time I'll be asked why something isn't in Python so I mainly reserve it for when I am sure nobody will ask "why R?" :-) There is a benefit nowadays that I can rely on Python>=3.6 to be available by default anywhere I am deploying whereas R has to be installed in some way, so like Bash it's part of a toolbox I can rely on being available with at least a constrained set of features.
- rossdavidh 2y agoMy experience is that you can "sell" R when the statistical or modelling technique is not (or not well) implemented in python. Which still includes a lot of potentially useful statistical techniques! R should/could lean into being the tool that python programmers reach for when they need something a little less mainstream, if they made it easier for non-R programmers to do so.
- agumonkey 2y ago> I suspect lazy evaluation is a part of this. I had no idea R was lazy. Makes me wanna learn it now.
- civilized 2y agoR is not lazy. It has non-standard evaluation mechanisms (formulas, promises, quosures...) that enable to you to write domain-specific languages that "do what the user meant". If your code (or the code of the libraries you're using) doesn't use any non-standard evaluation tools, evaluation will be eager and work like any other ALGOL language. It is possible to make some objects behave in a lazy way, but this is also true of many other languages.
- orhmeh09 2y agoThank you for the correction. Is it possible to use NSE in say Python or JavaScript?
- CornCobs 2y agoYes, though the languages do not support it explicitly you can simulate lazy evaluation by wrapping all your arguments in closures. This way they won't be evaluated until called within the function body.
- agumonkey 2y agoSidenote, the evaluation model of python can be surprising. List comprehension will create implicit function scopes that can trip you up.
- aquasync 2y agoR's evaluation of arguments is lazy, so while not at the level of Haskell it feels like a lazy language to me. Try eg: f = function(x) { print('hello'); x } f(print('world')) X is not evaluated in f until referenced. Indeed if you remove x from f, world is not printed.
- 2y ago
- mr_toad 2y agoMaybe too expressive and too flexible? Different R programs can have wildly different dialects, making it difficult for two R programmers to even understand each other. 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.
- orhmeh09 2y agoThis is fair. For what it's worth, Python is tending toward this and I think is introducing newer syntax at a faster rate with things such as structural pattern matching and typing, which I have had difficulty explaining to people who don't keep up with each new release.
- stevenae 2y agoSwitching from R to Python, this resonates. I write base (non-tidy) R, and it's definitely another language from tidy. That said, having written a fair amount of base Python, jumping into torch/tensor flow feels like an even further separation than base R/tidy.
- int_19h 2y agoIn modern idiomatic Python, you should really be using `pathlib` and `io`, not `os`.
- orhmeh09 2y agoYeah, you're absolutely right. The `os` methods are closest to the base R file operations and those in `pathlib` are closest to `fs` (which is a third-party library for R that requires installation).
- barfbagginus 2y agoPathlib gives a decent oop interface to most file operations. The pathlib docs has a handy Rosetta Stone table for replacing `os` and `shutil` invocations which is very handy. 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-folders-in-python-recursively/49782093#49782093 https://stackoverflow.com/questions/13118029/deleting-folder...
- orhmeh09 2y agoPathlib is a great addition and it's nice that it's in the standard library. I like fsspec also, which has some functionality that overlaps with Python's existing libraries but makes it a little cleaner IMO.
- andrewla 2y agoOOP as used in R is very much a function of API design and not a function of routine R usage for data analysis. To many users of R they are not even aware that they are using OOP at all, especially for the S3 style of objects. 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.
- th0ma5 2y agoSome detail about that phrase https://www.catalyst.org/2021/03/22/racism-misogyny-asian-american-women-workplace/ https://www.catalyst.org/2021/03/22/racism-misogyny-asian-am...
- Onawa 2y agoI can honestly say that I had never heard that phrase used before now, but I do know I felt icky when I read it in the comment before I even clicked on your link. Definitely glad to see it is being called out, terms like this absolutely need to be removed from modern discourse.
- deleted 2y ago[deleted]
- chuckadams 2y agoPretty sure the phrase GP was looking for was "pull back the curtain", which likely originated with The Wizard of Oz.
- clatan 2y ago
- usgroup 2y agoYet you’re using OOP every time you call plot, predict, summary and so on: possibly without realising.
- CornCobs 2y agoI actually think this "multi-tiered" system of OOP is quite cool, when compared to languages that stick OOP in your face upfront. 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.
- PheonixPharts 2y agoFunctional programming is not orthogonal to object oriented programming, they are paradigms that can be used together and the popular object system developed in Java is not close to the only way to do OOP. 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.
- epgui 2y ago> Effectively instead of object.method() you have method(object) 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.
- fn-mote 2y ago>> Effectively instead of object.method() you have method(object) > This reflects a very deep misunderstanding of the distinctive characteristics of each paradigm. I think the parent made a hasty reading of the GP comment. The GP shows an awareness of multiple OO systems in R. I believe the GP is attempting to explain to a Java programmer how R could be considered object-oriented even though `plot(item)` does not "look like" what you would see in an object oriented system. Which is to say: there is an generic function dispatch based on the type of the first argument to the function. This can be _used_ to write in an OO style.