February 05, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tuesday, 5 February 2013 at 18:33:36 UTC, Andrei Alexandrescu wrote:
> I have a DIP in the making that makes "ref" entirely sealed, i.e. it makes it impossible to have a dangling ref in safe code. If that DIP gets approved, then DIP23 gets considerably simplified because operator& won't be applicable to the result of a function anymore.
>
>
> Andrei
I hope it at least considers my proposal with regard to 'out' return values. 'out' implies ref and guarantees that the result is as good as global:
out int foo(ref int a) { return a; } // Error, 'out' return may not return ref parameter
out int goo(ref int a) { return new int; } // Fine
My impression was that this would solve 98% of problems, the other 2% requiring scope parameters, which also imply ref:
ref int haa(ref int a, scope int b) { return b; } // Error, may not return scope parameter
ref int gaa(ref int a, scope int b) { return a; } // Fine
|
February 05, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | On Tuesday, 5 February 2013 at 19:44:03 UTC, Dmitry Olshansky wrote:
> 05-Feb-2013 23:37, Zach the Mystic пишет:
> [snip]
>>
>> While I appreciate your responding to my post, I'm a little confused
>> which of its points you are addressing here.
>
> Sorry, I posted reply to the wrong post.
I hope this doesn't end up being the primary reason people respond to my posts. :-)
|
February 05, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tuesday, 5 February 2013 at 18:33:36 UTC, Andrei Alexandrescu wrote: > [..] > Walter and I reviewed the discussion and had a long talk. We are very seriously considering banning the use of & against a ref result from a function (and actually ref parameters and even struct members in @safe code). [..] Did you consider using Rust's idea of 'Named lifetimes' in order to make ref parameters memory-safe. I haven't given much thought to it, but since Rust's borrowed pointers are effectively isomorphic to D's ref variables, it should work. Here's a Rust borrowed pointer tutorial: http://static.rust-lang.org/doc/tutorial-borrowed-ptr.html |
February 05, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 2/5/13 2:05 PM, Steven Schveighoffer wrote: > On Tue, 05 Feb 2013 13:33:35 -0500, Andrei Alexandrescu > <SeeWebsiteForEmail@erdani.org> wrote: > >> Walter and I reviewed the discussion and had a long talk. We are very >> seriously considering banning the use of & against a ref result from a >> function (and actually ref parameters and even struct members in @safe >> code). One would still be able to take the address of a field in a >> class because that's assumed to live on the GC heap. > > What about structs that live on the heap? e.g. a struct element of an > array, or a struct member of a class instance. In that case we'll disallow it conservatively. > I think the point about @safe code is moot, aren't pointers disallowed > in safe code anyway? Yah, time to start enforcing it more seriously. But we want to ban some uses of & in all code. >> To get the address of an object in @system code without resorting to >> operator& at all, we're considering adding a stdlib function >> implemented like this (there are several other ways, this is just for >> illustration): >> >> @system T* addressOf(T)(ref T obj) >> { >> static T* id(T* p) { return p; } >> auto idr = cast(T* function(ref T)) id; >> return idr(obj); >> } > > > I think a cast would be sufficient: > > cast(int *)(&refparam); // understood that a cast is required > > To jump through this machinery to turn a reference into a, um... > reference, seems like a huge waste of code space and resources. The whole point was to avoid using operator &. Andrei |
February 05, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 2/5/13 2:11 PM, H. S. Teoh wrote:
> On Tue, Feb 05, 2013 at 02:05:24PM -0500, Steven Schveighoffer wrote:
>> On Tue, 05 Feb 2013 13:33:35 -0500, Andrei Alexandrescu
>> <SeeWebsiteForEmail@erdani.org> wrote:
>>
>>> Walter and I reviewed the discussion and had a long talk. We are
>>> very seriously considering banning the use of& against a ref
>>> result from a function (and actually ref parameters and even
>>> struct members in @safe code). One would still be able to take the
>>> address of a field in a class because that's assumed to live on
>>> the GC heap.
>>
>> What about structs that live on the heap? e.g. a struct element of
>> an array, or a struct member of a class instance.
>>
>> I think the point about @safe code is moot, aren't pointers
>> disallowed in safe code anyway?
> [...]
>
> AFAIK, pointers are allowed in @safe code as long as no type casts or
> pointer arithmetic are performed.
Yah, apparently that's not sufficient. We must make sure pointers don't escape.
Andrei
|
February 05, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 2/5/13 2:21 PM, Steven Schveighoffer wrote: > On Tue, 05 Feb 2013 13:33:35 -0500, Andrei Alexandrescu > <SeeWebsiteForEmail@erdani.org> wrote: > >> Walter and I reviewed the discussion and had a long talk. We are very >> seriously considering banning the use of & against a ref result from a >> function (and actually ref parameters and even struct members in @safe >> code). One would still be able to take the address of a field in a >> class because that's assumed to live on the GC heap. > > Back to the problem I stated, how does one do this: > > ref A foo(); > > ref A bar(); > > A *a; > > if(condition) > a = &foo(); > else > a = &bar(); > > // use a for a few lines > > I can see a possible solution but it's not pretty: > > void processA(ref A a) > { > // lines that deal with a here > } > > if(condition) > processA(foo()); > else > processA(bar()); > > But this kind of seems hacky. Why should I have to declare a function > just to keep a persistent reference to a return value for the scope of > my function? Not only is is awkward, there is a performance hit in that > I have to call another function. You define the function in situ. We understand some valid code will be disallowed by the change, > Note also that this doesn't fix memory issues: > > struct S > { > ref S self() {return this;} > } > > ref S bad() > { > S s; > return s.self(); > } > > Which I believe would be valid still with your rules. Also consider the simpler: ref int id(ref int x) { return x; } ref int id1(ref int x) { return id(x); } ref int id2(ref int x) { return id1(x); } ref int oops(int x) { return id2(x); } DIP24 addresses that and other similar cases at their core. Andrei |
February 05, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 2/5/13 2:25 PM, Steven Schveighoffer wrote:
> On Tue, 05 Feb 2013 13:33:35 -0500, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org> wrote:
>
>> Walter and I reviewed the discussion and had a long talk. We are very
>> seriously considering banning the use of & against a ref result from a
>> function (and actually ref parameters and even struct members in @safe
>> code). One would still be able to take the address of a field in a
>> class because that's assumed to live on the GC heap.
>
> Thinking about this some more, would this be allowed:
>
> @trusted T *getAddr(T)(ref T obj) { return &obj; } // allowed? You said
> only @safe code would disallow address of ref parameters
We hope to be able to disallow it.
Andrei
|
February 05, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Zach the Mystic | On 2/5/13 2:44 PM, Zach the Mystic wrote:
> On Tuesday, 5 February 2013 at 18:33:36 UTC, Andrei Alexandrescu wrote:
>> I have a DIP in the making that makes "ref" entirely sealed, i.e. it
>> makes it impossible to have a dangling ref in safe code. If that DIP
>> gets approved, then DIP23 gets considerably simplified because
>> operator& won't be applicable to the result of a function anymore.
>>
>>
>> Andrei
>
> I hope it at least considers my proposal with regard to 'out' return
> values. 'out' implies ref and guarantees that the result is as good as
> global:
>
> out int foo(ref int a) { return a; } // Error, 'out' return may not
> return ref parameter
> out int goo(ref int a) { return new int; } // Fine
>
> My impression was that this would solve 98% of problems, the other 2%
> requiring scope parameters, which also imply ref:
>
> ref int haa(ref int a, scope int b) { return b; } // Error, may not
> return scope parameter
> ref int gaa(ref int a, scope int b) { return a; } // Fine
I'm sorry, I didn't know of that proposal. Generally we're aiming for economy of means i.e. we want to clarify semantics of existing syntax instead of adding new syntax and semantics.
Andrei
|
February 05, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to TommiT | On 2/5/13 3:08 PM, TommiT wrote:
> On Tuesday, 5 February 2013 at 18:33:36 UTC, Andrei Alexandrescu wrote:
>> [..]
>> Walter and I reviewed the discussion and had a long talk. We are very
>> seriously considering banning the use of & against a ref result from a
>> function (and actually ref parameters and even struct members in @safe
>> code). [..]
>
> Did you consider using Rust's idea of 'Named lifetimes' in order to make
> ref parameters memory-safe. I haven't given much thought to it, but
> since Rust's borrowed pointers are effectively isomorphic to D's ref
> variables, it should work. Here's a Rust borrowed pointer tutorial:
> http://static.rust-lang.org/doc/tutorial-borrowed-ptr.html
Thanks, I'll give that a read. We're very careful at this point about spending much "complexity budget" (as a friend calls it) on new features.
Andrei
|
February 05, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tuesday, 5 February 2013 at 20:24:16 UTC, Andrei Alexandrescu wrote:
>> I hope it at least considers my proposal with regard to 'out' return
>> values. 'out' implies ref and guarantees that the result is as good as
>> global:
>>
>> out int foo(ref int a) { return a; } // Error, 'out' return may not
>> return ref parameter
>> out int goo(ref int a) { return new int; } // Fine
>>
>> My impression was that this would solve 98% of problems, the other 2%
>> requiring scope parameters, which also imply ref:
>>
>> ref int haa(ref int a, scope int b) { return b; } // Error, may not
>> return scope parameter
>> ref int gaa(ref int a, scope int b) { return a; } // Fine
>
> I'm sorry, I didn't know of that proposal. Generally we're aiming for economy of means i.e. we want to clarify semantics of existing syntax instead of adding new syntax and semantics.
>
> Andrei
It's not a new syntax, just new semantics. Also, the reason for adding these semantics to the function signature was so that the compiler would never have to leave the function in order to compile it. It's a natural complement to ref returns' scope being the most local of the ref parameters, which you suggested in your proposal. It keeps that too.
|
Copyright © 1999-2021 by the D Language Foundation