4 ms·
RE: functions/variables -- you don't quite have this right. Let's walk through when this can occur and when this can't. First, this cannot occur if you're talki
by notafraudster 7y ago
RE: functions/variables -- you don't quite have this right. Let's walk through when this can occur and when this can't. First, this cannot occur if you're talking about your local environment:
z <- function() { print("hello world") }
z <- 3
z # Outputs 3
z() # Errors because there is no function z()
What the actual quirk you're talking about has to do with attaching other namespaces. So, the way R works is that by default it loads several packages. For instance, the reason you can call `mean()` is that the "base" package is attached when you open a blank session in R. It is absolutely possible to have multiple symbols take the same label across namespaces. Here's an example:
mean <- 4 # Creates variable called mean in the local namespace
mean(c(5, 10, 20)) # Uses the mean function in the attached base namespace
mean # Uses the mean variable in the local namespace
But this is not unique to variables versus functions, it also works with functions:
mean <- function(x) { sum(x) * 100 }
mean(c(1, 2, 3)) # Outputs 600
base::mean(c(1, 2, 3)) # Outputs 2
rm(mean) # Drop local namespace function
mean(c(1, 2, 3)) # Outputs 2
You can use sessionInfo() to see the order of attached namespaces that will be searched. In RStudio, you can also press the little dropdown arrow next to "Global Environment" in the environment pane to see the order of attached namespaces -- it'll search them in that order. Alternatively, you can be defensive and always prefix all functions in any namespace with the namespace name (equivalent to always using module.function style function calls in python).
Finally, you can use the built-in function "find" to see the order in which R will try to resolve a symbol, e.g.
sum <- function() { print("i like sum coding in R!!!") }
find("sum") # .GlobalEnv first, base second
I'm not sure this is a quirk. What are your options as a namespaced language? 1) Allow users to import multiple functions/variables with the same name across different namespaces and resolve the conflict via some kind of hierarchical order; 2) Don't allow users to import multiple functions/variables with the same name, so you can never use overloading to monkey patch; 3) Always require namespace prefixes at all times; 4) Make function dispatch a blocking operation that asks REPL users which to use? I dunno, it doesn't seem to me like R's approach is any less sane.
I guess one thing that is different about R's approach is that "built-ins" have no special priority, they're all part of some namespaces that are attached by default but otherwise exactly like third-party libraries (base, stats, graphics, etc.)
In R, the only reserved words that cannot be overloaded are while, repeat, next, if, function, for, and break. (Note: else does not appear here because of a genuinely baffling quirk about how else is implemented in R)
- playing_colours 7y agoCan an alias be an option to resolve conflict: “import mypackage.mean as mymean”?
- hdkrgr 7y agoNo aliases (afaik), but convention is that you explicitly call mypackage::mean in cases where names might even hint at being ambigous.
- credit_guy 7y agoOn a tangent here, but is there a reason to use <- instead of = for assignment? Actually, to answer my own question (I know google), I found this very informative stackoverflow answer [1]. My TLDR: no difference, other than "<-" is more likely to cause carpal tunnel syndrome. [1] https://stackoverflow.com/questions/1741820/what-are-the-differences-between-and-assignment-operators-in-r https://stackoverflow.com/questions/1741820/what-are-the-dif...
- rgovostes 7y agoThanks for the explanation. Yes, your second example is something like what I found in R code I was asked to modify. What I find distasteful is that when calling mean(), the resolution of this name depends NOT on whether the local variable mean has been defined, but whether it has been assigned a function. This is illustrated by your 2nd and 3rd examples. Of course if you are used to it, it may not catch you by surprise.
- j7ake 7y agoAs much as I love R, there are indeed quirks that I think R allows to happen but shouldn't. For example: mean(2, 4) # outputs 2 mean(c(2, 4)) # outputs 3 I really don't see why R allows you to enter mean(2,4) without giving an error.