A fresh lifetime is a better default behaviour. For example,
fn F(x: &mut T)
could be either
fn A<'a>(x: &'a mut T<'a>)
or
fn B<'a, 'b>(x: &'a mut T<'b>)
In A, it's possible for any borrow with lifetime 'a to escape via the
mutable state in x, including the borrow into x itself. This makes it so
you can't call A with any `&mut T` that has a shorter lifetime than the
contents of the T, and the borrow into A will be alive and inaccessible for
the remainder of the lifetime of the contents of the T. B is almost
certainly what people will want when they write F.
On Tuesday, April 23, 2013, Paulo Sérgio Almeida wrote:
> Ok. Suppose the current syntax is frozen. But I talked about two things:
> syntax for explicit lifetimes (mainly point 3, altough a bit also in points
> 1 and 2) and defaults for when no explicit (named) lifetimes are used.
>
> Even if no syntax change is made, for the cases when named lifetimes are
> used, what I find specially painful is the default rule when no explicit
> lifetimes are used:
>
> "an implicit fresh lifetime for each parameter and result".
>
> This rule, specially when a result is involved, which is exactly one of
> the cases when stating lifetime is needed, seems to make little sense, and
> will force named lifetimes to be used in many cases, causing noise and
> distraction and decreasing legibility.
>
> In what way is the default that I propose, which basically is:
>
> "one implicit fresh lifetime for each type parameter and another for all
> the remainder parameter types"
>
> confusing or a possible source of obscurity? I find it quite natural that,
> e.g., if I am returning a borrowed reference (not a copy, not an owned, not
> a @) of type T and I have received one or more borrowed references to T,
> i.e.:
>
> fn f<T>(p1: &T, p2: &T, ...) -> &T { ... }
>
> the *natural* thing to expect is that the result comes from one of the T
> that I received as parameters, and the default that I propose is not
> obscure at all, but makes the code cristal clear. I find having to write
>
> fn f<'r, T>(p1: &'r T, p2: &'r T, ...) -> &'r T { ... }
>
> because of the current defaults, needlessly painful and distracting. Is
> the current default less obscure? Will it cause less surprise? Or it is the
> other way around ...
>
> Regards,
> Paulo
>
>
> On 4/23/13 4:11 PM, Niko Matsakis wrote:
>
>> Thanks for your proposal. We've been through a number of rounds with the
>> lifetime syntax, including an earlier scheme that was quite similar to
>> what you propose in some regards (there was a single anonymous lifetime
>> parameter that was used whenever you wrote `&T`, which meant that yes
>> you often did not need to use explicit lifetime parameter names).
>>
>> However, we found that this was ultimately more confusing to people than
>> helpful. One of the goals of the current syntax was to make the
>> mechanism of named lifetimes more explicit and thus more clear to the
>> reader. Smarter defaults have the disadvantage that they often obscure
>> the underlying system, making it harder to learn what's really going on.
>>
>> In practice,named lifetimes don't seem to be that common, at least for
>> me. We should do some numerical analysis, but I've found subjectively
>> that most functions simply consume data and do not return pointers. This
>> is particularly true for "non-library" code, and even more true with
>> judicious use of `@` pointers (it is often not worth the trouble to
>> avoid the GC; it can make life much easier, that's what it's there for).
>>
>> So in summary I do not think it likely we will change the current syntax.
>>
>>
>> Niko
>>
>>
>>
>> On Mon, Apr 22, 2013 at 12:21 PM, Paulo Sérgio Almeida <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> Hi all,
>>
>> (My first post here.)
>> First, congrats for what you are trying to achieve with Rust. I
>> arrived very late to the party, and so I am not sure that what I
>> will say can be of use. But as I understand, lifetimes is one of
>> those things that are not completely solidified, and anyway, better
>> late than never.
>>
>> Looking at some code, expressing lifetimes of borrowed references is
>> one of those things that is somewhat bewildering, making the code
>> somewhat noisy. I think it can be improved through a better choice
>> of defaults and a slight change in explicit lifetimes.
>>
>> The main thing I think is "wrong" is the defaults for function
>> parameters. From the tutorial: "the compiler simply creates a fresh
>> name for the lifetime automatically: that is, the lifetime name is
>> guaranteed to refer to a distinct lifetime from the lifetimes of all
>> other parameters."
>>
>> This default is not very useful. For example, it is wrong basically
>> everytime we want to return a borrowed pointer (unless, for a global
>> variable?). The more common case is returning something with the
>> same lifetime as some parameter. In many cases we don't need to
>> distinguish parameters, and specify which we are returning, in
>> others we want to split parameters in two equivalence classes, the
>> one from which we are returning, and everything else.
>>
>> When type parameters are involved, a return type typically says
>> where the result comes from most of the times. Again, the default
>> should be different. E.g., when we are returning a borrowed
>> reference to a "key" of type parameter K, the default should be
>> "other things also of type K in parameters".
>>
>> Finally, with better defaults, in the remaining cases where we need
>> to explicitly express lifetimes, having to "invent" identifiers is a
>> nuisance. Also the space which must be used between the lifetime
>> identifier and the type is too distracting and makes it cumbersome
>> (for humans) to "parse" the type of some identifier.
>>
>> I have been thinking about this and have the following proposal. (Of
>> course there may be inumerous things that must have escaped me, but
>> here it goes anyway.)
>>
>> ---
>> Regarding types for borrowed references in function parameters or
>> result, and type parameters:
>>
>> 1) each type-parameter has an associated implicit lifetime, which by
>> default is different from the lifetimes of other type-parameters or
>> normal function parameter types, but it can be qualified in each
>> declaration or use with an explicit lifetime;
>>
>> 2) function parameter types or return type that are not type
>> parameters have all the same implicit lifetime by default, but they
>> can be qualified explicitly with some lifetime.
>>
>> 3) explicit lifetimes are written identifier' instead of
>> 'identifier; a null identifier is allowed, as in &'T, to qualify a
>> reference &T with lifetime '.
>> ---
>>
>> (Another useful possibility would be allowing several ' at the end,
>> allowing e.g., &T, &'T, &''T as borrowed references to the same type
>> but with different lifetimes. In practice, a single ' plus 1) and 2)
>> will cover "99%" of cases. We could even get rid of using
>> identifiers, using only several '. But this is not relevant for the
>> main proposal.)
>>
>> 1) and 2) are about defaults for implicit lifetimes, which currently
>> are "fresh lifetime for each parameter", and 3) is about simplifying
>> the remaining cases of explicit expression. The motivation for 3) is
>> to remove both the need of a space separating lifetime from type and
>> also the need to "invent" lifetime identifiers. Rewriting examples
>> from the tutorial and elsewhere, under this proposal, would make
>> code more legible and standard, reducing a lot the need for explicit
>> lifetime expression. Things would "just work" as wanted most times.
>>
>> ------------------------------**------------------------------**
>> --------------------
>>
>> From the Rust Borrowed Pointers Tutorial
>>
>> ---
>>
>> fn get_x<'r>(p: &'r Point) -> &'r float { &p.x }
>>
>> becomes
>>
>> fn get_x(p: &Point) -> &float { &p.x }
>>
>> ---
>>
>> fn select<'r, T>(shape: &'r Shape, threshold: float,
>> a: &'r T, b: &'r T) -> &'r T {
>> if compute_area(shape) > threshold {a} else {b}
>> }
>>
>> becomes
>>
>> [email protected] <mailto:[email protected]>
>>
>> https://mail.mozilla.org/**listinfo/rust-dev<https://mail.mozilla.org/listinfo/rust-dev>
>>
>>
>>
> ______________________________**_________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/**listinfo/rust-dev<https://mail.mozilla.org/listinfo/rust-dev>
>
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev