Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I don't use R, so I thought you were referring to dynamic scoping, which I do think it's horrifying.

But it seems R uses lexical scoping - that is, the y is captured at function definition time. That's extremely common and quite useful, in my opinion.



R documentation and users SAY that R has lexical scoping, which can be really confusing for people reading about the topic.

But if you're coming from something like Common Lisp (which is my point of reference), you soon discover that "Lexical Scoping" as implemented there and "Lexical Scoping" as implemented in R are two different things.

In R (paraphrasing) you generally have a search path of environments, and at run-time, R will find a variable by going from the inner-most to the outer-most environment looking for variables of that name. When it finds one, that's the variable R uses. What R does do is capture the path of environments that were in effect at the time of a function's creation. R has to do many of these variable lookups at runtime, which is also a factor that makes is so slow.

So what you get is a scoping scheme that, if i were being short, i'd call "actually more like dynamic scoping with environment search paths", and if i were being flippant "pretty much dynamic scoping dressed up to look like lexical scoping without any of the benefits/distinctions of either. If someone changes the applicable environments or variable later, R will just keep on humming along, pointing at new variable references that align with whatever variable name the original author of the code used, as long as that variable exists somewhere on the applicable search path"


A search through linked environment objects corresponding to nested lexical scopes is a valid, correct implementation of lexical scoping.

It could be that R somehow gets some aspect of it wrong but you haven't so far presented evidence of that. (Maybe it's something you know a lot about and so it's obvious to you.)


R uses a "sort of" lexical scoping which causes some "interesting" things. Eg a symbol may be simultaneously in global and local scope within the same function, which can be (ab)used to create a variable that's randomly scoped[0]. I'd say this is sort of a "dynamically lexical scope".

[0] http://andrewgelman.com/2014/01/29/stupid-r-tricks-random-sc...


The article is not convicing me that the language is obeying any poorly designed requirements.

The function f contains a free reference to a variable called a. This is satisfied in some sort of global environment.

Later, f is called from a function in which there is a local a bound to 100. Of course, this a which is local to that function is invisible to the free reference in f which continues to refers to the global a that contains 10.

It could be there is some problem in R, but whatever that is, this article isn't exposing it in a convincing way.

Same thing in Common Lisp (using CLISP):

  [1]> (defun f (x) (* a x))
  F
  [2]> (setf a 10)
  10
  [3]> (f 3)
  30
  [4]> (defun g (y) (let ((a 100)) (f y)))
  G
  [5]> (g 3)
  30
The surprise is supposed to be that `(g 3)` doesn't produce 100. Why should it?

(It could produce 100 if the symbol a were marked for binding as a special variable; but it isn't. Thus it's just a free variable in f resolved in the global environment, and a lexical binding in g).


Ah, fair enough, that's definitively weird.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: