Expected function parameter scoping behavioor

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Expected function parameter scoping behavioor

Logan Smyth
Hey all,
We're currently exploring some changes to Babel's behavior for function parameter default scoping, and I was hoping to validate my understanding of the spec, because my reading of the spec does not conform to Chrome or FF's behavior. Alternatively if you know bugs for those engines for this, let me know.

My understanding from https://tc39.github.io/ecma262/#sec-functiondeclarationinstantiation step #27 is that if function parameters contain any expressions, the function body is shifted to run in a declarative environment separately from the params. Per #27.f.i.4.a, the initial values of the params are copied from from the param environment into the function body environment, at initial execution time.

Given that, I'd expect cases such as
```
(function fn(arg, setValue = function () { arg = "a string" }) {
  setValue();

  return arg;
})("initial")
```
to return `initial`, because the `arg` binding being mutated by `setValue` is not tied to the `arg` binding that the function returns, as the `"initial"` value would have been copied into the function body binding before `setValue` ran.

Is my understanding there correct?

Similarly I'd have expected
```
(function fn(arg, getValue = function () { return arg; }) {

  arg = "new value";

  return getValue();
})("initial")
```

to return `"initial"` because it is returning the binding value from the declarative environment in the function params and accessed by `getValue` is not the same environment being mutated by the assignment to `arg1`.

Is my understanding correct, or is there something I'm misunderstanding?

Thanks!

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Expected function parameter scoping behavioor

Allen Wirfs-Brock
You misunderstand.  The two scope design is all about preventing closures from referencing variables declared within the body of the functions.  See https://github.com/tc39/tc39-notes/blob/master/es6/2013-09/default-arguments.pdf for the motivation for this design. (but be aware that there are probably some subtle differences between the final specified design and what this deck describes.

In you to test cases, `arg` is not declared within the body of `fn` so there is no duplicate binding for it.  Things would be different if you had a `var` or `function` declaration for `arg` within the body.

Allen

On May 9, 2017, at 12:40 PM, Logan Smyth <[hidden email]> wrote:

Hey all,
We're currently exploring some changes to Babel's behavior for function parameter default scoping, and I was hoping to validate my understanding of the spec, because my reading of the spec does not conform to Chrome or FF's behavior. Alternatively if you know bugs for those engines for this, let me know.

My understanding from https://tc39.github.io/ecma262/#sec-functiondeclarationinstantiation step #27 is that if function parameters contain any expressions, the function body is shifted to run in a declarative environment separately from the params. Per #27.f.i.4.a, the initial values of the params are copied from from the param environment into the function body environment, at initial execution time.

Given that, I'd expect cases such as
```
(function fn(arg, setValue = function () { arg = "a string" }) {
  setValue();

  return arg;
})("initial")
```
to return `initial`, because the `arg` binding being mutated by `setValue` is not tied to the `arg` binding that the function returns, as the `"initial"` value would have been copied into the function body binding before `setValue` ran.

Is my understanding there correct?

Similarly I'd have expected
```
(function fn(arg, getValue = function () { return arg; }) {

  arg = "new value";

  return getValue();
})("initial")
```

to return `"initial"` because it is returning the binding value from the declarative environment in the function params and accessed by `getValue` is not the same environment being mutated by the assignment to `arg1`.

Is my understanding correct, or is there something I'm misunderstanding?

Thanks!
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Expected function parameter scoping behavioor

Logan Smyth
Perfect, thanks Allen, now I see the part that I was misreading. I didn't recognize that the only bindings that would be recreated and shadowed in the new environment were those that had explicitly been redeclared in the body, I was thinking `varNames` included the parameter names, which is clearly wrong. So in my examples, the addition of a `var arg;` into the function body, causes the behavior I was referencing. That's an interesting edge case.

Thanks!

On Tue, May 9, 2017 at 1:19 PM, Allen Wirfs-Brock <[hidden email]> wrote:
You misunderstand.  The two scope design is all about preventing closures from referencing variables declared within the body of the functions.  See https://github.com/tc39/tc39-notes/blob/master/es6/2013-09/default-arguments.pdf for the motivation for this design. (but be aware that there are probably some subtle differences between the final specified design and what this deck describes.

In you to test cases, `arg` is not declared within the body of `fn` so there is no duplicate binding for it.  Things would be different if you had a `var` or `function` declaration for `arg` within the body.

Allen

On May 9, 2017, at 12:40 PM, Logan Smyth <[hidden email]> wrote:

Hey all,
We're currently exploring some changes to Babel's behavior for function parameter default scoping, and I was hoping to validate my understanding of the spec, because my reading of the spec does not conform to Chrome or FF's behavior. Alternatively if you know bugs for those engines for this, let me know.

My understanding from https://tc39.github.io/ecma262/#sec-functiondeclarationinstantiation step #27 is that if function parameters contain any expressions, the function body is shifted to run in a declarative environment separately from the params. Per #27.f.i.4.a, the initial values of the params are copied from from the param environment into the function body environment, at initial execution time.

Given that, I'd expect cases such as
```
(function fn(arg, setValue = function () { arg = "a string" }) {
  setValue();

  return arg;
})("initial")
```
to return `initial`, because the `arg` binding being mutated by `setValue` is not tied to the `arg` binding that the function returns, as the `"initial"` value would have been copied into the function body binding before `setValue` ran.

Is my understanding there correct?

Similarly I'd have expected
```
(function fn(arg, getValue = function () { return arg; }) {

  arg = "new value";

  return getValue();
})("initial")
```

to return `"initial"` because it is returning the binding value from the declarative environment in the function params and accessed by `getValue` is not the same environment being mutated by the assignment to `arg1`.

Is my understanding correct, or is there something I'm misunderstanding?

Thanks!
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss