August 29 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 Re: Why can't we make reference variables? | |
|---|---|
Posted in reply to Tommi | 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 Re: Why can't we make reference variables? | |
|---|---|
Posted in reply to cal | 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 Re: Why can't we make reference variables? | |
|---|---|
Posted in reply to Tommi | 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 Re: Why can't we make reference variables? | |
|---|---|
Posted in reply to Tommi | 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 Re: Why can't we make reference variables? | |
|---|---|
Posted in reply to Jonathan M Davis | 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 Re: Why can't we make reference variables? | |
|---|---|
Posted in reply to Timon Gehr | 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 Re: Why can't we make reference variables? | |
|---|---|
Posted in reply to Tommi | 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 Re: Why can't we make reference variables? | |
|---|---|
Posted in reply to Tommi | 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 Re: Why can't we make reference variables? | |
|---|---|
Posted in reply to Timon Gehr | I think there's an (undocumented?) Ref class in some file (object_.d?) |
« First ‹ Prev |
|---|

Reply