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

Clarification required that Lists are 'referency' #752

Closed
IgnoredAmbience opened this Issue Dec 9, 2016 · 14 comments

Comments

Projects
None yet
5 participants
@IgnoredAmbience
Member

IgnoredAmbience commented Dec 9, 2016

In 8.1.1.4.7 Global Environment Records DeleteBinding(N) step 7b, varNames is assigned the List value from envNames.[[VarNames]]. Subsequently varNames has an element removed. The algorithm does not explicitly propagate this value back to the envNames record.

It can then be inferred that Lists should be treated as being 'reference-like' when referred to, as opposed to being 'value-like' as in some other languages.

I have re-checked the Types and Algorithmic Conventions sections and couldn't find text explicitly supporting this interpretation.

Would it be a helpful addition to the spec to clarify this in the Types section? I'm happy to raise a PR.

@littledan

This comment has been minimized.

Show comment
Hide comment
@littledan

littledan Dec 9, 2016

Member

I always assumed they were reference-like. I wouldn't mind clarifying text that everything in the spec is reference-like, and nothing at all is value-like, or the text could be restricted to specification types like this. Any thoughts @allenwb ?

Member

littledan commented Dec 9, 2016

I always assumed they were reference-like. I wouldn't mind clarifying text that everything in the spec is reference-like, and nothing at all is value-like, or the text could be restricted to specification types like this. Any thoughts @allenwb ?

@IgnoredAmbience

This comment has been minimized.

Show comment
Hide comment
@IgnoredAmbience

IgnoredAmbience Dec 9, 2016

Member

I've been programming in Haskell and OCaml too much where everything is explicitly value-like unless otherwise specified. As a result of that, my default behaviour was to read mutation operations on value-like lists as mutating the value and reassigning to the variable, my intuition only tripped when the reassignment to the local variable would have no overall effect.

I had a brief grep look through the ES5 spec for List mutations, and was interested to note that it didn't matter there whether Lists were treated as value-like or reference-like there as the results would be the same either way.

Records, Objects are nearly always treated as reference-like in the spec, as the text usually says "update the x field of y" making them less likely to cause a trip. Although not declared as a specification type, the Execution Context Stack is also clearly reference-like as it is global to the specification.
I believe (from a quick search) that the Reference Specification Type itself can be value-like, as it seems to be immutable after construction, similarly Symbols can be value-like as their only field is immutable.
It seems that in most cases [citation needed] Strings are treated as values, although I have found one instance of a String being treated as a reference-like type.
(And null, undefined, booleans and numbers are clearly pure values).

(Yes, I am in pedantic mode).

Member

IgnoredAmbience commented Dec 9, 2016

I've been programming in Haskell and OCaml too much where everything is explicitly value-like unless otherwise specified. As a result of that, my default behaviour was to read mutation operations on value-like lists as mutating the value and reassigning to the variable, my intuition only tripped when the reassignment to the local variable would have no overall effect.

I had a brief grep look through the ES5 spec for List mutations, and was interested to note that it didn't matter there whether Lists were treated as value-like or reference-like there as the results would be the same either way.

Records, Objects are nearly always treated as reference-like in the spec, as the text usually says "update the x field of y" making them less likely to cause a trip. Although not declared as a specification type, the Execution Context Stack is also clearly reference-like as it is global to the specification.
I believe (from a quick search) that the Reference Specification Type itself can be value-like, as it seems to be immutable after construction, similarly Symbols can be value-like as their only field is immutable.
It seems that in most cases [citation needed] Strings are treated as values, although I have found one instance of a String being treated as a reference-like type.
(And null, undefined, booleans and numbers are clearly pure values).

(Yes, I am in pedantic mode).

@littledan

This comment has been minimized.

Show comment
Hide comment
@littledan

littledan Dec 9, 2016

Member

In Haskell and OCaml, everything is by reference. Many objects are immutable (or all in Haskell), but there isn't conceptual copying happening all the time as in Swift and C++. It's just that idioms often encourage operations to return new objects.

In the ES spec, no new object is being created. Often, lists aren't mutated, but when they are, you're mutating the original one. IMO the spec is already clear enough, but it wouldn't hurt to have a clarifying note to explain that the mental model is not that of C++/Swift with copying.

Member

littledan commented Dec 9, 2016

In Haskell and OCaml, everything is by reference. Many objects are immutable (or all in Haskell), but there isn't conceptual copying happening all the time as in Swift and C++. It's just that idioms often encourage operations to return new objects.

In the ES spec, no new object is being created. Often, lists aren't mutated, but when they are, you're mutating the original one. IMO the spec is already clear enough, but it wouldn't hurt to have a clarifying note to explain that the mental model is not that of C++/Swift with copying.

@IgnoredAmbience

This comment has been minimized.

Show comment
Hide comment
@IgnoredAmbience

IgnoredAmbience Dec 9, 2016

Member

Agreed it's by reference when compiled, I was referring to the conceptual level of the language, but we're now off topic 😄

I think we're agreed on the clarifying note then, I'll draft it up for review.

Member

IgnoredAmbience commented Dec 9, 2016

Agreed it's by reference when compiled, I was referring to the conceptual level of the language, but we're now off topic 😄

I think we're agreed on the clarifying note then, I'll draft it up for review.

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Dec 9, 2016

Member

Lists are a flexible mechanism of the relatively informal specification notation. Different use cases may have slightly different semantics (or example, ordered vs unordered, mutable vs immutable) that should be clear from each usage context. Most usages can be thought of as reference-like (or equivalently, the pseudo-code "let" operation can be thought of as a "by name" aliasing of its RHS). Because List mutability is common, I tried to always be explicit about when a new copy of a List was needed.

This informality seems to generally be adequate for human interpretation of the spec. Any effort to formalize the spec. or to perform mechanical analysis would probably need to replace List with somethings that were less informal.

Member

allenwb commented Dec 9, 2016

Lists are a flexible mechanism of the relatively informal specification notation. Different use cases may have slightly different semantics (or example, ordered vs unordered, mutable vs immutable) that should be clear from each usage context. Most usages can be thought of as reference-like (or equivalently, the pseudo-code "let" operation can be thought of as a "by name" aliasing of its RHS). Because List mutability is common, I tried to always be explicit about when a new copy of a List was needed.

This informality seems to generally be adequate for human interpretation of the spec. Any effort to formalize the spec. or to perform mechanical analysis would probably need to replace List with somethings that were less informal.

@littledan

This comment has been minimized.

Show comment
Hide comment
@littledan

littledan Dec 9, 2016

Member

@allenwb Even though lists are used in various different ways, I think it's in common among all uses that there is no implicit copying of them when they're passed around. Would it be bad to add some wording to clarify this?

Member

littledan commented Dec 9, 2016

@allenwb Even though lists are used in various different ways, I think it's in common among all uses that there is no implicit copying of them when they're passed around. Would it be bad to add some wording to clarify this?

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Dec 29, 2016

Member

I'd like to add the following to algorithm conventions:

Algorithm steps may declare named aliases for any value using the form “Let x be someValue”. These aliases are reference-like in that both x and someValue refer to the same underlying data and modifications to either are visible to both. Algorithm steps that want to avoid this reference-like behavior should explicitly make a copy of the right-hand side: “Let x be a copy of someValue” creates a copy of someValue.

Member

bterlson commented Dec 29, 2016

I'd like to add the following to algorithm conventions:

Algorithm steps may declare named aliases for any value using the form “Let x be someValue”. These aliases are reference-like in that both x and someValue refer to the same underlying data and modifications to either are visible to both. Algorithm steps that want to avoid this reference-like behavior should explicitly make a copy of the right-hand side: “Let x be a copy of someValue” creates a copy of someValue.

@littledan

This comment has been minimized.

Show comment
Hide comment
@littledan

littledan Dec 29, 2016

Member

+1 to @bterlson's language. I like how it applies to all objects--nothing is specifical about lists.

I can't lose this pedantry contest, so here's a new tangential point: Should we make it clear that 'a copy' refers to a shallow copy somehow? Maybe 'a copy' should be an operation on spec types specifically. Almost all usages are on spec records (if that includes property descriptors and environments) or lists, except for String.prototype.trim which could be reworded. If 'a copy' is restricted to spec types, it is easier to understand what it means to be shallow.

Member

littledan commented Dec 29, 2016

+1 to @bterlson's language. I like how it applies to all objects--nothing is specifical about lists.

I can't lose this pedantry contest, so here's a new tangential point: Should we make it clear that 'a copy' refers to a shallow copy somehow? Maybe 'a copy' should be an operation on spec types specifically. Almost all usages are on spec records (if that includes property descriptors and environments) or lists, except for String.prototype.trim which could be reworded. If 'a copy' is restricted to spec types, it is easier to understand what it means to be shallow.

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Dec 29, 2016

Member

Seems good to specify that it's a shallow copy. Perhaps it's enough to simply insert "shallow":

Algorithm steps that want to avoid this reference-like behavior should explicitly make a copy of the right-hand side: “Let x be a copy of someValue” creates a shallow copy of someValue.

Member

bterlson commented Dec 29, 2016

Seems good to specify that it's a shallow copy. Perhaps it's enough to simply insert "shallow":

Algorithm steps that want to avoid this reference-like behavior should explicitly make a copy of the right-hand side: “Let x be a copy of someValue” creates a shallow copy of someValue.

@domenic

This comment has been minimized.

Show comment
Hide comment
@domenic

domenic Dec 30, 2016

Member

How about omitting the copy stuff altogether? It's not needed anywhere, right? And I'd expect it to be fully defined with algorithms for creating a new List/Record/etc. if we did use it.

Member

domenic commented Dec 30, 2016

How about omitting the copy stuff altogether? It's not needed anywhere, right? And I'd expect it to be fully defined with algorithms for creating a new List/Record/etc. if we did use it.

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Dec 30, 2016

Member

What does copy stuff refer to?

Member

bterlson commented Dec 30, 2016

What does copy stuff refer to?

@domenic

This comment has been minimized.

Show comment
Hide comment
@domenic

domenic Dec 30, 2016

Member

"Algorithm steps that want to avoid this reference-like behavior..."

Member

domenic commented Dec 30, 2016

"Algorithm steps that want to avoid this reference-like behavior..."

@littledan

This comment has been minimized.

Show comment
Hide comment
@littledan

littledan Dec 30, 2016

Member

Previously, "a copy" wasn't defined anywhere, but it was used in several places, so I like that this suggested text defines it.

Member

littledan commented Dec 30, 2016

Previously, "a copy" wasn't defined anywhere, but it was used in several places, so I like that this suggested text defines it.

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Dec 30, 2016

Member

Talked to Domenic offline, we think these changes are fine :) I'll commit.

Member

bterlson commented Dec 30, 2016

Talked to Domenic offline, we think these changes are fine :) I'll commit.

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