Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upClarification required that Lists are 'referency' #752
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
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 ?
|
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 ? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
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).
|
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. (Yes, I am in pedantic mode). |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
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.
|
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. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
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.
|
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. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
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.
|
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. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
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?
|
@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? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
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.
|
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. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
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.
|
+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. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
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.
|
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. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
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.
|
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. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
What does copy stuff refer to? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
"Algorithm steps that want to avoid this reference-like behavior..." |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
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.
|
Previously, "a copy" wasn't defined anywhere, but it was used in several places, so I like that this suggested text defines it. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bterlson
Dec 30, 2016
Member
Talked to Domenic offline, we think these changes are fine :) I'll commit.
|
Talked to Domenic offline, we think these changes are fine :) I'll commit. |
IgnoredAmbience commentedDec 9, 2016
In 8.1.1.4.7 Global Environment Records DeleteBinding(N) step 7b,
varNamesis assigned the List value fromenvNames.[[VarNames]]. SubsequentlyvarNameshas an element removed. The algorithm does not explicitly propagate this value back to theenvNamesrecord.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.