View mode: basic / threaded / horizontal-split · Log in · Help
August 29, 2012
Why can't we make reference variables?
In the following example code there's a situation, where the data 
we're looking for already exists, the data has value semantics, 
finding the data takes quite a lot of time, we need to "use" the 
data on multiple occasions, and the size of the data is so large 
that we don't want to copy it.

In this situation, I think, the most convenient and sensible 
thing to do is to make a reference to the data, and use that 
reference multiple times. We could make a pointer, but then we'd 
be stuck with the nasty syntax of dereferencing:

struct Book // has value semantics
{
    // ... lots of data

    void read() const
    {
        // ...
    }
}

struct NationalLibrary
{
    immutable Book[] _books;

    ref immutable(Book) find(string nameOfBook)
    {
        auto idx = 0;
        // ... takes quite long to figure out the index
        return _books[idx];
    }
}

void main()
{
    NationalLibrary nl;

    // This is fine if we just want to read it once:
    nl.find("WarAndPeace").read();
	
    // ... but if we want to read it multiple times, we don't want
    // to each time go to the library and take the time to find 
it:

    immutable(Book)* ptrWarAndPeace = &nl.find("WarAndPeace");
    // And now we're stuck with this syntax:
    (*ptrWarAndPeace).read();
    (*ptrWarAndPeace).read();

    // I'd like to be able to do this:	
    // ref immutable(Book) refWarAndPeace = 
nl.find("WarAndPeace");
    // refWarAndPeace.read();
    // refWarAndPeace.read();
}

Foreach loops can make reference variables, and function calls 
can do it for the parameters passed in. So, my question is, 
wouldn't it be better if we could, in general, make reference 
variables?
August 29, 2012
Re: Why can't we make reference variables?
On Wednesday, 29 August 2012 at 00:21:29 UTC, Tommi wrote:
> In this situation, I think, the most convenient and sensible 
> thing to do is to make a reference to the data, and use that 
> reference multiple times. We could make a pointer, but then 
> we'd be stuck with the nasty syntax of dereferencing:

This works currently:

struct Test
{
    void foo() const
    {
        writeln("FOO");
    }
}

void main()
{
    immutable(Test)* ptr = new immutable(Test);
    ptr.foo();
}
August 29, 2012
Re: Why can't we make reference variables?
On Wednesday, 29 August 2012 at 00:34:02 UTC, cal wrote:
> On Wednesday, 29 August 2012 at 00:21:29 UTC, Tommi wrote:
>> In this situation, I think, the most convenient and sensible 
>> thing to do is to make a reference to the data, and use that 
>> reference multiple times. We could make a pointer, but then 
>> we'd be stuck with the nasty syntax of dereferencing:
>
> This works currently:
>
> struct Test
> {
>     void foo() const
>     {
>         writeln("FOO");
>     }
> }
>
> void main()
> {
>     immutable(Test)* ptr = new immutable(Test);
>     ptr.foo();
> }

Now, that's a surprise for someone coming from C++. But even 
though ptr looks like a reference variable in your example, it 
doesn't look like it at all in this example:

void main()
{
    int counter = 0;

    auto notQuiteRefCounter = &counter;

    // Increments the pointer, not counter value
    ++notQuiteRefCounter;

    // Can't do this
//  int counterBackup = notQuiteRefCounter;

    // Prints deref: 0   no-deref: 18FD34
    writefln("deref: %s  no-deref: %s",
             *notQuiteRefCounter,
              notQuiteRefCounter);
}
August 29, 2012
Re: Why can't we make reference variables?
On Wednesday, August 29, 2012 02:21:28 Tommi wrote:
> Foreach loops can make reference variables, and function calls
> can do it for the parameters passed in. So, my question is,
> wouldn't it be better if we could, in general, make reference
> variables?

Not going to happen. Unfortunately though, I don't remember all of Walter's 
reasons for it, so I can't really say why (partly due to complications it 
causes in the language, I think, but I don't know). Use a pointer, 
std.typecons.RefCounted, a class, or make your struct a reference type (which 
would probably mean having the data held in a separate struct with a pointer 
to it in the outer struct). It's really not hard to have a type which is a 
reference type if that's what you really want. You just can't declare a ref to 
a variable as a local variable.

And really, the only two differences between using a pointer and being able to 
directly declare a reference like you can in C++ is the fact that a pointer 
can be null and that operations which don't use . require that you dereference 
the pointer first (e.g. ==). So, while there may be cases where being able to 
do something like

ref var = otherVar;

would be nice, it really doesn't buy you all that much.

- Jonathan M Davis
August 29, 2012
Re: Why can't we make reference variables?
Not exactly the same thing (what you propose would have different
IFTI behaviour), but works quite well:

import std.stdio;

struct Ref(T){
    private T* _payload;
    this(ref T i){_payload = &i; }
    @property ref T deref(){ return *_payload; }
    alias deref this;
}
auto ref_(T)(ref T arg){return Ref!T(arg);}

void main(){
    int i,j;
    auto r = i.ref_;
    r++;
    auto q = r;
    writeln(r," ",q);
    q++;
    writeln(r," ",q);
    q = j.ref_;
    q++;
    writeln(r," ",q.deref);
}
August 29, 2012
Re: Why can't we make reference variables?
On Wednesday, 29 August 2012 at 01:28:49 UTC, Jonathan M Davis 
wrote:
> Not going to happen. Unfortunately though, I don't remember all 
> of Walter's reasons for it, so I can't really say why (partly
> due to complications it causes in the language, I think, but I
> don't know).

I'd really like to hear about those complications (unless they're 
too complicated for me to understand), because for someone like 
me, not knowing the implementation details of the language, it 
looks like the language already *has* implemented reference 
variables. We just can't create them, apart from these few 
distinct ways:

foreach (ref actualRefVariable, array)
{
    ++actualRefVariable; // <-- that's a reference variable 
alright
}

void fun(ref int actualRefVariable)
{
    ++actualRefVariable; // <-- that's a reference variable 
alright
}
August 29, 2012
Re: Why can't we make reference variables?
On Wednesday, 29 August 2012 at 01:42:36 UTC, Timon Gehr wrote:
> Not exactly the same thing (what you propose would have 
> different
> IFTI behaviour), but works quite well:
>
> import std.stdio;
>
> struct Ref(T){
>     private T* _payload;
>     this(ref T i){_payload = &i; }
>     @property ref T deref(){ return *_payload; }
>     alias deref this;
> }
> auto ref_(T)(ref T arg){return Ref!T(arg);}
>
> void main(){
>     int i,j;
>     auto r = i.ref_;
>     r++;
>     auto q = r;
>     writeln(r," ",q);
>     q++;
>     writeln(r," ",q);
>     q = j.ref_;
>     q++;
>     writeln(r," ",q.deref);
> }

I did figure that that's possible. But, to me, having reference 
variables be implemented in a library instead of them being a 
core language feature, is like having pointers implemented as a 
library. I'd like to have a good answer when some newcomer asks 
me: "why, oh why is this so?".
August 29, 2012
Re: Why can't we make reference variables?
On Wed, 29 Aug 2012 03:16:20 +0200
"Tommi" <tommitissari@hotmail.com> wrote:

> On Wednesday, 29 August 2012 at 00:34:02 UTC, cal wrote:
> > On Wednesday, 29 August 2012 at 00:21:29 UTC, Tommi wrote:
> >> In this situation, I think, the most convenient and sensible 
> >> thing to do is to make a reference to the data, and use that 
> >> reference multiple times. We could make a pointer, but then 
> >> we'd be stuck with the nasty syntax of dereferencing:
> >
> > This works currently:
> >
> > struct Test
> > {
> >     void foo() const
> >     {
> >         writeln("FOO");
> >     }
> > }
> >
> > void main()
> > {
> >     immutable(Test)* ptr = new immutable(Test);
> >     ptr.foo();
> > }
> 
> Now, that's a surprise for someone coming from C++. But even 
> though ptr looks like a reference variable in your example, it 
> doesn't look like it at all in this example:
> 

I've been primarily a D guy for years, and even I'm surprised by that!
O_O
August 29, 2012
Re: Why can't we make reference variables?
On Wed, 29 Aug 2012 03:44:38 +0200
"Tommi" <tommitissari@hotmail.com> wrote:

> On Wednesday, 29 August 2012 at 01:28:49 UTC, Jonathan M Davis 
> wrote:
> > Not going to happen. Unfortunately though, I don't remember all 
> > of Walter's reasons for it, so I can't really say why (partly
> > due to complications it causes in the language, I think, but I
> > don't know).
> 
> I'd really like to hear about those complications (unless they're 
> too complicated for me to understand), 

I don't remember exactly either, but IIRC, it would somehow make it
impossible to guarantee...something about references not escaping
their proper scope...
August 29, 2012
Re: Why can't we make reference variables?
I think there's an (undocumented?) Ref class in some file 
(object_.d?)
« First   ‹ Prev
1 2 3 4 5
Top | Discussion index | About this forum | D home