April 10, 2012
On 4/10/12 11:50 PM, Jonathan M Davis wrote:
> On Tuesday, April 10, 2012 23:33:11 Andrei Alexandrescu wrote:
>> I think this all holds water. Destroy!
>
> So, this essentially erases the difference between lvalues and rvalues as far
> as ref is concerned? ref will effectively have nothing to do with lvalues or
> rvalues?

Except when an implicit conversion is in the mix, yes. It's conversions and escapes that spoil things. We disallow conversion results to bind to ref and abolish ref escapes altogether, so I think we should be fine.

Nevertheless please attack this any way you can. We better find bugs now rather than later.


Andrei

_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 10, 2012

On 4/10/2012 9:52 PM, Jonathan M Davis wrote:
> Are you intending to implement this for 2.059 or wait for 2.060? It would certainly mitigate the issues that we've been having with opEquals and opCmp, but it would obviously delay the release a bit. - Jonathan M Davis

I'm planning on doing it for 2.059. If we wait, then we pointlessly force people to rewrite their code.
_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 10, 2012
On Tuesday, April 10, 2012 23:56:05 Andrei Alexandrescu wrote:
> Nevertheless please attack this any way you can. We better find bugs now rather than later.

I'm definitely going to have to think this one through quite a bit before I can really give any meaningful feedback, I suspect. It seems like the sort of thing where everything seems great until one minor detail gets pointed out which ruins the whole thing.

- Jonathan M Davis
_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 10, 2012
On Tuesday, April 10, 2012 22:00:45 Walter Bright wrote:
> On 4/10/2012 9:52 PM, Jonathan M Davis wrote:
> > Are you intending to implement this for 2.059 or wait for 2.060? It would certainly mitigate the issues that we've been having with opEquals and opCmp, but it would obviously delay the release a bit. - Jonathan M Davis
> I'm planning on doing it for 2.059. If we wait, then we pointlessly force people to rewrite their code.

It's fine with me. I was just looking to find out what the plan was. opEquals and opCmp for structs have always been a little iffy due to const ref, and this release would probably make that situation worse as it stands. This proposal appears to make it _much_ better (assuming that no one can find any major problems with it).

- Jonathan M Davis
_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 11, 2012
On 4/11/12 12:02 AM, Jonathan M Davis wrote:
> On Tuesday, April 10, 2012 23:56:05 Andrei Alexandrescu wrote:
>> Nevertheless please attack this any way you can. We better find bugs now
>> rather than later.
>
> I'm definitely going to have to think this one through quite a bit before I can
> really give any meaningful feedback, I suspect. It seems like the sort of
> thing where everything seems great until one minor detail gets pointed out
> which ruins the whole thing.

Yup, that's why the big boys use formal proofs.

Andrei

_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 11, 2012

On Apr 11, 2012, at 02:57 AM, Walter Bright <walter@digitalmars.com> wrote:

> Our D solution, disallowing rvalue references, is technically sound but as we've discussed here is a usability disaster, and auto ref isn't going to cut it. We figured a solution is:
>
> *** Allow rvalue references, however, disallow any implicit conversions of the literal's type in the process of taking a reference to it. ***
>
> That takes care of 1 and 2. The solution to 3 is a bit more subtle. Some people have wondered why the D compiler can create reference types itself, but does not allow the user to outside of function parameters and foreach variables. This is the reason why. References, in order to be safe, must not be allowed to escape a scope. They can only be passed downward to enclosed scopes, and returned from functions where the return value is checked. Also, one cannot take the address of a reference. I think this closes the holes.
>
> With all that, I intend to once again allow struct literals to be lvalues for 2.059. Somewhat later, also allow references to other literals like 0 and 5.6.

I think this should be posted on the newsgroup as well.

--
/Jacob Carlborg

April 11, 2012



I think this all holds water. Destroy!
>
>Andrei
>
>
First, let me just say, I really like this change.  This makes the most sense to me.  I always felt it was an artificial limitation, especially when 'this' is passed by ref but is always bindable to rvalues.

But let me play devil's advocate here, because I think this needs to be fully vetted.

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

Issue 1:

In TDPL, you say:

for context:
void bump(ref int x) {++x;}


"If a function expects a ref, it accepts only "real" data, not temporaries;  anything that's not an lvalue is rejected during compilation; for example:

    bump(5); // Error! Cannot bind an rvalue to a ref parameter

This prevents silly mistakes when people believe work is being done but in fact the call has no visible affect."

This is in section 5.2.1


Now, this obviously becomes valid code.  Are you OK with this?  It seemed like a major explanation as to why refs don't bind to rvalues.  I personally think it's just "coder beware".

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

Issue 2:

Another reason I remember you stating as to why rvalues cannot bind to ref is that it's not the most efficient semantics.  So if rvalues bind to both non-ref and ref, can you have overloads between ref and non-ref for optimization purposes?


Note that this is *valid* code with 2.058 (and probably many previous compilers):

import std.stdio;

void foo(ref int x) { writeln("ref"); }
void foo(int x) { writeln("nonref"); }

void main()
{
    int x;
    foo(x);
    foo(5);
}

prints:
ref
nonref

Will this still compile under the new rules, or will it be ambiguous?

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

Issue 3:

The point that you cannot take an address of a ref value is going to cause a *lot* of existing code to fail.  I don't really like this rule for code that isn't marked @safe (which should disallow taking addresses anyway).  It seems overly restrictive, and it will be viral in nature.  I know you mentioned this is the "long term plan", are the other parts of this severable from this?  Is the plan to implement this right now or later?  Can you explain why the existing requirements that you don't use pointers in @safe code isn't enough?


-Steve


April 11, 2012
On Apr 11, 2012, at 12:14 AM, Walter Bright <walter@digitalmars.com> wrote:

> 
> 
> On 4/10/2012 8:36 PM, Jason House wrote:
>> 
>> While I have no plans to use it, what mechanism, if any, will allow escaping the address? Usually, casts are the back door, but I don't believe that works in this case.
> 
> Case 3.

I understand that, but D is a systems language and allows a determined programmer to do what they need. I could imagine passing a ref to a thread and ensuring that it finishes before the function exits. D usually allows a back door for such things, and disallows such back doors in SafeD

April 11, 2012
Le 2012-04-10 à 23:36, Jason House a écrit :

> While I have no plans to use it, what mechanism, if any, will allow escaping the address? Usually, casts are the back door, but I don't believe that works in this case.

There's always this middle ground: taking the address of a ref could give you a void*. That way you really can't do anything unsafe with it without a cast.

Heck, with this trick you could even allow SafeD to take the address of anything. You wouldn't be able to do much without a cast beside comparing and printing addresses, but even that could be handy for debugging and checking for aliasing.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/



_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 11, 2012
I like this idea, but unfortunately, void* is read/writeable -- most low-level C functions that use a buffer take void *.

I also think void[] is writeable, and can be created from a void * without a cast.

-Steve




>________________________________
> From: Michel Fortin <michel.fortin@michelf.com>
>To: Discuss the dmd beta releases for D <dmd-beta@puremagic.com>
>Sent: Wednesday, April 11, 2012 8:50 AM
>Subject: Re: [dmd-beta] rvalue references
> 
>Le 2012-04-10 à 23:36, Jason House a écrit :
>
>> While I have no plans to use it, what mechanism, if any, will allow escaping the address? Usually, casts are the back door, but I don't believe that works in this case.
>
>There's always this middle ground: taking the address of a ref could give you a void*. That way you really can't do anything unsafe with it without a cast.
>
>Heck, with this trick you could even allow SafeD to take the address of anything. You wouldn't be able to do much without a cast beside comparing and printing addresses, but even that could be handy for debugging and checking for aliasing.
>
>-- 
>Michel Fortin
>michel.fortin@michelf.com
>http://michelf.com/
>
>
>
>_______________________________________________
>dmd-beta mailing list
>dmd-beta@puremagic.com
>http://lists.puremagic.com/mailman/listinfo/dmd-beta
>
>
>