More magical AA semantics

H. S. Teoh hsteoh at quickfur.ath.cx
Fri Jan 11 08:15:28 PST 2013


On Fri, Jan 11, 2013 at 08:53:44AM +0100, Don wrote:
> Consider this code:
> ---
>    int[int] x;
> 
>    int k = x[2] + 5; // Error, range violation. Makes sense.
> 
>    x[2] = x[2] + 5;  // But this works!!!
> ---
> 
> That is, x[2] doesn't exist, *unless you are about to assign to
> it*.

http://d.puremagic.com/issues/show_bug.cgi?id=3825


> What happens is:
> 1. lvalue index (creates x[2], sets it to int.init)

Actually it doesn't. It binary-zeroes the entry.


> 2. rvalue index (returns x[2], which is now 0)
> 3. lvalue index assign (sets x[2] = 5)
> 
> In reality, step 1 returns a pointer to the newly created element.

Yeah that's pretty much what's happening currently.


> How could this be implemented as a library type?

I'd argue that this behaviour is a bug, and *shouldn't* be implemented
in the library type. This behaviour causes, for example, real[string] to
have 0.0 as default entry value instead of nan, like the rest of the
language.


> The superficially similar case, x[2] += 5; can be implemented
> with opIndexOpAssign. But I don't know how to do this one.

There's another problem: there is currently no operator overload that
can handle things like a['b']['c']=d, because the first [] is a lookup
and the second [] is an assignment.


> Note that elements are not always magically created when an
> lvalue is required. AFAIK it only happens in assignment. For
> example this code gives a runtime error:
> ---
> void foo(ref int g) { ++g; }
> 
>    int[int] x;
>    foo( x[2] );  // range error, x[2] doesn't exist yet
> ---

I think this is correct behaviour. The previous case I consider a bug.


T

-- 
No! I'm not in denial!


More information about the Digitalmars-d mailing list