Inner functions and outer 'this' (Re: That hash symbol)

Claus Reinke claus.reinke at talk21.com
Sun Mar 27 02:04:12 PDT 2011


>> function f() {} // target this binding
>>
>> (function () {
>>  function f() { // skip this binding
>
> The line directly above introduces two bindings in two scopes.  Did
> you mean that both of them are skipped, or just one?

This made me feel as if I was missing something, so I went back to the
ES spec: by my reading of '13. Function Definition', a FunctionDeclaration
for 'f' introduces a binding for 'f' into the scope in which the declaration
occurs (in this case, the body of the immediately executed anonymous
function). That is _one_ binding.

If we had a named FunctionExpression 'f' instead, that would introduce
a binding for 'f' in 'f's body. That would still be _one_ binding.

Since 'f's body is nested in that of the anonymous function, any
binding in scope in the outer function's body is also in scope in 'f's
body, as long as it isn't shadowed by a more local binding.

>> Not usually (did your counting scopes cloud the idea, or
>> am I missing some Javascript-specific problem?) - it has
>
> I have never used such a feature, and thanks for recounting your
> experiences below.

Ok, sorry. It is easy to forget for me that this idea is new to
most programmers. Fortunately, in that case, just playing around
with the idea will help. I just want to make sure that this isn't
hampered by miscommunications.

> Counting scopes seems brittle to me because changes to
> intervening scopes can break code that is distant from them.
> That's, of course, always the case with introducing a variable
> that may mask.

Indeed, the problem of shadowing is always there. When one
starts rewriting/refactoring programs, that problem becomes
more prominent, because one needs to avoid variable capture.
And when one starts reasoning about program rewriting, the
problem is so central that is needs a solution.

De Bruijn went with abandoning all names, which only works
at implementation-level (and presenting users a named form
re-introduces the problem); others went with conventions that
work only at proof-level (where pesky, but well-understood
details can be abstracted away); most went with forcing
renaming of bound variables, but this really messes with
the programmer-chosen names.

The latter is the issue Javascript programmers are running
into with the fixed special name 'this' (with manual renaming
a la 'var that = this', to avoid shadowing).

Berkling's approach was the first that introduced a systematic
way of handling binding structure and preventing name
capture _without_ interfering with programmer-chosen
names. I wouldn't expect Javascript code to use more than
'#this' or '##this', but since such expectations never outlive
practice, it is good if the system can handle whatever
programmers actually do.

Claus

 



More information about the es-discuss mailing list