My hat off to him though!
As for the language ... consider this: lapply(), sapply(), tapply(), vapply() each does something different. The language allows two kinds of assignment operators even: a=1 or a <- 1 that are "almost" identical ... good luck, here is a language there are two ways to even assign a value to a name.
The <- assignment is normal for functional programming languages. F#, OCaml, S, and more use this operator. This is because the arrow key used to be a physical key on keyboards back in the 70s when FPP was popular and brand new.
The = sign (function assignment operator) is function level scope and <- (assignment operator) is top level scope.
eg:
median(x = 1:10)
x ## Error object 'x' not found
median(y <- 1:10)
y ## [1] 5.5
So therefor, x <- 1:10
median(x)
is equivalent to median(x <- 1:10)
It's a convenient feature the language supports. The alternative is how Python does while loops. If anything, R comes out above in this regard.edit: Python has the := operator which functions the same way <- does in R. I guess Python is catching up on this one.
eg (Python):
env_base = os.environ.get("PYTHONUSERBASE", None)
if env_base:
return env_base
vs if env_base := os.environ.get("PYTHONUSERBASE", None):
return env_basethree ways if you count a <<- 1 for writing in global variables from inside functions (of course, not a recommended practice...)
I don't see what you point is though. So there are several ways to do the same thing in a language, so it's bad? Bad in what way?
As for the lapply, sapply, tapply, mapply, it's very well documented as to when and where you should use them. Sapply applies only on a single vector, and for generalization on larger data structures you use the other "applys". Nothing very hard to comprehend, and this is well explained in the official docs.
There are many people in the R community working on this together (e.g. Jenny Bryan, Charlotte, etc).
> lapply(), sapply(), tapply(), vapply() each does something different.
The apply situation has been standardized through the purrr lib and dplyr for a long time. They are base library functions that aren't mandatory.
> two kinds of assignment operators even
Consider the custom of using <-. It reduces the kinds of assignment operators to 1. Similar to avoiding from lib import * in python. You can do it, but there are community standards against it.
There are many books that cover how to develop in R in detail, and they are no less thorough than treatments of the subject in other languages (e.g. Hadley's books are as good as any I've read for python).
Many issues around inconsistency, etc, in language design (mostly how base functions / data types behave) have very clean, consistent implementations in libraries like rlang.
The main differences I see when comparing R vs python package code, that affect style are...
1. Most R operations are immutable.
2. R often uses single dispatch, rather than putting methods on a class object.
3. In R, vectorised behavior is often the norm.
4. R functions can choose to use lazy evaluation (it usually very clear when this happens in e.g. tidyverse packages).
These issues are covered in detail in books like Hadley's Advanced R.