Structs

Brendan Eich brendan at mozilla.com
Wed Jun 2 22:26:51 PDT 2010


On Jun 2, 2010, at 3:50 PM, Waldemar Horwat wrote:

> Brendan Eich wrote:
>> So either we lose this refactoring equivalence:
>> b = a[i];
>> b.x = 42;
>> assert(a[i].x === 42);
>> This assertion botches with Sam's proposed semantics.
>> Or else we lose the other equivalence, if we reify a struct-view- 
>> object on element extraction (rvalue):
>> a[j] = a[i];
>> a[j].x = 42;
>> assert(a[i].x === 42);
>> This example is just like the one above, but uses a[j] for some  
>> valid index j, instead of a b temporary. Note that with objects  
>> (reference types), specifically a plain old Array of object  
>> instances, the assertion holds. But with the sketchy struct  
>> semantics I've been proposing, typed-array-of-struct elements  
>> behave like value types when assigned to (lvalues), so this  
>> assertion botches .
>> Structs can't be fully (mutable) value types without breaking one  
>> equivalence. Yet they can't be reference types or we lose the  
>> critical in-line allocation and packing that WebGL needs, but this  
>> leaves them in limbo, breaking another equivalence.
>
> Aargh, what fun!  This is one of the more fascinating aspects of not  
> having type annotations.
>
> Possibly the most ECMAScripty approach would be to break the first  
> equivalence by making the step that converts lvalues to rvalues  
> convert struct references into copies of structs.  In ES5 terms this  
> would be the GetValue internal call.  Struct references would not be  
> first class any more than lvalues are.

For an expression a[i]j.x, the ES specs all evaluate a[i], call  
GetValue on it if a Reference, then make a new Reference with the  
result as base and 'x' as the propertyName. Only then, depending on  
whether a[i].x occurs as the left-hand side of assignment or in a RHS  
expression, e.g., would we PutValue or GetValue.

For what you suggest (which was Sam's thought, inspired by C#), we  
would need to preserve the a[i] struct reference instead of calling  
GetValue and copying to a fresh struct value. We'd need to factor the  
internal methods so that the value of the expression to the left of .  
followed by Identifier could remain a struct reference (presumably the  
same goes for [ instead of .), while any other struct reference result  
would be "dereferenced" by creating a copy.

IINM this was Oliver's point in reply. He was advocating the alias  
alternative, where structs reify as "view objects", fat pointers or  
aliases. Either way could be made to work.

Which is more ECMAScripty is not clear to me, due to both equivalences  
being useful for arrays of objects (arrays of true reference types). I  
do not think GetValue, an internal spec method, supports the user's  
principle of least astonishment. I rather suspect that implicit struct  
copies will be surprising, given their mutability (yet no aliasing of  
the original element of the array whence they came).

/be


More information about the es-discuss mailing list