New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Immutable bindings of object Environment Records. #1084

Closed
smellyshovel opened this Issue Jan 27, 2018 · 9 comments

Comments

Projects
None yet
4 participants
@smellyshovel

smellyshovel commented Jan 27, 2018

As it is said in the 8.1.1.2 section of the spec:

Immutable bindings do not exist for object Environment Records.

And:

Because properties can be dynamically added and deleted from objects, the set of identifiers bound by an object Environment Record may potentially change as a side-effect of any operation that adds or deletes properties. Any bindings that are created as a result of such a side-effect are considered to be a mutable binding even if the Writable attribute of the corresponding property has the value false.

So if I understand correctly that means that the following code should outputs 3:

Object.defineProperty(this, "prop", {
    value: 1,
    writable: false
});

console.log(prop); // 1

this.prop = 2;
console.log(prop); // 1

prop = 3;
console.log(prop); // Here.

But what is actually does output is 1.

Is it implementations' bug or what? I've tested in Chome's and Node.js's V8 and Firefox's SpiderMonkey and the result is 1 everywhere.

Could you please clarify to me why?

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Jan 27, 2018

Member

any operation that adds or deletes properties

Object.defineProperty(this, 'prop', { value: 3 });
console.log(prop);

In other words, "writable: false" means you can't [[Set]] it - you can't change it by assignment. However, it's still configurable, so you can still [[Define]] it.

Member

ljharb commented Jan 27, 2018

any operation that adds or deletes properties

Object.defineProperty(this, 'prop', { value: 3 });
console.log(prop);

In other words, "writable: false" means you can't [[Set]] it - you can't change it by assignment. However, it's still configurable, so you can still [[Define]] it.

@smellyshovel

This comment has been minimized.

Show comment
Hide comment
@smellyshovel

smellyshovel Jan 27, 2018

@ljharb , but it still doesn't explain this part of the quote:

Any bindings that are created as a result of such a side-effect are considered to be a mutable binding even if the Writable attribute of the corresponding property has the value false.

Why after [[Set]]ting variable prop to 3 it behaves like immutable binding and is anyways eqals to 1?

smellyshovel commented Jan 27, 2018

@ljharb , but it still doesn't explain this part of the quote:

Any bindings that are created as a result of such a side-effect are considered to be a mutable binding even if the Writable attribute of the corresponding property has the value false.

Why after [[Set]]ting variable prop to 3 it behaves like immutable binding and is anyways eqals to 1?

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Jan 27, 2018

Member

I’m not sure what the intention was, but “mutable” means “changeable”, not “assignable”.

Member

ljharb commented Jan 27, 2018

I’m not sure what the intention was, but “mutable” means “changeable”, not “assignable”.

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Jan 28, 2018

Member

Why after [[Set]]ting variable prop to 3 it behaves like immutable binding and is anyways eqals to 1?

Assignment to non-write properties in non-strict mode code are silently ignored. If you did the same assignment in strict mode it would throw an exception.

Member

allenwb commented Jan 28, 2018

Why after [[Set]]ting variable prop to 3 it behaves like immutable binding and is anyways eqals to 1?

Assignment to non-write properties in non-strict mode code are silently ignored. If you did the same assignment in strict mode it would throw an exception.

@smellyshovel

This comment has been minimized.

Show comment
Hide comment
@smellyshovel

smellyshovel Jan 28, 2018

@ljharb , @allenwb

Let me try to explain what I mean.

First of all, object component is one of two components of the global Environment Record. It is represented by Global Object. So the Global Object is the binding object of the object component of the global Environment Record.

Because properties can be dynamically added and deleted from objects...

// dynamically adding the property to the Global Object
this.a = 1;

...the set of identifiers bound by an object Environment Record may potentially change as a side-effect of any operation that adds or deletes properties.

// so now we have the new identifier available
console.log(a); // 1

Any bindings that are created as a result of such a side-effect...

In this example such a binding is a

...are considered to be a mutable binding...

And yeah, here it goes:

// I can change the value of the binding
a = 2;
console.log(a); // 2 for real

So this part works the proper way. But:

are considered to be a mutable binding even if the Writable attribute of the corresponding property has the value false

So this means that if the a property of the global object has the writable attribute set to false:

Object.defineProperty(this, "a", {
    value: 1,
    writable: false
});

Then I must not be able to change it's value addressing it as a property of the Global Object:

this.a = 2; // must not work
console.log(this.a); // 1 (and it doesn't)

But I must be able to change the value of the property addressing it via the binding:

a = 2; // must work!
console.log(a); // must be 2, but it's 1!

And I must be able to do so because of 2 reasons:

  1. "[bindings] are considered to be a mutable binding even if the Writable attribute of the corresponding property has the value false."
  2. "Immutable bindings do not exist for object Environment Records."

Immutable bindings do not exist for object Environment Records. At all. Immutable properties of the object Environment Records' binding objects do. But the bindings pointing to the corresponsive properties of such objects don't.

Could you please explain which part did I interpret incorrect? What exactly part do I understand wrong?
Thank you for your time.

smellyshovel commented Jan 28, 2018

@ljharb , @allenwb

Let me try to explain what I mean.

First of all, object component is one of two components of the global Environment Record. It is represented by Global Object. So the Global Object is the binding object of the object component of the global Environment Record.

Because properties can be dynamically added and deleted from objects...

// dynamically adding the property to the Global Object
this.a = 1;

...the set of identifiers bound by an object Environment Record may potentially change as a side-effect of any operation that adds or deletes properties.

// so now we have the new identifier available
console.log(a); // 1

Any bindings that are created as a result of such a side-effect...

In this example such a binding is a

...are considered to be a mutable binding...

And yeah, here it goes:

// I can change the value of the binding
a = 2;
console.log(a); // 2 for real

So this part works the proper way. But:

are considered to be a mutable binding even if the Writable attribute of the corresponding property has the value false

So this means that if the a property of the global object has the writable attribute set to false:

Object.defineProperty(this, "a", {
    value: 1,
    writable: false
});

Then I must not be able to change it's value addressing it as a property of the Global Object:

this.a = 2; // must not work
console.log(this.a); // 1 (and it doesn't)

But I must be able to change the value of the property addressing it via the binding:

a = 2; // must work!
console.log(a); // must be 2, but it's 1!

And I must be able to do so because of 2 reasons:

  1. "[bindings] are considered to be a mutable binding even if the Writable attribute of the corresponding property has the value false."
  2. "Immutable bindings do not exist for object Environment Records."

Immutable bindings do not exist for object Environment Records. At all. Immutable properties of the object Environment Records' binding objects do. But the bindings pointing to the corresponsive properties of such objects don't.

Could you please explain which part did I interpret incorrect? What exactly part do I understand wrong?
Thank you for your time.

@littledan

This comment has been minimized.

Show comment
Hide comment
@littledan

littledan Jan 29, 2018

Member

It seems like this thread is a miscommunication about wording: "immutable binding" is a specific term used in environment records to refer to certain kinds of bindings, such as that created by const declarations. On the other hand, there are non-writable properties, which throw when written to in strict mode. Although, at a high level, these may be immutable (especially if made non-configurable, so you can't even redefine them), they're not included in what's referred to as "immutable bindings".

Maybe we should clarify the wording of this section somehow.

Member

littledan commented Jan 29, 2018

It seems like this thread is a miscommunication about wording: "immutable binding" is a specific term used in environment records to refer to certain kinds of bindings, such as that created by const declarations. On the other hand, there are non-writable properties, which throw when written to in strict mode. Although, at a high level, these may be immutable (especially if made non-configurable, so you can't even redefine them), they're not included in what's referred to as "immutable bindings".

Maybe we should clarify the wording of this section somehow.

@smellyshovel

This comment has been minimized.

Show comment
Hide comment
@smellyshovel

smellyshovel Jan 29, 2018

@littledan

It seems like this thread is a miscommunication about wording: "immutable binding" is a specific term used in environment records to refer to certain kinds of bindings, such as that created by const declarations.

Exactly. I thought that it might be any binding the value of which you can not change in any way.

But I still don't understand this part though:

are considered to be a mutable binding even if the Writable attribute of the corresponding property has the value false

Doesn't it finally mean that I must be able to change the value of the binding corresponding to non-writable property of the binding object of the corresponding Object Env.? This is the only question that bothers me for now.

Maybe we should clarify the wording of this section somehow.
And yeah, this would be great of you, if we would finally come to some concrete conclusion.

smellyshovel commented Jan 29, 2018

@littledan

It seems like this thread is a miscommunication about wording: "immutable binding" is a specific term used in environment records to refer to certain kinds of bindings, such as that created by const declarations.

Exactly. I thought that it might be any binding the value of which you can not change in any way.

But I still don't understand this part though:

are considered to be a mutable binding even if the Writable attribute of the corresponding property has the value false

Doesn't it finally mean that I must be able to change the value of the binding corresponding to non-writable property of the binding object of the corresponding Object Env.? This is the only question that bothers me for now.

Maybe we should clarify the wording of this section somehow.
And yeah, this would be great of you, if we would finally come to some concrete conclusion.

@littledan

This comment has been minimized.

Show comment
Hide comment
@littledan

littledan Feb 3, 2018

Member

Doesn't it finally mean that I must be able to change the value of the binding corresponding to non-writable property of the binding object of the corresponding Object Env.? This is the only question that bothers me for now.

No, just because the binding itself isn't considered "immutable" in this particular piece of technical language doesn't mean you can necessarily change it.

Is anyone interested in proposing some new wording which may clarify things? @jmdyck ?

Member

littledan commented Feb 3, 2018

Doesn't it finally mean that I must be able to change the value of the binding corresponding to non-writable property of the binding object of the corresponding Object Env.? This is the only question that bothers me for now.

No, just because the binding itself isn't considered "immutable" in this particular piece of technical language doesn't mean you can necessarily change it.

Is anyone interested in proposing some new wording which may clarify things? @jmdyck ?

@smellyshovel

This comment has been minimized.

Show comment
Hide comment
@smellyshovel

smellyshovel Feb 3, 2018

@littledan the clearest explanation for me from all out here. Thank you!

smellyshovel commented Feb 3, 2018

@littledan the clearest explanation for me from all out here. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment