[1]: https://jamesmccaffrey.wordpress.com/2016/05/02/r-language-v...
[1]: https://jamesmccaffrey.wordpress.com/2016/05/02/r-language-v...
But behind the scenes, R is just a lisp with some data structures that are adapted to statistics and data science.
All base data structures are by default immutable. And e.g. the vector type is extremely performant as it's just a thinly wrapped C Array. In Python you need to reach for Numpy for anything similar, and you do feel some pain when converting between native python types and Numpy types for various functions which support one or the other.
The data frame is immensely powerful. And has excellent performance characteristics as it's built upon vectors. A list of objects, like you'd make in python is just a lot slower and more unwieldy to deal with. And much harder to make generalizable functions upon.
Hadley Wickham's Tidyverse[2] is exactly an attempt to hide away the arcane details and create a modern, coherent and consistent language on top of R, keeping the power of all the great statistics R libraries. The fact that R behind the scenes is a Lisp, with support for macros, makes this possible. For doing data-transformations and statistics, I can't think of anything currently as powerful as CRAN + Tidyverse.
In R it's slightly different. The vector (being generally without dimensions) is the base data type and n-dimensional arrays are made of a vector and dimensions. A matrix is then a 2d array. Also vectors/arrays are by default type-specific.
> support for macros
From what I've seen, R does not support macros, but functions which can retrieve/generate code at runtime. That's an early mechanism which got replaced by macros in Lisp. Macros in Lisp are source code transformers and can be compiled - thus they are not a runtime mechanism like in R or earlier Lisps with so-called FEXPRs.
This looks more like 'FEXPRS' from decades ago.
1962 the ideas of macros were introduced and macros are source code transformers, which take source code and generate new source code. This can also used in a compiled implementation, where macros translate the code before compiling.
FEXPRs are then functions which get arguments unevaluated and can decide at runtime which to evaluate and how.
This is something I wish there was more progress on. A serious limitation in some contexts.
> A vector is what is called an array in all other programming languages except R
Vectors are called vectors in several "wispy" languages: Common Lisp, Scheme, Clojure...
> An array with two dimensions is (almost) the same as a matrix.
I think it's the same, not "almost" the same. At least in the current version of R:
> class(array(1, c(2,3)))
[1] "matrix"
> identical(array(1, c(2,3)), matrix(1, nrow=2, ncol=3))
[1] TRUE
In 4.0 there will be a change and the class of a matrix will be both "matrix" and "array", but I think the fact that there is no difference between a 2-dimensional array and a matrix remains.That said, the real value in R seems to be the libraries. Has anyone looked at a shim that could make those libraries available to Python in a reasonably natural way? If that existed, the R language itself could be allowed to finally rest in peace.
Being vector aware and having a dataframe support in R is much more elegant for me than Python's add on library. It's like Scala building on top of Java but trying to have an Actor paradigm vs Erlang built from get go around concurrency and choosing Actor as it's main concurrency paradigm. You can see this in other language on PHP and C++ let you be OOP but it's an after thought compare to Ruby or Python.
Statisticians aren't that interested in writing a really good programming language. And why should they be? They have better things to do. The trick is to not take on responsibility for something you don't care about, if you can help it.
[1] https://github.com/rust-lang/rustfix
[2] https://doc.rust-lang.org/nightly/edition-guide/editions/tra...