DMD 0.177 release

Andrei Alexandrescu (See Website For Email) SeeWebsiteForEmail at erdani.org
Thu Dec 14 22:15:25 PST 2006


Kevin Bealer wrote:
> This reminds me of the "opIndex" discussion we had here quite a while ago.  The
> problem was that for user defined containers, you can't simulate X[i] if the
> contained type is something like a struct.
> 
> class C {
>    S s1;
> 
>    S opIndex(int i)
>    {
>       return s1;
>    }
> }
> 
> There is an opIndexAssign(), but it has the same problem when applied to the inout
> parameter.

Hm. This inability to return lvalues looks like a serious loophole
within D's type system.

> 1. Add a return type qualifier with "inout" semantics, like a C++ "&" type.
> 
>     Something like one of these, inout of course looks a bit funny:
> 
>     ref S opIndexRef(int i);
>     inout S opIndexRef(int i);

This will have serious ripples through the type system. For example, 
people might start to ask themselves whether they can define standalone 
inout variables, and what that means. Or, tell inside a template whether 
it received an inout parameter or not.

At any rate, Perl 5 has implemented this exact hack, and seems to be
working with it. See:

http://search.cpan.org/~nwclark/perl-5.8.7/pod/perlsub.pod#Lvalue_subroutines

The Perl guys seem to be unhappy about it because they labeled it as 
"experimental" in Perl 5 and they discuss eliminating it in Perl 6, in 
favor of some even more exotic features. See:

http://dev.perl.org/perl6/rfc/149.html

> 2. Return S* and let the compiler apply the "*".
> 
>     S* opIndex(int i);
>     Compiler silently transforms foo(x[i]) into foo(*x[i])

This is also (probably more) unsatisfactory. People will be able to
index and obtain lvalues, but will be unable to return something
assignable from a function:

++s[a]; // possible through a compiler hack
++s(a, b); // impossible

> Conceptually, the problem looks similar to me: how to "tunnel" an assignable type
> through a return value of a method, like the C++ "&" types do.  The opIndex
> version needs to tunnel up through more layers than opAssign() does since it's not
> the A type, so the (a.opIndex(b), a) can't work there of course.
> 
> I would vote for "S*" being the conceptual return type in both cases for
> opAssign() and opIndex(), although in the case of opAssign() it wouldn't bother me
> if the user visible signature was "void opAssign(...)" and the compiler handles
> the pointer as it does with this().

I see this as D's #1 major problem as of today. I think the function
returning inout is better, but I foresee a bunch of issues with it. The
question whether lvalues are needed beyond function return values must
be satisfactorily answered.


Andrei




More information about the Digitalmars-d-announce mailing list