[Issue 9238] Support rvalue references

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed Jan 9 15:03:11 PST 2013


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


Andrei Alexandrescu <andrei at erdani.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrei at erdani.com


--- Comment #10 from Andrei Alexandrescu <andrei at erdani.com> 2013-01-09 15:03:08 PST ---
Desiderata
==========

Design choices may sometimes invalidate important use cases, so let's start
with what we'd like to have:

1. Safety

We'd like most or all uses of ref to be safe. If not all are safe, we should
have easy means to distinguish safe from unsafe cases statically. If that's not
possible, we should be able to enforce safety with simple runtime checks in
@safe code.

2. Efficient passing of values

The canonical use case of ref parameters is to allow the callee to modify a
value in the caller. However, a significant secondary use case is as an
optimization for passing arguments into a function. In such cases, the caller
is not concerned with mutation and may actually want to prevent it. The
remaining problem is that ref traditionally assumes the caller holds an actual
lvalue, whereas in such cases the caller may want to pass an rvalue.

3. Transparently returning references to ref parameters

One important use case is functions that return one of their reference
parameters, the simplest being:

ref T identity(T)(ref T obj) { return obj; }

We'd like to allow identity and to make it safe by design. If we don't, we
disallow a family of use cases such as min() and max() that return by
reference, call chaining idioms etc.

4. Sealed containers

This important use case is motivated by efficient and safe allocators. We want
to support scoped and region-based allocation, and at the same time we want to
combine such allocators with containers that return references to their data.

Consider as a simple example a scoped container:

struct ScopedContainer(T)
{
    private T[] payload;
    this(size_t n) { payload = new T[n]; }
    this(this) { payload = payload.dup; }
    ~this() { delete payload; }
    void opAssign(ref ScopedContainer rhs) {
      payload = rhs.payload.dup;
    }
    ref T opIndex(size_t n) { return payload[n]; }
}

The container eagerly allocates its state and deallocates it when it leaves
scope. We'd like to allow opIndex to typecheck and guarantee safety.

5. Simplicity

We wish to get the design right with maximum economy in language design. One
thing easily forgotten when focusing minutia while carrying significant context
in mind is that whatever language additions we make come on top of an already
large machinery.

There have been ideas based on defining "scope ref", "in ref", or "@attribute
ref". We'd like to avoid such and instead make sure plain "ref" is useful,
safe, and easy to understand.  

------------

These desiderata and the interactions among them impose constraints on the
design space. In the following post I'll sketch some possible designs dictated
by prioritizing desiderata, and analyze the emerging tradeoffs.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list