On Sunday, 5 May 2013 at 00:47:00 UTC, Walter Bright wrote:
If the compiler accepts that code, it will crash at runtime. If
it doesn't accept that code, then it will also disallow
legitimate code like:
ref T foob(ref U u) { static T t; return t; }
ref T bar() { U u; return foob(u); }
It doesn't accept it, with or without any combination of
annotation. Now, the example with a static effectively require an
annotation.
And it illustrate
wonderfully what I'm saying : most people in the discussion
(and it has been
shown now that this includes you) were unaware of how does
Rust solve the problem.
I don't think excluding a solution that isn't understood is
the smartest thing
to do.
I suggest you enumerate the cases with a Rust-like system and
show us how it solves the problem without annotations. Note
that Rust has pretty much zero real world usage - it's one
thing to say needing to use annotations is 'rare' and another
to know it based on typical usage patterns of the language.
Rust assume, when no annotation is present, that the return ref's
lifetime is the union of ref parameters lifetime. I'm sure we can
find an example of D code somewhere that don't fit into this, but
real world usage in D would almost never require any annotation
(this is the case of all D codebase I've played with as of now,
and I don't actually see any use case for example like the static
one mentioned above).
For example, if the default is "assume the ref return refers to
the ref parameter", then some containers would require the
annotation and some would not. This is not very viable when
doing generic coding, unless you are willing to provide two
copies of each such function - one with the annotations and the
other without.
The default can't be that as several parameters can be passed by
ref. The default is return ref lifetime is the union of ref
parameters lifetime. I don't see any container that require the
annotation.
Note also that if you have A calls B calls C, the annotation on
C doesn't propagate up to B, again leading to a situation where
you're forced to make two versions of the functions.
(I say doesn't propagate because in a language that supports
separate compilation, all the compiler knows about a function
is its signature.)
It doesn't require code duplication. Named lifetime make sense
for the caller, not the callee (in which they only are identifier
that can be used to describe lifetime's relation explicitly for
the caller).