Brendan Eich wrote: > On Aug 21, 2008, at 4:05 PM, David-Sarah Hopwood wrote: > >> Brendan Eich wrote: >>> The maddening mix of dynamic scope (the hopeless global top-level, >>> with, eval) and lexical scope [...] >> >> 'with' is lexically scoped. >> <http://groups.google.com/group/google-caja-discuss/browse_thread/thread/edc12e29e2cfba9f/c2ea493e83a6bf1f?lnk=gst#c2ea493e83a6bf1f> >> > > There, you wrote > > "The first example illustrates (but does not prove) that 'with' actually > provides lexical scoping, *provided* that all free identifiers in the > scope of the 'with' exist as properties of the supplied scope object. " > > The *provided* is not guaranteed by 'with', so if it's not satisfied, > then by your own argument 'with' does not provide lexical scoping.
My statement in that post was imprecise: 'with' *always* provides lexical scoping for all of the identifiers that it affects. It does not affect the scoping of identifiers that do not exist as properties of the scope object: those have the same scoping as they would have had without the 'with'. Of course if that set of properties changes, then the effect on the scope is "dynamic" in some sense, but that's still not "dynamic scoping". I made the "*provided*" caveat just because at that point I hadn't done sufficient testing and careful analysis of the spec to confirm that 'with' actually is always lexically scoped. But the design of Jacaranda (the object-capability subset I'm working on) depends on that, so I certainly hope it's correct. In your example below, the opt_* variables are globally scoped in the case where they are not affected by the 'with'. The global scoping is not fully lexical (and I fully agree with your dismissal of the global scope semantics as "hopeless"), but it isn't the 'with' construct that is causing that. > Perhaps you meant to write "'with' may but not must be lexically scoped"? > > Consider this counter-example: > > var opt_A = false, opt_B = 0, opt_C = ""; // defaults > > function setOptions(opts) { > with (opts) { > if (opt_A) setOptionA(true); > if (opt_B) setOptionB(opt_B); > if (opt_C) setOptionC(opt_C); > } > } > setOptions({opt_A: true, opt_C: "hi"}); > setOptions({opt_B: 42, opt_C: "bye"}); This is lexical scoping with conditional shadowing. If it were dynamic, then you'd expect: function setOptionB(x) { print(x == opt_B); } setOptions({opt_B: 42}); to print true, but it actually prints false. > I'm not recommending this kind of code, but IIRC Lars Hansen pointed out > the pattern, based on sightings in the wild. > > Is this "dynamic scope" in the classical sense? No, but it smells as bad > and has similar undesirable properties ;-). Oh, I'm certainly not disputing the latter. My discussion of 'with' is made in the spirit of "know your enemy". -- David-Sarah Hopwood _______________________________________________ Es-discuss mailing list Es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss