7 ms·
I'm not an R-guru, but I did my thesis with 5k lines of R, so I'd call myself proficent: Point 10: R has lazy evaluation, which means here that a function will
by olympus 9y ago
I'm not an R-guru, but I did my thesis with 5k lines of R, so I'd call myself proficent:
Point 10: R has lazy evaluation, which means here that a function will not be evaluated when you define it, it will be evaluated when you call it (maybe not quite the same as some other language's lazy eval). I'm not aware of any built in feature for query planning, if you ask for nrow(some_func(myframe)), it will evaluate the some_func(myframe) function and then count up the rows. You could always write your own query planning function I suppose.
Point 11: R has several multicore/cluster libraries, and some are actually decent. If you are like most R users, you use StackOverflow a lot, and you'll end up with one algorithm that uses the snow package and another algorithm that uses multicore, one that uses parallel, and so on. A few very well written packages have hooks that make going to multiple cores easy, but most do not and you typically have to roll your own.
- j2kun 9y ago> R has lazy evaluation, which means here that a function will not be evaluated when you define it, it will be evaluated when you call it. It seems unlikely you meant this as stated. How is it possible to "evaluate a function" when you define it? Certainly you need to give it arguments, and that can only happen when you call it.
- deleted 9y ago[deleted]
- olympus 9y agoA clearer explanation is the lazy evaluation here: http://adv-r.had.co.nz/Functions.html#function-arguments http://adv-r.had.co.nz/Functions.html#function-arguments I can pass an argument but R won’t try to evaluate unless it needs it. This can be beneficial when only some of a function’s branches need the argument. You can pass a solver for the traveling salesman problem but R won’t waste CPU cycles until it reaches a point where it has to solve the TSP to get an answer. Maybe the first branch of the function is a feasibility check, and the TSP will be skipped for something else. This is a little harder to explain for data frames, but you can create R functions that act a little like generators in python. This can help with memory management where instead of a gigantic matrix you have a function that generates the part of the matrix that you need.
- mkl 9y agoWow, if I'm understanding that correctly R's function arguments can have default values that depend on the values variables within the function have when the argument is first used. That seems insane!
- rainforest 9y agoIt's odd but it enables a lot of useful things (e.g. magrittr's pipe operators). It's possible to write functions that change their behaviour depending on what name they were called by too.
- roel_v 9y ago"That seems insane!" Welcome to R!
- deleted 9y ago[deleted]
- carljv 9y agoIt's a sort of lisp-y idea. Arguments passed to functions get "quoted", so the function can get or change data about the expression and its scope/environment before evaluating it. Like others have mentioned, it's what make R quite good for developing DSLs like R's formula language or dplyr. (And other conveniences, like auto-labeled plots, etc.) But similar to lisp macros, it can make for unpleasant surprises if not used wisely. If you look at attempts to do this stuff in python---e.g. patsy, which emulates R's formula DSL, and there's another project that emulates dplyr I don't recall the name of---you see they have to resort to parsing and eval'ing strings instead of working on expressions (language objects that represent ASTs), which is not nearly as nice or safe. Edit: But just to emphasize your surprise -- yes, you can definitely be surprised by delayed evaluation in many contexts if you're used to more traditional languages. > y <- 10 > wat <- function(x=10*y) { y = -y; x } > wat() [1] -1000 But (1) good library writers don't play these kinds of tricks, so it doesn't come up too often in practice; and (2) when writing/debugging my own code, I've not found it too hard to reason about, anticipate, and avoid these effects. > y <- 10 > less_wat <- function(x=10*y) { force(x); y = -y; x } > less_wat() [1] 1000
- wesm 9y agoHi, Wes here. R data frames have limited to no query planning and are not multithreaded in general, so Problems 10 and 11 are problems in R also.
- gigatexal 9y agoAnd R’s syntax leaves much to be desired: it’s ugly compared to python’s.
- huac 9y agoTo each their own - I find the grammar of dplyr and the tidyverse is quite elegant.
- shoyer 9y agoAgreed! Sadly it is difficult to fully emulate in Python without some form of delayed evaluation in the language.
- digitalzombie 9y agoR is one of the few language that popularize data frame. Out of SAS, R, and Python or even C++ and Java. Data frame are native. So personally, the syntax especially for data frame is beautiful compares to python. Python don't even have missing value built in or subsetting data frame.
- hn_throw_1234 9y agoNative data.frames don't but data.table does to some extent. It's parallelization is still relatively new/nascent and requires OpenMP which doesn't have good support on MacOS but it is present.