www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - In, inout, out, and damn lies....

reply S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
This recent thread about unsafe, and some of my own coding has recently 
pointed out a feature D lacks:

In by reference

Let me start by first posing a question:

What is the implementation difference between inout and out?  Both are 
by reference, and it is true that the out keyword on in the parameter 
does not preclude you from accessing the variables contents.   So what 
does it mean?  It tells the person calling your function that you have 
no plans to use the value given in an "out" parameter.  So what?  Well 
what about the 'in' keyword?  It is implemented differently from out or 
inout, that is, it is passed by value.  So where is the option to 
specify that I want an "in" parameter by reference without using 
pointers?   It would be nice to not have to lie:

struct Foo {
	char[100000] bigArray;
}

int ProcessFoos( inout Foo bar )
{
	int hash = hash.max;
	foreach( char c; bar.bigArray ) {
		hash =  (hash << 1) ^ c;
	}
	return hash;
}

Cleary, inout is a lie here as I do not modify Foo at all.  It would be 
nice to be able to say "I want a reference, but i'm not going to modify 
the value it points to!"  The alternative right now is to just say "in" 
and copy 100000 bytes of memory for no good reason.

-S.
Feb 14 2006
next sibling parent "Chris Miller" <chris dprogramming.com> writes:
On Tue, 14 Feb 2006 08:11:42 -0500, S. Chancellor  
<dnewsgr mephit.kicks-ass.org> wrote:

 This recent thread about unsafe, and some of my own coding has recently  
 pointed out a feature D lacks:

 In by reference

 Let me start by first posing a question:

 What is the implementation difference between inout and out?  Both are  
 by reference, and it is true that the out keyword on in the parameter  
 does not preclude you from accessing the variables contents.   So what  
 does it mean?  It tells the person calling your function that you have  
 no plans to use the value given in an "out" parameter.  So what?  Well  
 what about the 'in' keyword?  It is implemented differently from out or  
 inout, that is, it is passed by value.  So where is the option to  
 specify that I want an "in" parameter by reference without using  
 pointers?   It would be nice to not have to lie:

 struct Foo {
 	char[100000] bigArray;
 }

 int ProcessFoos( inout Foo bar )
 {
 	int hash = hash.max;
 	foreach( char c; bar.bigArray ) {
 		hash =  (hash << 1) ^ c;
 	}
 	return hash;
 }

 Cleary, inout is a lie here as I do not modify Foo at all.  It would be  
 nice to be able to say "I want a reference, but i'm not going to modify  
 the value it points to!"  The alternative right now is to just say "in"  
 and copy 100000 bytes of memory for no good reason.

 -S.

Agreed; I've had to do this on several occasions.
Feb 14 2006
prev sibling next sibling parent bobef <bobef lessequal.com> writes:
S. Chancellor wrote:
 This recent thread about unsafe, and some of my own coding has recently 
 pointed out a feature D lacks:
 
 In by reference
 
 Let me start by first posing a question:
 
 What is the implementation difference between inout and out?  Both are 
 by reference, and it is true that the out keyword on in the parameter 
 does not preclude you from accessing the variables contents.   So what 
 does it mean?  It tells the person calling your function that you have 
 no plans to use the value given in an "out" parameter.  So what?  Well 
 what about the 'in' keyword?  It is implemented differently from out or 
 inout, that is, it is passed by value.  So where is the option to 
 specify that I want an "in" parameter by reference without using 
 pointers?   It would be nice to not have to lie:
 
 struct Foo {
     char[100000] bigArray;
 }
 
 int ProcessFoos( inout Foo bar )
 {
     int hash = hash.max;
     foreach( char c; bar.bigArray ) {
         hash =  (hash << 1) ^ c;
     }
     return hash;
 }
 
 Cleary, inout is a lie here as I do not modify Foo at all.  It would be 
 nice to be able to say "I want a reference, but i'm not going to modify 
 the value it points to!"  The alternative right now is to just say "in" 
 and copy 100000 bytes of memory for no good reason.
 
 -S.
 

Support. This is very annoying.
Feb 14 2006
prev sibling next sibling parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
S. Chancellor wrote:
 This recent thread about unsafe, and some of my own coding has recently 
 pointed out a feature D lacks:
 
 In by reference

Agree completely, but i would also like to add return by reference.
 
 Cleary, inout is a lie here as I do not modify Foo at all.  It would be 
 nice to be able to say "I want a reference, but i'm not going to modify 
 the value it points to!"  The alternative right now is to just say "in" 
 and copy 100000 bytes of memory for no good reason.

But I am afraid that I remember that Walters answer to this was something like: "a good optimizer will optimize this code so the struct wouln't actually be copyied". I have a feeling i read on this NG that DMD allready does this decision based on struct size but I might be wrong?
Feb 14 2006
parent reply S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-14 11:11:53 -0800, Ivan Senji 
<ivan.senji_REMOVE_ _THIS__gmail.com> said:

 S. Chancellor wrote:
 This recent thread about unsafe, and some of my own coding has recently 
 pointed out a feature D lacks:
 
 In by reference

Agree completely, but i would also like to add return by reference.
 
 Cleary, inout is a lie here as I do not modify Foo at all.  It would be 
 nice to be able to say "I want a reference, but i'm not going to modify 
 the value it points to!"  The alternative right now is to just say "in" 
 and copy 100000 bytes of memory for no good reason.

But I am afraid that I remember that Walters answer to this was something like: "a good optimizer will optimize this code so the struct wouln't actually be copyied". I have a feeling i read on this NG that DMD allready does this decision based on struct size but I might be wrong?

Since this is undefined behavior, it could cause binary compatibility problems between compilers. I think this needs more discussion to prevent binary compatibility problems. Or have we given up on that? -S.
Feb 14 2006
next sibling parent reply Sean Kelly <sean f4.ca> writes:
S. Chancellor wrote:
 On 2006-02-14 11:11:53 -0800, Ivan Senji 
 <ivan.senji_REMOVE_ _THIS__gmail.com> said:
 
 S. Chancellor wrote:
 This recent thread about unsafe, and some of my own coding has 
 recently pointed out a feature D lacks:

 In by reference

Agree completely, but i would also like to add return by reference.
 Cleary, inout is a lie here as I do not modify Foo at all.  It would 
 be nice to be able to say "I want a reference, but i'm not going to 
 modify the value it points to!"  The alternative right now is to just 
 say "in" and copy 100000 bytes of memory for no good reason.

But I am afraid that I remember that Walters answer to this was something like: "a good optimizer will optimize this code so the struct wouln't actually be copyied". I have a feeling i read on this NG that DMD allready does this decision based on struct size but I might be wrong?

Since this is undefined behavior, it could cause binary compatibility problems between compilers. I think this needs more discussion to prevent binary compatibility problems. Or have we given up on that?

Since this is done during an optimization pass, I assume it only applies to code that can be inlined. Sean
Feb 14 2006
parent S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-14 13:05:31 -0800, Sean Kelly <sean f4.ca> said:

 Since this is done during an optimization pass, I assume it only 
 applies to code that can be inlined.
 
 
 Sean

Wouldn't that make it almost useless?
Feb 14 2006
prev sibling parent Derek Parnell <derek psych.ward> writes:
On Tue, 14 Feb 2006 12:52:47 -0800, S. Chancellor wrote:

 On 2006-02-14 11:11:53 -0800, Ivan Senji 
 <ivan.senji_REMOVE_ _THIS__gmail.com> said:
 
 S. Chancellor wrote:
 This recent thread about unsafe, and some of my own coding has recently 
 pointed out a feature D lacks:
 
 In by reference

Agree completely, but i would also like to add return by reference.
 
 Cleary, inout is a lie here as I do not modify Foo at all.  It would be 
 nice to be able to say "I want a reference, but i'm not going to modify 
 the value it points to!"  The alternative right now is to just say "in" 
 and copy 100000 bytes of memory for no good reason.

But I am afraid that I remember that Walters answer to this was something like: "a good optimizer will optimize this code so the struct wouln't actually be copyied". I have a feeling i read on this NG that DMD allready does this decision based on struct size but I might be wrong?

Since this is undefined behavior, it could cause binary compatibility problems between compilers. I think this needs more discussion to prevent binary compatibility problems. Or have we given up on that? -S.

I agree with your concerns S., both the need for this functionality and the 'optimisation' problem. If I distribute a compiled library that does not optimise the passing large structures, and somebody tries to use that library with a compiler that does optimise this then we are going to have problems. To be able to explicitly tell the compiler to do this would seem to be a very useful idea. Of course, the current alternative is to use pointers and hope the called function behaves itself, but hopefully we are trying to move away from explicit pointers nowadays. I suppose another work around is to enclose the structure in a class, but that's starting to sound like a hack and overkill. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 15/02/2006 12:22:39 PM
Feb 14 2006
prev sibling next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor  
<dnewsgr mephit.kicks-ass.org> wrote:
 This recent thread about unsafe, and some of my own coding has recently  
 pointed out a feature D lacks:

 In by reference

 Let me start by first posing a question:

 What is the implementation difference between inout and out?  Both are  
 by reference, and it is true that the out keyword on in the parameter  
 does not preclude you from accessing the variables contents.   So what  
 does it mean?  It tells the person calling your function that you have  
 no plans to use the value given in an "out" parameter.  So what?  Well  
 what about the 'in' keyword?  It is implemented differently from out or  
 inout, that is, it is passed by value.  So where is the option to  
 specify that I want an "in" parameter by reference without using  
 pointers?   It would be nice to not have to lie:

 struct Foo {
 	char[100000] bigArray;
 }

 int ProcessFoos( inout Foo bar )
 {
 	int hash = hash.max;
 	foreach( char c; bar.bigArray ) {
 		hash =  (hash << 1) ^ c;
 	}
 	return hash;
 }

 Cleary, inout is a lie here as I do not modify Foo at all.  It would be  
 nice to be able to say "I want a reference, but i'm not going to modify  
 the value it points to!"  The alternative right now is to just say "in"  
 and copy 100000 bytes of memory for no good reason.

So, what is wrong with using a pointer in this case? i.e. int ProcessFoos( Foo* bar ) ? Regan
Feb 14 2006
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath <regan netwin.co.nz> wrote:
 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor  
 <dnewsgr mephit.kicks-ass.org> wrote:
 This recent thread about unsafe, and some of my own coding has recently  
 pointed out a feature D lacks:

 In by reference

 Let me start by first posing a question:

 What is the implementation difference between inout and out?  Both are  
 by reference, and it is true that the out keyword on in the parameter  
 does not preclude you from accessing the variables contents.   So what  
 does it mean?  It tells the person calling your function that you have  
 no plans to use the value given in an "out" parameter.  So what?  Well  
 what about the 'in' keyword?  It is implemented differently from out or  
 inout, that is, it is passed by value.  So where is the option to  
 specify that I want an "in" parameter by reference without using  
 pointers?   It would be nice to not have to lie:

 struct Foo {
 	char[100000] bigArray;
 }

 int ProcessFoos( inout Foo bar )
 {
 	int hash = hash.max;
 	foreach( char c; bar.bigArray ) {
 		hash =  (hash << 1) ^ c;
 	}
 	return hash;
 }

 Cleary, inout is a lie here as I do not modify Foo at all.  It would be  
 nice to be able to say "I want a reference, but i'm not going to modify  
 the value it points to!"  The alternative right now is to just say "in"  
 and copy 100000 bytes of memory for no good reason.

So, what is wrong with using a pointer in this case? i.e. int ProcessFoos( Foo* bar )

To be clear, I realise you said "without pointers" above, I want to know why you do not want to use a pointer. Regan
Feb 14 2006
parent reply S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-14 18:41:02 -0800, "Regan Heath" <regan netwin.co.nz> said:

 On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath <regan netwin.co.nz> wrote:
 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor  
 <dnewsgr mephit.kicks-ass.org> wrote:
 This recent thread about unsafe, and some of my own coding has recently 
  pointed out a feature D lacks:
 
 In by reference
 
 Let me start by first posing a question:
 
 What is the implementation difference between inout and out?  Both are  
 by reference, and it is true that the out keyword on in the parameter  
 does not preclude you from accessing the variables contents.   So what  
 does it mean?  It tells the person calling your function that you have  
 no plans to use the value given in an "out" parameter.  So what?  Well  
 what about the 'in' keyword?  It is implemented differently from out or 
  inout, that is, it is passed by value.  So where is the option to  
 specify that I want an "in" parameter by reference without using  
 pointers?   It would be nice to not have to lie:
 
 struct Foo {
 	char[100000] bigArray;
 }
 
 int ProcessFoos( inout Foo bar )
 {
 	int hash = hash.max;
 	foreach( char c; bar.bigArray ) {
 		hash =  (hash << 1) ^ c;
 	}
 	return hash;
 }
 
 Cleary, inout is a lie here as I do not modify Foo at all.  It would be 
  nice to be able to say "I want a reference, but i'm not going to 
 modify  the value it points to!"  The alternative right now is to just 
 say "in"  and copy 100000 bytes of memory for no good reason.

So, what is wrong with using a pointer in this case? i.e. int ProcessFoos( Foo* bar )

To be clear, I realise you said "without pointers" above, I want to know why you do not want to use a pointer. Regan

Pointers are just as vague as misusing inout. You're basically saying "I'm going to take this by reference and you don't have a clue what I'm going to do with it! Hahahaha!" -S.
Feb 14 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Tue, 14 Feb 2006 19:09:58 -0800, S. Chancellor  
<dnewsgr mephit.kicks-ass.org> wrote:
 On 2006-02-14 18:41:02 -0800, "Regan Heath" <regan netwin.co.nz> said:

 On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:
 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor   
 <dnewsgr mephit.kicks-ass.org> wrote:
 This recent thread about unsafe, and some of my own coding has  
 recently  pointed out a feature D lacks:
  In by reference
  Let me start by first posing a question:
  What is the implementation difference between inout and out?  Both  
 are  by reference, and it is true that the out keyword on in the  
 parameter  does not preclude you from accessing the variables  
 contents.   So what  does it mean?  It tells the person calling your  
 function that you have  no plans to use the value given in an "out"  
 parameter.  So what?  Well  what about the 'in' keyword?  It is  
 implemented differently from out or  inout, that is, it is passed by  
 value.  So where is the option to  specify that I want an "in"  
 parameter by reference without using  pointers?   It would be nice to  
 not have to lie:
  struct Foo {
 	char[100000] bigArray;
 }
  int ProcessFoos( inout Foo bar )
 {
 	int hash = hash.max;
 	foreach( char c; bar.bigArray ) {
 		hash =  (hash << 1) ^ c;
 	}
 	return hash;
 }
  Cleary, inout is a lie here as I do not modify Foo at all.  It would  
 be  nice to be able to say "I want a reference, but i'm not going to  
 modify  the value it points to!"  The alternative right now is to  
 just say "in"  and copy 100000 bytes of memory for no good reason.

int ProcessFoos( Foo* bar )

know why you do not want to use a pointer. Regan

Pointers are just as vague as misusing inout. You're basically saying "I'm going to take this by reference and you don't have a clue what I'm going to do with it! Hahahaha!"

So, your reason for avoiding them is as Derek said? You want to express that the function promises not to modify the data inside the object passed, right? Regan
Feb 14 2006
parent S. <S._member pathlink.com> writes:
In article <ops4zveocz23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Tue, 14 Feb 2006 19:09:58 -0800, S. Chancellor  
<dnewsgr mephit.kicks-ass.org> wrote:
 On 2006-02-14 18:41:02 -0800, "Regan Heath" <regan netwin.co.nz> said:

 On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:
 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor   
 <dnewsgr mephit.kicks-ass.org> wrote:
 This recent thread about unsafe, and some of my own coding has  
 recently  pointed out a feature D lacks:
  In by reference
  Let me start by first posing a question:
  What is the implementation difference between inout and out?  Both  
 are  by reference, and it is true that the out keyword on in the  
 parameter  does not preclude you from accessing the variables  
 contents.   So what  does it mean?  It tells the person calling your  
 function that you have  no plans to use the value given in an "out"  
 parameter.  So what?  Well  what about the 'in' keyword?  It is  
 implemented differently from out or  inout, that is, it is passed by  
 value.  So where is the option to  specify that I want an "in"  
 parameter by reference without using  pointers?   It would be nice to  
 not have to lie:
  struct Foo {
 	char[100000] bigArray;
 }
  int ProcessFoos( inout Foo bar )
 {
 	int hash = hash.max;
 	foreach( char c; bar.bigArray ) {
 		hash =  (hash << 1) ^ c;
 	}
 	return hash;
 }
  Cleary, inout is a lie here as I do not modify Foo at all.  It would  
 be  nice to be able to say "I want a reference, but i'm not going to  
 modify  the value it points to!"  The alternative right now is to  
 just say "in"  and copy 100000 bytes of memory for no good reason.

int ProcessFoos( Foo* bar )

know why you do not want to use a pointer. Regan

Pointers are just as vague as misusing inout. You're basically saying "I'm going to take this by reference and you don't have a clue what I'm going to do with it! Hahahaha!"

So, your reason for avoiding them is as Derek said? You want to express that the function promises not to modify the data inside the object passed, right? Regan

Yes, that's what I thought I was saying in my original post. -S.
Feb 14 2006
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath wrote:

 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor  

 Cleary, inout is a lie here as I do not modify Foo at all.  It would be  
 nice to be able to say "I want a reference, but i'm not going to modify  
 the value it points to!"  The alternative right now is to just say "in"  
 and copy 100000 bytes of memory for no good reason.

So, what is wrong with using a pointer in this case? i.e. int ProcessFoos( Foo* bar ) ?

You have to trust the called function to NOT change the array. If we could say ... int ProcessFoos( inref Foo bar ) which means that the compiler will pass a pointer *and* protect the contents of the array, maybe by doing a copy if the function is silly enough to explicitly modify it. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 15/02/2006 1:40:30 PM
Feb 14 2006
next sibling parent reply Tom <Tom_member pathlink.com> writes:
In article <kfg0ycw7i51c.1t4brpu7xgj6c.dlg 40tude.net>, Derek Parnell says...
On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath wrote:

 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor  

 Cleary, inout is a lie here as I do not modify Foo at all.  It would be  
 nice to be able to say "I want a reference, but i'm not going to modify  
 the value it points to!"  The alternative right now is to just say "in"  
 and copy 100000 bytes of memory for no good reason.

So, what is wrong with using a pointer in this case? i.e. int ProcessFoos( Foo* bar ) ?

You have to trust the called function to NOT change the array. If we could say ... int ProcessFoos( inref Foo bar ) which means that the compiler will pass a pointer *and* protect the contents of the array, maybe by doing a copy if the function is silly enough to explicitly modify it.

Am I right that this would be the equivalent as in C++ would be: int ProcessFoos( const Foo &bar ) ? If this was the case, the compiler wouldn't allow modification of any member of the struct, so no copy would be necessary. If i'm wrong (or totally confused) please correct me, it's late and it has been a long day. Tom;
Feb 14 2006
parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 15 Feb 2006 03:05:50 +0000 (UTC), Tom wrote:

 In article <kfg0ycw7i51c.1t4brpu7xgj6c.dlg 40tude.net>, Derek Parnell says...
On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath wrote:

 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor  

 Cleary, inout is a lie here as I do not modify Foo at all.  It would be  
 nice to be able to say "I want a reference, but i'm not going to modify  
 the value it points to!"  The alternative right now is to just say "in"  
 and copy 100000 bytes of memory for no good reason.

So, what is wrong with using a pointer in this case? i.e. int ProcessFoos( Foo* bar ) ?

You have to trust the called function to NOT change the array. If we could say ... int ProcessFoos( inref Foo bar ) which means that the compiler will pass a pointer *and* protect the contents of the array, maybe by doing a copy if the function is silly enough to explicitly modify it.

Am I right that this would be the equivalent as in C++ would be: int ProcessFoos( const Foo &bar ) ? If this was the case, the compiler wouldn't allow modification of any member of the struct, so no copy would be necessary. If i'm wrong (or totally confused) please correct me, it's late and it has been a long day.

No, I wasn't implying C++'s const functionality. I was implying that the compiler would *not* complain if the function had code to modified the passed array, instead it would silently take a copy of it and modify the copy. But this is probably too much against Walter's philosophy so I'm just wasting bandwidth again ;-) -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 15/02/2006 2:14:14 PM
Feb 14 2006
parent reply Tom <Tom_member pathlink.com> writes:
In article <1d166miote41e$.1qa28uiydunuu$.dlg 40tude.net>, Derek Parnell says...
On Wed, 15 Feb 2006 03:05:50 +0000 (UTC), Tom wrote:

 In article <kfg0ycw7i51c.1t4brpu7xgj6c.dlg 40tude.net>, Derek Parnell says...
On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath wrote:

 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor  

 Cleary, inout is a lie here as I do not modify Foo at all.  It would be  
 nice to be able to say "I want a reference, but i'm not going to modify  
 the value it points to!"  The alternative right now is to just say "in"  
 and copy 100000 bytes of memory for no good reason.

So, what is wrong with using a pointer in this case? i.e. int ProcessFoos( Foo* bar ) ?

You have to trust the called function to NOT change the array. If we could say ... int ProcessFoos( inref Foo bar ) which means that the compiler will pass a pointer *and* protect the contents of the array, maybe by doing a copy if the function is silly enough to explicitly modify it.

Am I right that this would be the equivalent as in C++ would be: int ProcessFoos( const Foo &bar ) ? If this was the case, the compiler wouldn't allow modification of any member of the struct, so no copy would be necessary. If i'm wrong (or totally confused) please correct me, it's late and it has been a long day.

No, I wasn't implying C++'s const functionality. I was implying that the compiler would *not* complain if the function had code to modified the passed array, instead it would silently take a copy of it and modify the copy. But this is probably too much against Walter's philosophy so I'm just wasting bandwidth again ;-)

I'm the king of wasted bandwidth so don't feel bad about it ;-) So, if you didn't imply const functionality what is wrong about inref beeing that (const Type &var === inref Type var)? I really don't understand what´s the benefit of making a copy silently instead of complaining about the function trying to modify the INREF parameter. Please if you don't mind to explain me further, or I'm _really_ confused here and should shut my mouth (or my hands) :-) Tom;
Feb 14 2006
parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 15 Feb 2006 03:38:21 +0000 (UTC), Tom wrote:

 In article <1d166miote41e$.1qa28uiydunuu$.dlg 40tude.net>, Derek Parnell
says...
 If this was the case, the compiler wouldn't allow modification of any member of
 the struct, so no copy would be necessary. If i'm wrong (or totally confused)
 please correct me, it's late and it has been a long day.

No, I wasn't implying C++'s const functionality. I was implying that the compiler would *not* complain if the function had code to modified the passed array, instead it would silently take a copy of it and modify the copy. But this is probably too much against Walter's philosophy so I'm just wasting bandwidth again ;-)

I'm the king of wasted bandwidth so don't feel bad about it ;-) So, if you didn't imply const functionality what is wrong about inref beeing that (const Type &var === inref Type var)? I really don't understand what´s the benefit of making a copy silently instead of complaining about the function trying to modify the INREF parameter. Please if you don't mind to explain me further, or I'm _really_ confused here and should shut my mouth (or my hands) :-)

Ok, you asked for it ;-) Its pure laziness, that's all. It's just a way of automating CoW semantics. If all the compiler did was complain then I'd have to modify my code to do something different. This is a RARE circumstance I'm addressing here and one that also smacks of lazy coding. void func( inref char[] a) { . . . a[0] = 'C'; // compiler complains! . . . } so I change it to void func( inref char[] a) { . . . char[] b = a.dup; b[0] = 'C'; // compiler is now happy . . . } but if the compiler was happy for me to be lazy it might help me out by silent doing ... void func( inref char[] a) { a = a.dup; // take a copy and replace the pointer. . . . a[0] = 'C'; // compiler is now happy . . . } So, there is not really a good argument for supporting the silent CoW idea because I may as well be explicit about it anyway, thus using current D syntax ... void func(char[] a) { a = a.dup; // take a copy and replace the pointer. . . . a[0] = 'C'; . . . } -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 15/02/2006 2:48:01 PM
Feb 14 2006
parent Tom <Tom_member pathlink.com> writes:
In article <1pbs7p4w3px1t$.18g0zn4yzirgl.dlg 40tude.net>, Derek Parnell says...
On Wed, 15 Feb 2006 03:38:21 +0000 (UTC), Tom wrote:

 In article <1d166miote41e$.1qa28uiydunuu$.dlg 40tude.net>, Derek Parnell
says...
 If this was the case, the compiler wouldn't allow modification of any member of
 the struct, so no copy would be necessary. If i'm wrong (or totally confused)
 please correct me, it's late and it has been a long day.

No, I wasn't implying C++'s const functionality. I was implying that the compiler would *not* complain if the function had code to modified the passed array, instead it would silently take a copy of it and modify the copy. But this is probably too much against Walter's philosophy so I'm just wasting bandwidth again ;-)

I'm the king of wasted bandwidth so don't feel bad about it ;-) So, if you didn't imply const functionality what is wrong about inref beeing that (const Type &var === inref Type var)? I really don't understand what´s the benefit of making a copy silently instead of complaining about the function trying to modify the INREF parameter. Please if you don't mind to explain me further, or I'm _really_ confused here and should shut my mouth (or my hands) :-)

Ok, you asked for it ;-) Its pure laziness, that's all. It's just a way of automating CoW semantics. If all the compiler did was complain then I'd have to modify my code to do something different. This is a RARE circumstance I'm addressing here and one that also smacks of lazy coding. void func( inref char[] a) { . . . a[0] = 'C'; // compiler complains! . . . } so I change it to void func( inref char[] a) { . . . char[] b = a.dup; b[0] = 'C'; // compiler is now happy . . . } but if the compiler was happy for me to be lazy it might help me out by silent doing ... void func( inref char[] a) { a = a.dup; // take a copy and replace the pointer. . . . a[0] = 'C'; // compiler is now happy . . . } So, there is not really a good argument for supporting the silent CoW idea because I may as well be explicit about it anyway, thus using current D syntax ... void func(char[] a) { a = a.dup; // take a copy and replace the pointer. . . . a[0] = 'C'; . . . }

Thanks for the detailed thing! :-D but it made me realize that I understood it from the beginning. I think this kind of laziness isn't a good tradeoff with efficiency. I mean, I personally prefer the compiler to complain than compiler making silent copies of potentially big structures. I think compiler SHOULD complain if there was an INREF functionality. C++'s "const Type &var" is an priceless thing and D should implement it someway (IMHO). Regards, Tom;
Feb 15 2006
prev sibling parent "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 15 Feb 2006 13:44:37 +1100, Derek Parnell <derek psych.ward> wrote:
 On Wed, 15 Feb 2006 15:33:45 +1300, Regan Heath wrote:

 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor

 Cleary, inout is a lie here as I do not modify Foo at all.  It would be
 nice to be able to say "I want a reference, but i'm not going to modify
 the value it points to!"  The alternative right now is to just say "in"
 and copy 100000 bytes of memory for no good reason.

So, what is wrong with using a pointer in this case? i.e. int ProcessFoos( Foo* bar ) ?

You have to trust the called function to NOT change the array.

True.
 If we could say ...

     int ProcessFoos( inref Foo bar )

 which means that the compiler will pass a pointer *and* protect the
 contents of the array, maybe by doing a copy if the function is silly
 enough to explicitly modify it.

The fundamental problem being that as far as I can see the compiler provides no way to (or cannot) protect 'data' at all, eg. import std.stdio; struct Foo { const byte[10] data; } void processFoo(Foo* f) { f.data[1] = 5; } int main() { Foo f; processFoo(&f); writefln(f.data); return 0; } I suspect the "const" above applies to the static array itself (i.e. the static array data pointer/memory address), not the data contained in the array/pointed to by the array data pointer (which is const by nature anyway). To apply it to the data itself we'd need some syntax like: const byte[10] const data; or similar. Yet, even were that to work. It doesn't provide us a way to express the contract of a function which promises not to modify the content of the thing passed to it, whether it be a class, array, pointer to struct, etc. Given the convoluted things you can do with pointers I'm not sure even a really smart compiler could provide any guarantee that it will prevent/catch the function modifying the data at compile time. Even at runtime there doesn't seem to be any way short of copying the object and comparing with the copy at the end (which defeats the point of passing it by reference). Placing the object in read only memory works, but, it only works for: const byte[10] const data; or another _copy_ of a function parameter. It doesn't work for: byte[10] data; passed to a function which promises not to modify the content of the array (because "data" is not in read only memory.. yet) Is there any way to ask the hardware to 'lock' a section of memory, such that writes fail and signal an error? Could D provide this with software perhaps? What would that cost in terms of performance? Would it be enough to lock the contents of the object passed By contents I mean the thing that is referred to by the pointer/reference not the reference itself), or would it have to lock the contents of every reference in every reference ... in every object passed? (these questions are the same or similar to those Walter posted around here somewhere) The method I'd use at the moment is to use a pointer, and assume the function will use "Copy On Write" when it modifies something. Regan
Feb 14 2006
prev sibling next sibling parent Tom <Tom_member pathlink.com> writes:
In article <dssku5$1ifs$1 digitaldaemon.com>, S. Chancellor says...
This recent thread about unsafe, and some of my own coding has recently 
pointed out a feature D lacks:

In by reference

Let me start by first posing a question:

What is the implementation difference between inout and out?  Both are 
by reference, and it is true that the out keyword on in the parameter 
does not preclude you from accessing the variables contents.   So what 
does it mean?  It tells the person calling your function that you have 
no plans to use the value given in an "out" parameter.  So what?  Well 
what about the 'in' keyword?  It is implemented differently from out or 
inout, that is, it is passed by value.  So where is the option to 
specify that I want an "in" parameter by reference without using 
pointers?   It would be nice to not have to lie:

struct Foo {
	char[100000] bigArray;
}

int ProcessFoos( inout Foo bar )
{
	int hash = hash.max;
	foreach( char c; bar.bigArray ) {
		hash =  (hash << 1) ^ c;
	}
	return hash;
}

Cleary, inout is a lie here as I do not modify Foo at all.  It would be 
nice to be able to say "I want a reference, but i'm not going to modify 
the value it points to!"  The alternative right now is to just say "in" 
and copy 100000 bytes of memory for no good reason.

-S.

Wow, I didn't know about that. Seems to be a critical one! It's without question a serious issue to take care of if we expect D to be competitive. It should be possible to do IN BY REFERENCE parameters. Tom;
Feb 14 2006
prev sibling next sibling parent reply David Medlock <noone nowhere.com> writes:
S. Chancellor wrote:

 This recent thread about unsafe, and some of my own coding has recently 
 pointed out a feature D lacks:
 
 In by reference
 
 Let me start by first posing a question:
 
 What is the implementation difference between inout and out?  Both are 
 by reference, and it is true that the out keyword on in the parameter 
 does not preclude you from accessing the variables contents.   So what 
 does it mean?  It tells the person calling your function that you have 
 no plans to use the value given in an "out" parameter.  So what?  Well 
 what about the 'in' keyword?  It is implemented differently from out or 
 inout, that is, it is passed by value.  So where is the option to 
 specify that I want an "in" parameter by reference without using 
 pointers?   It would be nice to not have to lie:

inout is a C++ reference. out ensures the value will be initialized if it is untouched, it would also probably allow some compiler optimizations in certain cases.
 
 struct Foo {
     char[100000] bigArray;
 }
 
 int ProcessFoos( inout Foo bar )
 {
     int hash = hash.max;
     foreach( char c; bar.bigArray ) {
         hash =  (hash << 1) ^ c;
     }
     return hash;
 }
 
 Cleary, inout is a lie here as I do not modify Foo at all.  It would be 
 nice to be able to say "I want a reference, but i'm not going to modify 
 the value it points to!"  The alternative right now is to just say "in" 
 and copy 100000 bytes of memory for no good reason.
 
 -S.

This type of ability might be somewhat useful for library authors, but outside that it sounds as if you wish to handle a specific class of errors by changing the whole language. If you are simply writing programs and not a library, asking the compiler to guess your intent is not really feasible. The in/out/inout bestows *capabilities* not *constraints*. Even so, why not just use a class and perhaps an Immutable wrapper? Structs are useful for specific things, but shared data is not one of them, thats what classes are for. class CFoo { Foo foo; int opApply( int delegate( inout char c ) dg ) { <process foo.bigArray> } } -DavidM
Feb 15 2006
parent reply S. <S._member pathlink.com> writes:
In article <dsva39$139m$1 digitaldaemon.com>, David Medlock says...
S. Chancellor wrote:

 This recent thread about unsafe, and some of my own coding has recently 
 pointed out a feature D lacks:
 
 In by reference
 
 Let me start by first posing a question:
 
 What is the implementation difference between inout and out?  Both are 
 by reference, and it is true that the out keyword on in the parameter 
 does not preclude you from accessing the variables contents.   So what 
 does it mean?  It tells the person calling your function that you have 
 no plans to use the value given in an "out" parameter.  So what?  Well 
 what about the 'in' keyword?  It is implemented differently from out or 
 inout, that is, it is passed by value.  So where is the option to 
 specify that I want an "in" parameter by reference without using 
 pointers?   It would be nice to not have to lie:

inout is a C++ reference. out ensures the value will be initialized if it is untouched, it would also probably allow some compiler optimizations in certain cases.
 
 struct Foo {
     char[100000] bigArray;
 }
 
 int ProcessFoos( inout Foo bar )
 {
     int hash = hash.max;
     foreach( char c; bar.bigArray ) {
         hash =  (hash << 1) ^ c;
     }
     return hash;
 }
 
 Cleary, inout is a lie here as I do not modify Foo at all.  It would be 
 nice to be able to say "I want a reference, but i'm not going to modify 
 the value it points to!"  The alternative right now is to just say "in" 
 and copy 100000 bytes of memory for no good reason.
 
 -S.

This type of ability might be somewhat useful for library authors, but outside that it sounds as if you wish to handle a specific class of errors by changing the whole language.

Who said ANYTHING changing the entire language? The functionality I require is already IN the language as pointers or as inout. The point is that there is inconsitency in this case.
If you are simply writing programs and not a library, asking the 
compiler to guess your intent is not really feasible.  The in/out/inout 
bestows *capabilities* not *constraints*.

The point of the in/inout/out keywords has NOTHING to do with anything other than information. You are incorrect that they bestow features OR constraints. They are neither! They are a means for function writers to give INFORMATION about what their function does to the compiler, and to consumers of their function. It just so happens that OUT by value or INOUT by value make NO SENSE, so those keywords bestow reference passing on the parameter! Currently there is no way to get reference passing parameters aside from pointers, or one of those informational keywords. Having to use pointers, or incorrently stating what your function does with the parameter, are unacceptable ways to obtain a reference.
Even so, why not just use a class and perhaps an Immutable wrapper?
Structs are useful for specific things, but shared data is not one of 
them, thats what classes are for.
class CFoo
{
    Foo foo;
    int opApply( int delegate( inout char c ) dg ) {
	<process foo.bigArray>
    }	
}

Structs (AKA structures) and Classes are two fundementally different things which are supposed to be for completely different purposes. That is storing structured data vs grouping functions, which work on the same data, together. You seem to be saying that the only difference between structures is solely the fact that one has reference semantics while the other does not. I would fully disagree with that assertion. -S.
Feb 15 2006
parent reply David Medlock <noone nowhere.com> writes:
S. wrote:
 In article <dsva39$139m$1 digitaldaemon.com>, David Medlock says...
 
S. Chancellor wrote:


This recent thread about unsafe, and some of my own coding has recently 
pointed out a feature D lacks:

In by reference

Let me start by first posing a question:

What is the implementation difference between inout and out?  Both are 
by reference, and it is true that the out keyword on in the parameter 
does not preclude you from accessing the variables contents.   So what 
does it mean?  It tells the person calling your function that you have 
no plans to use the value given in an "out" parameter.  So what?  Well 
what about the 'in' keyword?  It is implemented differently from out or 
inout, that is, it is passed by value.  So where is the option to 
specify that I want an "in" parameter by reference without using 
pointers?   It would be nice to not have to lie:

inout is a C++ reference. out ensures the value will be initialized if it is untouched, it would also probably allow some compiler optimizations in certain cases.
struct Foo {
    char[100000] bigArray;
}

int ProcessFoos( inout Foo bar )
{
    int hash = hash.max;
    foreach( char c; bar.bigArray ) {
        hash =  (hash << 1) ^ c;
    }
    return hash;
}

Cleary, inout is a lie here as I do not modify Foo at all.  It would be 
nice to be able to say "I want a reference, but i'm not going to modify 
the value it points to!"  The alternative right now is to just say "in" 
and copy 100000 bytes of memory for no good reason.

-S.

Its not a lie, its an ability which you simply did not use. This type of ability might be somewhat useful for library authors, but outside that it sounds as if you wish to handle a specific class of errors by changing the whole language.

Who said ANYTHING changing the entire language? The functionality I require is already IN the language as pointers or as inout. The point is that there is inconsitency in this case.

Making in variables reside in unwriteable memory does change the language, not the syntax but the semantics. If you can't see that I cannot discuss it further with you.
 
If you are simply writing programs and not a library, asking the 
compiler to guess your intent is not really feasible.  The in/out/inout 
bestows *capabilities* not *constraints*.

The point of the in/inout/out keywords has NOTHING to do with anything other than information. You are incorrect that they bestow features OR constraints. They are neither!

If they provide no new capabilites, you must intend that they are the same? Again I don't think you understand what the modifiers do. They are a means for function writers to give INFORMATION
 about what their function does to the compiler, and to consumers of their
 function.  It just so happens that OUT by value or INOUT by value make NO
SENSE,
 so those keywords bestow reference passing on the parameter!  Currently there
is
 no way to get reference passing parameters aside from pointers, or one of those
 informational keywords.  

Wrong again, all class instances are passed by reference as I showed in my example. Structs are passed by value. And with out/inout you can modify the reference in either case. For structs, without inout you would have to pass an in paramter to get the current value and an out parameter to change the new value. if you add const what about this: void update( const in int a, out int b ) { b = a + 5; } int x = 5; update( x, x ); Since x is obviously not in read only memory, you will still have to copy some data around. Having to use pointers, or incorrently stating what
 your function does with the parameter, are unacceptable ways to obtain a
 reference.
 
 
Even so, why not just use a class and perhaps an Immutable wrapper?
Structs are useful for specific things, but shared data is not one of 
them, thats what classes are for.
class CFoo
{
   Foo foo;
   int opApply( int delegate( inout char c ) dg ) {
	<process foo.bigArray>
   }	
}

Structs (AKA structures) and Classes are two fundementally different things which are supposed to be for completely different purposes. That is storing structured data vs grouping functions, which work on the same data, together. You seem to be saying that the only difference between structures is solely the fact that one has reference semantics while the other does not. I would fully disagree with that assertion. -S.

What I am saying is that structs are arbitrary chunks of memory passed as chunks of memory, whilst classes are references to objects passed as references to objects. You aren't objecting to a capability which isn't there you are objecting to the way to achieve it in D. I am having trouble judging your tone, but I suspect you might be worked up over this? Cheers. -DavidM
Feb 15 2006
parent reply S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-15 18:00:35 -0800, David Medlock <noone nowhere.com> said:

 S. wrote:
 In article <dsva39$139m$1 digitaldaemon.com>, David Medlock says...
 
 S. Chancellor wrote:
 
 
 This recent thread about unsafe, and some of my own coding has recently 
 pointed out a feature D lacks:
 
 In by reference
 
 Let me start by first posing a question:
 
 What is the implementation difference between inout and out?  Both are 
 by reference, and it is true that the out keyword on in the parameter 
 does not preclude you from accessing the variables contents.   So what 
 does it mean?  It tells the person calling your function that you have 
 no plans to use the value given in an "out" parameter.  So what?  Well 
 what about the 'in' keyword?  It is implemented differently from out or 
 inout, that is, it is passed by value.  So where is the option to 
 specify that I want an "in" parameter by reference without using 
 pointers?   It would be nice to not have to lie:

inout is a C++ reference. out ensures the value will be initialized if it is untouched, it would also probably allow some compiler optimizations in certain cases.
 struct Foo {
    char[100000] bigArray;
 }
 
 int ProcessFoos( inout Foo bar )
 {
    int hash = hash.max;
    foreach( char c; bar.bigArray ) {
        hash =  (hash << 1) ^ c;
    }
    return hash;
 }
 
 Cleary, inout is a lie here as I do not modify Foo at all.  It would be 
 nice to be able to say "I want a reference, but i'm not going to modify 
 the value it points to!"  The alternative right now is to just say "in" 
 and copy 100000 bytes of memory for no good reason.
 
 -S.
 

Its not a lie, its an ability which you simply did not use. This type of ability might be somewhat useful for library authors, but outside that it sounds as if you wish to handle a specific class of errors by changing the whole language.

Who said ANYTHING changing the entire language? The functionality I require is already IN the language as pointers or as inout. The point is that there is inconsitency in this case.

Making in variables reside in unwriteable memory does change the language, not the syntax but the semantics. If you can't see that I cannot discuss it further with you.

You seem to be confusing this thread with the const thread. Go re-read my original message. This has nothing to do with "readonlyness". Nowhere did I recommend the compiler _DO_ anything but provide a "inref" keyword which allowed you to declare what you were doing, and that you wanted to do it to a reference. (If walter wants to implement some kind of warning when you write to it, that's fine by me.) I did nowhere call for any compiler checking of this feature.As you will also note, the compiler does not currently prevent you from using the value of an "out" parameter before you assign anything to it either. (Although it seems the current version of DMD sets it to the type initializer regardless of what you do.) Also moving the variables to unwritable memory clearly would not be "by reference,...."
 
 If you are simply writing programs and not a library, asking the 
 compiler to guess your intent is not really feasible.  The in/out/inout 
 bestows *capabilities* not *constraints*.

The point of the in/inout/out keywords has NOTHING to do with anything other than information. You are incorrect that they bestow features OR constraints. They are neither!

If they provide no new capabilites, you must intend that they are the same? Again I don't think you understand what the modifiers do.

You've already demonstrated that you don't by claiming that classes are passed by reference even when an in parameter is specified. You should try it.
 They are a means for function writers to give INFORMATION
 about what their function does to the compiler, and to consumers of their
 function.  It just so happens that OUT by value or INOUT by value make 
 NO SENSE,
 so those keywords bestow reference passing on the parameter!  Currently 
 there is
 no way to get reference passing parameters aside from pointers, or one of those
 informational keywords.

Wrong again, all class instances are passed by reference as I showed in my example. Structs are passed by value. And with out/inout you can modify the reference in either case.

Yes, Mostly. That is indeed how they are implemented, and that is indeed what in and inout do.
 For structs, without inout you would have to pass an in paramter to get 
 the current value and an out parameter to change the new value.

Yes. That's because DMD does you a favor and initializes any out parameters to their type's initializer. If it skipped this step, inout and out would be identical aside from their informational purposes.
 
 if you add const what about this:
 
 void update( const in int a, out int b )
 {
    b = a + 5;
 }
 
 
 int x = 5;
 update( x, x );
 
 Since x is obviously not in read only memory, you will still have to 
 copy some data around.
 
 Having to use pointers, or incorrently stating what
 your function does with the parameter, are unacceptable ways to obtain a
 reference.
 
 
 Even so, why not just use a class and perhaps an Immutable wrapper?
 Structs are useful for specific things, but shared data is not one of 
 them, thats what classes are for.
 class CFoo
 {
   Foo foo;
   int opApply( int delegate( inout char c ) dg ) {
 	<process foo.bigArray>
   }	
 }

Structs (AKA structures) and Classes are two fundementally different things which are supposed to be for completely different purposes. That is storing structured data vs grouping functions, which work on the same data, together. You seem to be saying that the only difference between structures is solely the fact that one has reference semantics while the other does not. I would fully disagree with that assertion. -S.

What I am saying is that structs are arbitrary chunks of memory passed as chunks of memory, whilst classes are references to objects passed as references to objects. You aren't objecting to a capability which isn't there you are objecting to the way to achieve it in D.

The difference between structs and classes goes beyond reference semantics. What is well suited as a struct may not be well suited as a class. Your suggestion of using classes instead of structures to obtain my goal is not a solution to the question raised. Also, you are incorrect, if you pass a class via an "IN" parameter is is in fact dup'd prior to being passed in. Go ahead and try it. Clearly there is a REASON why in C++ there is the ability to pass _any_ type by reference or by value. This is available in C, C#, Visual Basic, etc. and also in D but using outdated syntax to accomplish it. Syntax which is not consistent with the rest of D. Do you think this is a useless feature? That seems to be what you're implying. Let me reiterate what I'm saying for you, since you are mixing up threads: 1. In always dup's the type, essentially passing by value. (It seems this is broken for arrays, but not classes.) 2. Inout passes by reference and leaves the passed value in tact. 3. Out passed by reference and destroys the current contents, essentially acting as another return value. 4. There is no current way to specify that you will NOT modify the value, but that you don't want the overhead of copying. This needs to be addressed. Once something is passed by reference the compiler cannot PREVENT you from modifying it, but that's not the point. If you WANTED to modify it you could simply say inout. We're not malicious hackers here. The purposes of these keywords are fundamentally informational, not that they actually "DO" anything in particular. It just so happens though it would be stupid to have a By value out parameter or the like, so D simplifies it and wraps some functionality into that inout modifier. 5. If the compiler wants to give an error if you try to modify an InByRef parameter, more power to it. Obviously it can't copy it into readonly memory before passing or it wouldn't be able to be by reference.
 I am having trouble judging your tone, but I suspect you might be 
 worked up over this?

"Wrong again". Cheers -S.
Feb 16 2006
parent reply David Medlock <noone nowhere.com> writes:
S. Chancellor wrote:
 On 2006-02-15 18:00:35 -0800, David Medlock <noone nowhere.com> said:
 
 S. wrote:
 Who said ANYTHING changing the entire language?  The functionality I 
 require is
 already IN the language as pointers or as inout.  The point is that 
 there is
 inconsitency in this case.

Making in variables reside in unwriteable memory does change the language, not the syntax but the semantics. If you can't see that I cannot discuss it further with you.

You seem to be confusing this thread with the const thread. Go re-read my original message. This has nothing to do with "readonlyness". Nowhere did I recommend the compiler _DO_ anything but provide a "inref" keyword which allowed you to declare what you were doing, and that you wanted to do it to a reference. (If walter wants to implement some kind of warning when you write to it, that's fine by me.) I did nowhere call for any compiler checking of this feature.As you will also note, the compiler does not currently prevent you from using the value of an "out" parameter before you assign anything to it either. (Although it seems the current version of DMD sets it to the type initializer regardless of what you do.)

Actually I am not. To do what you wish to do you need to ensure that the data isnt changed by the function you call. Unless you can be sure of that, the struct data *must* be passed by value or you *will* change the semantics of the current operators. foo test( inref B foo ) { return some_other_c_function( &foo ); } If foo was passed by reference the original is modified. If I could guarantee that foo is not modified then reference semantics would work.
 Also moving the variables to unwritable memory clearly would not be "by 
 reference,...."
 

semantics wouldnt break existing code....
 If you are simply writing programs and not a library, asking the 
 compiler to guess your intent is not really feasible.  The 
 in/out/inout bestows *capabilities* not *constraints*.

The point of the in/inout/out keywords has NOTHING to do with anything other than information. You are incorrect that they bestow features OR constraints. They are neither!

If they provide no new capabilites, you must intend that they are the same? Again I don't think you understand what the modifiers do.

You've already demonstrated that you don't by claiming that classes are passed by reference even when an in parameter is specified. You should try it.

import std.stdio; class A { int x = 1; } struct B { int x = 1; } void one( in A a ) { a.x = 5; } void two( in B b ) { b.x = 5; } void main( char[][] args ) { A foo = new A(); writefln( "%s", foo.x ); one( foo ); writefln( "%s", foo.x ); B bar; writefln( "%s", bar.x ); two( bar ); writefln( "%s", bar.x ); } prints: 1 5 1 1 This is reference versus value semantics. The class object is passed by reference, the struct is passed by value.
 The difference between structs and classes goes beyond reference 
 semantics.   What is well suited as a struct may not be well suited as a 
 class.  Your suggestion of using classes instead of structures to obtain 
 my goal is not a solution to the question raised.  Also, you are 
 incorrect, if you pass a class via an "IN" parameter is is in fact dup'd 
 prior to being passed in.  Go ahead and try it.

I did and the class reference still points to the same class object as the caller.
 Clearly there is a REASON why in C++ there is the ability to pass _any_ 
 type by reference or by value.  This is available in C, C#, Visual 
 Basic,  etc. and also in D but using outdated syntax to accomplish it.  
 Syntax which is not consistent with the rest of D.  Do you think this is 
 a useless feature?  That seems to be what you're implying.

No I don't think its a useless feature. I do think as long as we have pointers and C compatability in D it isn't really feasible.
 
 Let me reiterate what I'm saying for you, since you are mixing up threads:
 
 1.  In always dup's the type, essentially passing by value. (It seems 
 this is broken for arrays, but not classes.)

It dups the value for everything but arrays(pointers with a length) and classes.
 4.  There is no current way to specify that you will NOT modify the 
 value, but that you don't want the overhead of copying.  This needs to 
 be addressed.   

I thought we werent talking about const? Once something is passed by reference the compiler
 cannot PREVENT you from modifying it, but that's not the point.  If you 
 WANTED to modify it you could simply say inout.  We're not malicious 
 hackers here.  The purposes of these keywords are fundamentally 
 informational, not that they actually "DO" anything in particular.  

Again, they do change the passing semantics. Whether or not you realize it, you are asking for in/inref to be equivalent to C++'s const.
 I am having trouble judging your tone, but I suspect you might be 
 worked up over this?

"Wrong again". Cheers -S.

Can't imagine how I got that impression with the title of the thread... -DavidM
Feb 16 2006
parent reply S. Chancellor <S._member pathlink.com> writes:
In article <dt1uqc$dut$1 digitaldaemon.com>, David Medlock says...
import std.stdio;

class A { int x = 1; }
struct B { int x = 1; }

void one( in A a )
{
  a.x = 5;
}

void two( in B b )
{
   b.x = 5;
}

void main( char[][] args )
{
   A foo = new A();
   writefln( "%s", foo.x );
   one( foo );
   writefln( "%s", foo.x );

   B bar;
   writefln( "%s", bar.x );
   two( bar );
   writefln( "%s", bar.x );
}


prints:
1
5
1
1

This is reference versus value semantics.
The class object is passed by reference, the struct is passed by value.

Oops. In my test I got confused about what & was giving me. You are right. However, You've just proven there's absolutely nothing wrong with just giving me an inref keyword that is essentially an alias to the inout keyword. Which is what I requested. Have a nice day. -S.
Feb 16 2006
parent reply Dave <Dave_member pathlink.com> writes:
In article <dt2faq$105d$1 digitaldaemon.com>, S. Chancellor says...
In article <dt1uqc$dut$1 digitaldaemon.com>, David Medlock says...
import std.stdio;

class A { int x = 1; }
struct B { int x = 1; }

void one( in A a )
{
  a.x = 5;
}

void two( in B b )
{
   b.x = 5;
}

void main( char[][] args )
{
   A foo = new A();
   writefln( "%s", foo.x );
   one( foo );
   writefln( "%s", foo.x );

   B bar;
   writefln( "%s", bar.x );
   two( bar );
   writefln( "%s", bar.x );
}


prints:
1
5
1
1

This is reference versus value semantics.
The class object is passed by reference, the struct is passed by value.

Oops. In my test I got confused about what & was giving me. You are right. However, You've just proven there's absolutely nothing wrong with just giving me an inref keyword that is essentially an alias to the inout keyword. Which is what I requested. Have a nice day. -S.

How about one keyword: 'byref' as in 'in', 'out' and 'byref'. It's grep-able and should be pretty much universally understood by anyone except total programming newbies (who probably would have as much trouble grasping 'inout' anyway). Heck, modern BASICS's and even things like Windows script have 'ByVal' and 'ByRef' and I've never heard any complaints there - they are well understood even by developers who are not real familiar with pointer syntax or semantics. int foo(byref int x) { ... } foreach(byref double d; darr) { ... } As for keyword consistency using the words in and out -- 'in' will rarely be used anyway and for my money could be removed as a keyword, unless it inherits some special meaning w.r.t. 'constness' or something along those lines. - Dave
Feb 16 2006
parent reply S. <S._member pathlink.com> writes:
In article <dt2hth$132q$1 digitaldaemon.com>, Dave says...
In article <dt2faq$105d$1 digitaldaemon.com>, S. Chancellor says...
In article <dt1uqc$dut$1 digitaldaemon.com>, David Medlock says...
import std.stdio;

class A { int x = 1; }
struct B { int x = 1; }

void one( in A a )
{
  a.x = 5;
}

void two( in B b )
{
   b.x = 5;
}

void main( char[][] args )
{
   A foo = new A();
   writefln( "%s", foo.x );
   one( foo );
   writefln( "%s", foo.x );

   B bar;
   writefln( "%s", bar.x );
   two( bar );
   writefln( "%s", bar.x );
}


prints:
1
5
1
1

This is reference versus value semantics.
The class object is passed by reference, the struct is passed by value.

Oops. In my test I got confused about what & was giving me. You are right. However, You've just proven there's absolutely nothing wrong with just giving me an inref keyword that is essentially an alias to the inout keyword. Which is what I requested. Have a nice day. -S.

How about one keyword: 'byref' as in 'in', 'out' and 'byref'. It's grep-able and should be pretty much universally understood by anyone except total programming newbies (who probably would have as much trouble grasping 'inout' anyway). Heck, modern BASICS's and even things like Windows script have 'ByVal' and 'ByRef' and I've never heard any complaints there - they are well understood even by developers who are not real familiar with pointer syntax or semantics. int foo(byref int x) { ... } foreach(byref double d; darr) { ... } As for keyword consistency using the words in and out -- 'in' will rarely be used anyway and for my money could be removed as a keyword, unless it inherits some special meaning w.r.t. 'constness' or something along those lines.

One of the reasons there's out/inout/in keywords exist is to provide implementation details in the parameter list. But also, while we're at it, since any out keywords are obviously by reference, lets make that automatic? Whoops, we forgot we sometimes want in keywords which are references. And to answer your question, maybe eventually the different keywords will impart protections. For example, the out keyword overwrites the variable with it's initializer before allowing you to use it. -S.
Feb 16 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 16 Feb 2006 22:53:25 +0000 (UTC), S. <S._member pathlink.com>  
wrote:
 In article <dt2hth$132q$1 digitaldaemon.com>, Dave says...
 In article <dt2faq$105d$1 digitaldaemon.com>, S. Chancellor says...
 In article <dt1uqc$dut$1 digitaldaemon.com>, David Medlock says...
 import std.stdio;

 class A { int x = 1; }
 struct B { int x = 1; }

 void one( in A a )
 {
  a.x = 5;
 }

 void two( in B b )
 {
   b.x = 5;
 }

 void main( char[][] args )
 {
   A foo = new A();
   writefln( "%s", foo.x );
   one( foo );
   writefln( "%s", foo.x );

   B bar;
   writefln( "%s", bar.x );
   two( bar );
   writefln( "%s", bar.x );
 }


 prints:
 1
 5
 1
 1

 This is reference versus value semantics.
 The class object is passed by reference, the struct is passed by  
 value.

Oops. In my test I got confused about what & was giving me. You are right. However, You've just proven there's absolutely nothing wrong with just giving me an inref keyword that is essentially an alias to the inout keyword. Which is what I requested. Have a nice day. -S.

How about one keyword: 'byref' as in 'in', 'out' and 'byref'. It's grep-able and should be pretty much universally understood by anyone except total programming newbies (who probably would have as much trouble grasping 'inout' anyway). Heck, modern BASICS's and even things like Windows script have 'ByVal' and 'ByRef' and I've never heard any complaints there - they are well understood even by developers who are not real familiar with pointer syntax or semantics. int foo(byref int x) { ... } foreach(byref double d; darr) { ... } As for keyword consistency using the words in and out -- 'in' will rarely be used anyway and for my money could be removed as a keyword, unless it inherits some special meaning w.r.t. 'constness' or something along those lines.

One of the reasons there's out/inout/in keywords exist is to provide implementation details in the parameter list.

Does it say that somewhere in the D docs? Has Walter said that was his intention? I'm not saying it wasn't I'm just saying I haven't see/read that anywhere, all I can really assume is that out/inout/in are there to provide the effect they provide, and nothing more.
 But also, while we're at it,
 since any out keywords are obviously by reference, lets make that  
 automatic?
 Whoops, we forgot we sometimes want in keywords which are references.

In this case, I use a pointer.
 And to answer your question, maybe eventually the different keywords  
 will impart
 protections.  For example, the out keyword overwrites the variable with  
 it's
 initializer before allowing you to use it.

Sure, we could invent a new keyword "byref" and in the future apply the protection to it, but, who's to say the protection _ever_ gets implemented? The keyword would initially be no different to a pointer, so, it will start off as another way to do the same thing and it might just stay that way forever. It hardly seems worth it, to me. Regan
Feb 16 2006
parent reply S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-16 15:25:07 -0800, "Regan Heath" <regan netwin.co.nz> said:

 Does it say that somewhere in the D docs? Has Walter said that was his  
 intention? I'm not saying it wasn't I'm just saying I haven't see/read  
 that anywhere, all I can really assume is that out/inout/in are there 
 to  provide the effect they provide, and nothing more.
 
 But also, while we're at it,
 since any out keywords are obviously by reference, lets make that  automatic?
 Whoops, we forgot we sometimes want in keywords which are references.

In this case, I use a pointer.
 And to answer your question, maybe eventually the different keywords  
 will impart
 protections.  For example, the out keyword overwrites the variable with  it's
 initializer before allowing you to use it.

Sure, we could invent a new keyword "byref" and in the future apply the protection to it, but, who's to say the protection _ever_ gets implemented? The keyword would initially be no different to a pointer, so, it will start off as another way to do the same thing and it might just stay that way forever. It hardly seems worth it, to me.

If you don't think that was his intention, why didn't he make it a byref keyword to begin with? Why have in, inout, and out? Why even have out? It's hardly worth it to have out since it doesn't do hardly anything anyways. In fact it adds overhead by setting the parameter to it's initializer. Does having in/out/inout make coding more clear than just ByRef? If so, does using inout where you are not using the parameter as both an in and an out parameter obfuscate things? D has an ever expanding plethora of features which are useless to quite a few people. More being added by the minute, why not a simple aliased keyword? Nobody said you had to use it. -S.
Feb 16 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 16 Feb 2006 20:24:44 -0800, S. Chancellor  
<dnewsgr mephit.kicks-ass.org> wrote:
 On 2006-02-16 15:25:07 -0800, "Regan Heath" <regan netwin.co.nz> said:

 Does it say that somewhere in the D docs? Has Walter said that was his   
 intention? I'm not saying it wasn't I'm just saying I haven't see/read   
 that anywhere, all I can really assume is that out/inout/in are there  
 to  provide the effect they provide, and nothing more.

 But also, while we're at it,
 since any out keywords are obviously by reference, lets make that   
 automatic?
 Whoops, we forgot we sometimes want in keywords which are references.

 And to answer your question, maybe eventually the different keywords   
 will impart
 protections.  For example, the out keyword overwrites the variable  
 with  it's
 initializer before allowing you to use it.

the protection to it, but, who's to say the protection _ever_ gets implemented? The keyword would initially be no different to a pointer, so, it will start off as another way to do the same thing and it might just stay that way forever. It hardly seems worth it, to me.

If you don't think that was his intention, why didn't he make it a byref keyword to begin with?

Because we have pointers. :)
 Why have in, inout, and out?  Why even have out? It's hardly worth it to  
 have out since it doesn't do hardly anything anyways.  In fact it adds  
 overhead by setting the parameter to it's initializer.

The behaviour of 'out' achieves much the same thing as the auto initialising of other D variables. It makes it easier to debug when a function has forgotten to set it. I agree, it also tells the caller what to expect. I agree with your original statement WRT 'out', making the code clearer is "one of the reasons" for it. I do not believe the same argument applies to "byref". It adds nothing that a pointer does not already give us. If in the future we have some sort of data protection scheme and if that scheme requires a keyword in function declarations then "byref" just might be it.
 Does having in/out/inout make coding more clear than just ByRef?

I agree, in/out/inout make coding clearer.
 If so, does using inout where you are not using the parameter as both an  
 in and an out parameter obfuscate things?

Yes, which is why I use a pointer. A pointer passes data 'in' by reference. Yes, you can change the data it points to, but it is no different to a class or array reference passed 'in'.
 D has an ever expanding plethora of features which are useless to quite  
 a few people.  More being added by the minute, why not a simple aliased  
 keyword?

So.. your argument for a 'useless' feature is that there are plenty of other 'useless' features, why not add another one?
 Nobody said you had to use it.

This is true. Regan
Feb 16 2006
parent reply S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-16 23:46:37 -0800, "Regan Heath" <regan netwin.co.nz> said:

 If you don't think that was his intention, why didn't he make it a 
 byref  keyword to begin with?

Because we have pointers. :)

We have in, out and inout too! Why use pointers if we don't have to?
 
 Why have in, inout, and out?  Why even have out? It's hardly worth it 
 to  have out since it doesn't do hardly anything anyways.  In fact it 
 adds  overhead by setting the parameter to it's initializer.

The behaviour of 'out' achieves much the same thing as the auto initialising of other D variables. It makes it easier to debug when a function has forgotten to set it. I agree, it also tells the caller what to expect. I agree with your original statement WRT 'out', making the code clearer is "one of the reasons" for it. I do not believe the same argument applies to "byref". It adds nothing that a pointer does not already give us. If in the future we have some sort of data protection scheme and if that scheme requires a keyword in function declarations then "byref" just might be it.

I didn't ask for a ByRef keyword, I asked for a method for an in keyword to be by reference.
 Does having in/out/inout make coding more clear than just ByRef?

I agree, in/out/inout make coding clearer.

Wouldn't it be consistent then to have a sort of "inbyref" parameter? Wouldn't that be consistent with the rest of D style, rather then a pointer, which is just vague and C-esque?
 
 If so, does using inout where you are not using the parameter as both 
 an  in and an out parameter obfuscate things?

Yes, which is why I use a pointer. A pointer passes data 'in' by reference. Yes, you can change the data it points to, but it is no different to a class or array reference passed 'in'.

Pointers are a break from normal D style. One of the goals of D is to provide programmers access to things like pointers, while making it so they don't have to use them 90% of the time.
 
 D has an ever expanding plethora of features which are useless to quite 
  a few people.  More being added by the minute, why not a simple 
 aliased  keyword?

So.. your argument for a 'useless' feature is that there are plenty of other 'useless' features, why not add another one?

If that's what you want to read... I said there are plenty of features that are useful to quite a few people. This one is apparently useless to you.
Feb 17 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Fri, 17 Feb 2006 07:00:49 -0800, S. Chancellor  
<dnewsgr mephit.kicks-ass.org> wrote:
 On 2006-02-16 23:46:37 -0800, "Regan Heath" <regan netwin.co.nz> said:

 If you don't think that was his intention, why didn't he make it a  
 byref  keyword to begin with?


We have in, out and inout too! Why use pointers if we don't have to?

My point is that you _do_ have to use pointers. A pointer _is_ how you pass a struct by reference. Yes, we could add _another_ way to do that, but why? what does it add? It doesn't make the function declaration any clearer. It doesn't provide any more protection.
 Why have in, inout, and out?  Why even have out? It's hardly worth it  
 to  have out since it doesn't do hardly anything anyways.  In fact it  
 adds  overhead by setting the parameter to it's initializer.

initialising of other D variables. It makes it easier to debug when a function has forgotten to set it. I agree, it also tells the caller what to expect. I agree with your original statement WRT 'out', making the code clearer is "one of the reasons" for it. I do not believe the same argument applies to "byref". It adds nothing that a pointer does not already give us. If in the future we have some sort of data protection scheme and if that scheme requires a keyword in function declarations then "byref" just might be it.

I didn't ask for a ByRef keyword, I asked for a method for an in keyword to be by reference.

You have one, a pointer.
 Does having in/out/inout make coding more clear than just ByRef?


Wouldn't it be consistent then to have a sort of "inbyref" parameter?

No.
 Wouldn't that be consistent with the rest of D style, rather then a  
 pointer, which is just vague and C-esque?

How is a pointer vague?
 If so, does using inout where you are not using the parameter as both  
 an  in and an out parameter obfuscate things?

reference. Yes, you can change the data it points to, but it is no different to a class or array reference passed 'in'.

Pointers are a break from normal D style. One of the goals of D is to provide programmers access to things like pointers, while making it so they don't have to use them 90% of the time.

Which is exactly what you have. You only need a pointer when you're passing a structure by reference, which, is probably around 10% of the time depending on the sort of stuff you're doing.
 D has an ever expanding plethora of features which are useless to  
 quite  a few people.  More being added by the minute, why not a simple  
 aliased  keyword?

of other 'useless' features, why not add another one?

If that's what you want to read...

I was asking for clarification by stating the argument as I read it.
 I said there are plenty of features that are useful to quite a few  
 people.

No you didn't, you said the opposite:
 D has an ever expanding plethora of features which are useless to  
 quite  a few people.



Then you went on to say:
 More being added by the minute, why not a simple aliased  keyword?



which suggested to me that you were saying "one more useless feature can't hurt" or similar. If that was not your intention, sorry, that is how I read it.
 This one is apparently useless to you.

My position is that it's totally useless, it adds nothing a pointer does not already give us. Regan
Feb 17 2006
parent reply S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-17 19:49:59 -0800, "Regan Heath" <regan netwin.co.nz> said:

 If that's what you want to read...

I was asking for clarification by stating the argument as I read it.

No, you stated my argument in and altered form. I stated: "D has an ever expanding plethora of features which are useless to quite a few people. " Note the choosing of the phrase: "Quite a few people." Note that I did not say "All People." My argument is that while complex features which I will never use, such as complex types, are in D, while some sort of "inref" which is much simpler to add is not.
 
 I said there are plenty of features that are useful to quite a few  people.

No you didn't, you said the opposite:
 D has an ever expanding plethora of features which are useless to  
 quite  a few people.




That was supposed to read: I said there are plenty of features that are NOT useful to quite a few people.
 
 Then you went on to say:
 More being added by the minute, why not a simple aliased  keyword?



which suggested to me that you were saying "one more useless feature can't hurt" or similar. If that was not your intention, sorry, that is how I read it.

See above to what I said. You implied something other than what I said by rephrasing my argument and then you tried to get me to agree with the rephrased and incorrect statement.
 
 This one is apparently useless to you.

My position is that it's totally useless, it adds nothing a pointer does not already give us.

It's either totally useless, or it's your opinion, not both. -S.
Feb 17 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Fri, 17 Feb 2006 23:44:29 -0800, S. Chancellor  
<dnewsgr mephit.kicks-ass.org> wrote:
 On 2006-02-17 19:49:59 -0800, "Regan Heath" <regan netwin.co.nz> said:

 If that's what you want to read...


No, you stated my argument in and altered form.

That's what I just said. :)
 I stated:
 "D has an ever expanding plethora of features which are useless to   
 quite  a few people. "
 Note the choosing of the phrase: "Quite a few people."  Note that I did  
 not say "All People."

Sure, I missunderstood your original statement, you've restated it below so I'll go with that one.
 My argument is that while complex features which I will never use, such  
 as complex types,
 are in D, while some sort of "inref" which is much simpler to add is not.

My objection to "byref" is that it adds nothing that pointers don't already give us. You stated "pointers are vague" could you elaborate on that, how exactly is a pointer vague? If "byref" adds nothing then it doesn't really matter how simple it is, there would be no point in adding it, right?
 I said there are plenty of features that are useful to quite a few   
 people.

 D has an ever expanding plethora of features which are useless to   
 quite  a few people.




That was supposed to read: I said there are plenty of features that are NOT useful to quite a few people.

NP.
  Then you went on to say:
 More being added by the minute, why not a simple aliased  keyword?



can't hurt" or similar. If that was not your intention, sorry, that is how I read it.

See above to what I said. You implied something other than what I said by rephrasing my argument and then you tried to get me to agree with the rephrased and incorrect statement.

I was simply trying to understand the reasoning behind your statement. I was trying to trick you into anything.
 This one is apparently useless to you.

does not already give us.

It's either totally useless, or it's your opinion, not both.

I have no idea what you mean here. My opinion is that "byref" adds nothing of value. Regan
Feb 18 2006
next sibling parent "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 18 Feb 2006 23:07:32 +1300, Regan Heath <regan netwin.co.nz> wrote:
 I was simply trying to understand the reasoning behind your statement. I  
 was trying to trick you into anything.

"was" == "wasn't" :) freud would have a field day. Regan
Feb 18 2006
prev sibling parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Regan Heath wrote:
 My objection to "byref" is that it adds nothing that pointers don't  
 already give us. 

That is apsolutely not true. Then you might say the same about inout. You can do the same with pointers. It is all about abstracting some concepts a little higher. Pointers are a low level construct and people should maybe have an option not to use them to achieve pass by reference semantics.
 You stated "pointers are vague" could you elaborate on  
 that, how exactly is a pointer vague?

Byref vs. pointer is like class vs allocated part of memory plus a couple of functions that think they are doing something usefull to that part of memory, but we don't say we don't need classes. Pointers are sometimes a usefull thing to have, but refereneces are often enough. To pass a pointer to a function you have to take the adress of what you are passing, and in the function you need to dereference a pointer to get to the thing it is pointing at. All this is something a compiler can do for us if we had in-by-reference.
Feb 18 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 18 Feb 2006 11:21:27 +0100, Ivan Senji  
<ivan.senji_REMOVE_ _THIS__gmail.com> wrote:
 Regan Heath wrote:
 My objection to "byref" is that it adds nothing that pointers don't   
 already give us.

That is apsolutely not true. Then you might say the same about inout.

No, I would not. Lets examine the cases shall we? void foo(int a) //tells us 'a' is input void foo(out int a) //tells us 'a' is output void foo(int* a) //tells us nothing void foo(inout int a) //tells us 'a' is input and output. void foo(int* a) //tells us nothing I agree that out and inout add value. If you replace 'int' above with a structure the same is true, however, you get the problem that started this thread: struct A {} void foo(A a) //tells us 'a' is input copies 'in' the entire structure, which may not be desirable, I believe the solution: void foo(A* a) //tells us 'a' is input cannot be improved by "byref", how does "byref" make the above better? eg. void foo(byref A a) //tells us 'a' is input
 You can do the same with pointers. It is all about abstracting some  
 concepts a little higher.

I think it's about: - making the purpose of the parameter clear - passing it in a way to facilitate that purpose. I don't see how "byref" does either of those any better than a pointer does.
 Pointers are a low level construct and people should maybe have an  
 option not to use them to achieve pass by reference semantics.

It's commonly said that having 2 ways to do the same thing is a bad idea.
 You stated "pointers are vague" could you elaborate on  that, how  
 exactly is a pointer vague?

Byref vs. pointer is like class vs allocated part of memory plus a couple of functions that think they are doing something usefull to that part of memory, but we don't say we don't need classes.

I'm not sure what you're saying here.
 Pointers are sometimes a usefull thing to have, but refereneces are  
 often enough. To pass a pointer to a function you have to take the  
 adress of what you are passing,

True.
 and in the function you need to dereference a pointer to get to the  
 thing it is pointing at.

Lets examine this shall we. On the face of it, it's perfectly correct, however lets consider the scenarios: 'int' void foo(int a) //input void foo(out int a) //output void foo(inout int a) //input and output no need for pointers here so no need to dereference 'a'. 'struct A' void foo(A* a) //input void foo(out A a) //output void foo(inout A a) //input and output in the case using a pointer, there is no need to dereference 'a' because D allows us to use '.' on the pointer to access the members. The only time you'd dereference 'a' is to get the address of the structure. In the case where you actually want the address of the structure you have to use a pointer because "byref" will not give you that value.
 All this is something a compiler can do for us if we had in-by-reference.

It is something the compiler is already doing for us with pointers. Regan
Feb 18 2006
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Regan Heath wrote:
 On Sat, 18 Feb 2006 11:21:27 +0100, Ivan Senji  
 <ivan.senji_REMOVE_ _THIS__gmail.com> wrote:
 
 Regan Heath wrote:

 My objection to "byref" is that it adds nothing that pointers don't   
 already give us.

That is apsolutely not true. Then you might say the same about inout.

No, I would not. Lets examine the cases shall we? void foo(int a) //tells us 'a' is input void foo(out int a) //tells us 'a' is output void foo(int* a) //tells us nothing void foo(inout int a) //tells us 'a' is input and output. void foo(int* a) //tells us nothing I agree that out and inout add value. If you replace 'int' above with a structure the same is true, however, you get the problem that started this thread: struct A {} void foo(A a) //tells us 'a' is input copies 'in' the entire structure, which may not be desirable, I believe the solution: void foo(A* a) //tells us 'a' is input

I don't get it: passing a pointer here tells you that A is input but in the above example with int it told you nothing? HM.
 
 cannot be improved by "byref", how does "byref" make the above better? eg.

The same way inout is better than * why is void foo(inout A a) better than foo(A* a) when it does the sam thing? Except the first one is simpler to use and more informative of coders intentions.
 
 void foo(byref A a) //tells us 'a' is input
 
 You can do the same with pointers. It is all about abstracting some  
 concepts a little higher.

I think it's about: - making the purpose of the parameter clear - passing it in a way to facilitate that purpose.

OK, it is all about that.
 I don't see how "byref" does either of those any better than a pointer  
 does.

Yes, I see you have a problem with pointers: foo(int* a) tells you nothing foo(inout int a) tells you something but when it comes to structs you say pointers tells us 'a' is input. But that is just crazy. void foo(A* a) { //I don't care what is in 'a', and I am assigning something to it //so it is definitly not input but output. a.<something> = somethingelse; a.<something> = somethingelse; a.<something> = somethingelse; }
 
 Pointers are a low level construct and people should maybe have an  
 option not to use them to achieve pass by reference semantics.

It's commonly said that having 2 ways to do the same thing is a bad idea.

I' shouldn't even comment on this, but I will: then let's remove inout because it can be done with pointers.
 You stated "pointers are vague" could you elaborate on  that, how  
 exactly is a pointer vague?

Byref vs. pointer is like class vs allocated part of memory plus a couple of functions that think they are doing something usefull to that part of memory, but we don't say we don't need classes.

I'm not sure what you're saying here.

I'm saying that int the end evrything can be done another way. You could program everything in for example assembler, without having classes, inout, delegates and other stuff but achieving the same effect.
 
 Pointers are sometimes a usefull thing to have, but refereneces are  
 often enough. To pass a pointer to a function you have to take the  
 adress of what you are passing,

True.
 and in the function you need to dereference a pointer to get to the  
 thing it is pointing at.

Lets examine this shall we. On the face of it, it's perfectly correct, however lets consider the scenarios: 'int' void foo(int a) //input void foo(out int a) //output void foo(inout int a) //input and output no need for pointers here so no need to dereference 'a'. 'struct A' void foo(A* a) //input

Again that same assumption, why do you trust the writer of 'foo' that much? Did you write it? I wouldn't even trust myself that I'm using 'a' only as input. :)
 void foo(out A a)   //output
 void foo(inout A a) //input and output
 
 in the case using a pointer, there is no need to dereference 'a' because 
 D  allows us to use '.' on the pointer to access the members. The only 
 time  you'd dereference 'a' is to get the address of the structure. 

Ups. Forgot that :)
 In 
 the case  where you actually want the address of the structure you have 
 to use a  pointer because "byref" will not give you that value.
 
 All this is something a compiler can do for us if we had in-by-reference.

It is something the compiler is already doing for us with pointers.

Again: no it isn't.
Feb 18 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 18 Feb 2006 12:35:39 +0100, Ivan Senji  
<ivan.senji_REMOVE_ _THIS__gmail.com> wrote:
 Regan Heath wrote:
 On Sat, 18 Feb 2006 11:21:27 +0100, Ivan Senji   
 <ivan.senji_REMOVE_ _THIS__gmail.com> wrote:

 Regan Heath wrote:

 My objection to "byref" is that it adds nothing that pointers don't    
 already give us.

That is apsolutely not true. Then you might say the same about inout.

void foo(int a) //tells us 'a' is input void foo(out int a) //tells us 'a' is output void foo(int* a) //tells us nothing void foo(inout int a) //tells us 'a' is input and output. void foo(int* a) //tells us nothing I agree that out and inout add value. If you replace 'int' above with a structure the same is true, however, you get the problem that started this thread: struct A {} void foo(A a) //tells us 'a' is input copies 'in' the entire structure, which may not be desirable, I believe the solution: void foo(A* a) //tells us 'a' is input

I don't get it: passing a pointer here tells you that A is input but in the above example with int it told you nothing? HM.

In the world where 'out' and 'inout' do not exist, a pointer represents 3 cases, input, output, and input+output. In the world where 'out' and 'inout' exist they replace the output and input+output cases leaving only the input case. It's true, someone could use a pointer to handle the output or input+ouput cases, you can't guarantee they haven't, just like you can't guarantee they're not going to modify the data referenced by the pointer (or class reference). "byref" doesn't solve that problem either.
  cannot be improved by "byref", how does "byref" make the above better?  
 eg.

The same way inout is better than *

And that way is...? 'inout' is better than * because it allows you to use pass 'int' without dereferencing. "byref" is not required for 'int' and you don't need to dereference a struct, so no benefit there. 'inout' tells us that the variable is being used as input+output. 'in' tells us it's input, which is what a pointer is passed as, "byref" adds nothing more, so no benefit there. What does "byref" add that a pointer cannot?
 why is
 void foo(inout A a) better than foo(A* a) when it does the sam thing?  
 Except the first one is simpler to use and more informative of coders  
 intentions.

Those are the reasons why 'inout' is better, can you say the same for "byref"?
  void foo(byref A a) //tells us 'a' is input

 You can do the same with pointers. It is all about abstracting some   
 concepts a little higher.

- making the purpose of the parameter clear - passing it in a way to facilitate that purpose.

OK, it is all about that.

Well, that's just my opinion. I believe your "abstracting concepts a little higher" is essentially my "making the purpose of the parameter clear" or very similar.
 I don't see how "byref" does either of those any better than a pointer   
 does.

Yes, I see you have a problem with pointers: foo(int* a) tells you nothing foo(inout int a) tells you something but when it comes to structs you say pointers tells us 'a' is input. But that is just crazy.

Only if you ignore the cases that 'out' and 'inout' represent. My initial example was of a world where 'out' and 'inout' do not exist, the C world, I was attemting to show what we all know, that 'out' and 'inout' are valuable because they achieve the goals:
  - making the purpose of the parameter clear
  - passing it in a way to facilitate that purpose.


and thus add value. From that I was attempting to show how "byref" doesn't achieve those goals, or rather that it doesn't improve on what a pointer does to achieve those goals in any way. If you believe "byref" adds value can you tell me how?
 void foo(A* a)
 {
    //I don't care what is in 'a', and I am assigning something to it
    //so it is definitly not input but output.
    a.<something> = somethingelse;
    a.<something> = somethingelse;
    a.<something> = somethingelse;
 }

The same is true for a class reference. "byref" does not solve this issue, it adds nothing over a pointer WRT data protection.
 Pointers are a low level construct and people should maybe have an   
 option not to use them to achieve pass by reference semantics.

idea.

I' shouldn't even comment on this, but I will: then let's remove inout because it can be done with pointers.

If you're suggesting this, even in jest then my attempt to show that 'inout' adds value whereas "byref" does not has failed. My point is this: 'out' and 'inout' add value over a pointer in the output and input+output cases. "byref" does not add any value over a pointer _in the input case_ (which is where "byref" would be used).
 You stated "pointers are vague" could you elaborate on  that, how   
 exactly is a pointer vague?

Byref vs. pointer is like class vs allocated part of memory plus a couple of functions that think they are doing something usefull to that part of memory, but we don't say we don't need classes.


I'm saying that int the end evrything can be done another way. You could program everything in for example assembler, without having classes, inout, delegates and other stuff but achieving the same effect.

Of course, but, and here is the point I am trying to make. We do things in different ways because they are "better", correct? I do not believe "byref" is "better" than a pointer in the "input" case. 'out' and 'inout' are certainly better in the output and input+output cases, thus why we use them.
 Pointers are sometimes a usefull thing to have, but refereneces are   
 often enough. To pass a pointer to a function you have to take the   
 adress of what you are passing,

 and in the function you need to dereference a pointer to get to the   
 thing it is pointing at.

correct, however lets consider the scenarios: 'int' void foo(int a) //input void foo(out int a) //output void foo(inout int a) //input and output no need for pointers here so no need to dereference 'a'. 'struct A' void foo(A* a) //input

Again that same assumption, why do you trust the writer of 'foo' that much? Did you write it? I wouldn't even trust myself that I'm using 'a' only as input. :)

There is no difference here between an "A*" and a class reference. Do you trust this function: class B {} void foo(B b) {} //input Without some sort of data protection there is no way to guarantee the function writer won't modify the data referenced by either 'a' or 'b', but, what does that have to do with "byref" it doesn't solve that problem and more than a pointer does.
 void foo(out A a)   //output
 void foo(inout A a) //input and output
  in the case using a pointer, there is no need to dereference 'a'  
 because D  allows us to use '.' on the pointer to access the members.  
 The only time  you'd dereference 'a' is to get the address of the  
 structure.

Ups. Forgot that :)

Some of the best things about D are the simplest, the '.' operator everywhere is one of them :) Regan
Feb 18 2006
parent S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
Why do you keep referring to "ByRef"-  I wasn't asking for ByRef- this 
thread isn't about ByRef. It's about an _IN_ by reference passing 
method.  It has nothing to do with a method of restricting the 
developer, but establishing with the consumer of the function a type of 
guarantee while going along with the rest of the D passing methods.

-S.


On 2006-02-18 13:19:15 -0800, "Regan Heath" <regan netwin.co.nz> said:

 On Sat, 18 Feb 2006 12:35:39 +0100, Ivan Senji  
 <ivan.senji_REMOVE_ _THIS__gmail.com> wrote:
 Regan Heath wrote:
 On Sat, 18 Feb 2006 11:21:27 +0100, Ivan Senji   
 <ivan.senji_REMOVE_ _THIS__gmail.com> wrote:
 
 Regan Heath wrote:
 
 My objection to "byref" is that it adds nothing that pointers don't    
 already give us.

That is apsolutely not true. Then you might say the same about inout.

void foo(int a) //tells us 'a' is input void foo(out int a) //tells us 'a' is output void foo(int* a) //tells us nothing void foo(inout int a) //tells us 'a' is input and output. void foo(int* a) //tells us nothing I agree that out and inout add value. If you replace 'int' above with a structure the same is true, however, you get the problem that started this thread: struct A {} void foo(A a) //tells us 'a' is input copies 'in' the entire structure, which may not be desirable, I believe the solution: void foo(A* a) //tells us 'a' is input

I don't get it: passing a pointer here tells you that A is input but in the above example with int it told you nothing? HM.

In the world where 'out' and 'inout' do not exist, a pointer represents 3 cases, input, output, and input+output. In the world where 'out' and 'inout' exist they replace the output and input+output cases leaving only the input case. It's true, someone could use a pointer to handle the output or input+ouput cases, you can't guarantee they haven't, just like you can't guarantee they're not going to modify the data referenced by the pointer (or class reference). "byref" doesn't solve that problem either.
  cannot be improved by "byref", how does "byref" make the above better?  eg.

The same way inout is better than *

And that way is...? 'inout' is better than * because it allows you to use pass 'int' without dereferencing. "byref" is not required for 'int' and you don't need to dereference a struct, so no benefit there. 'inout' tells us that the variable is being used as input+output. 'in' tells us it's input, which is what a pointer is passed as, "byref" adds nothing more, so no benefit there. What does "byref" add that a pointer cannot?
 why is
 void foo(inout A a) better than foo(A* a) when it does the sam thing?  
 Except the first one is simpler to use and more informative of coders  
 intentions.

Those are the reasons why 'inout' is better, can you say the same for "byref"?
  void foo(byref A a) //tells us 'a' is input
 
 You can do the same with pointers. It is all about abstracting some   
 concepts a little higher.

- making the purpose of the parameter clear - passing it in a way to facilitate that purpose.

OK, it is all about that.

Well, that's just my opinion. I believe your "abstracting concepts a little higher" is essentially my "making the purpose of the parameter clear" or very similar.
 I don't see how "byref" does either of those any better than a pointer   does.

Yes, I see you have a problem with pointers: foo(int* a) tells you nothing foo(inout int a) tells you something but when it comes to structs you say pointers tells us 'a' is input. But that is just crazy.

Only if you ignore the cases that 'out' and 'inout' represent. My initial example was of a world where 'out' and 'inout' do not exist, the C world, I was attemting to show what we all know, that 'out' and 'inout' are valuable because they achieve the goals:
  - making the purpose of the parameter clear
  - passing it in a way to facilitate that purpose.


and thus add value. From that I was attempting to show how "byref" doesn't achieve those goals, or rather that it doesn't improve on what a pointer does to achieve those goals in any way. If you believe "byref" adds value can you tell me how?
 void foo(A* a)
 {
    //I don't care what is in 'a', and I am assigning something to it
    //so it is definitly not input but output.
    a.<something> = somethingelse;
    a.<something> = somethingelse;
    a.<something> = somethingelse;
 }

The same is true for a class reference. "byref" does not solve this issue, it adds nothing over a pointer WRT data protection.
 Pointers are a low level construct and people should maybe have an   
 option not to use them to achieve pass by reference semantics.


I' shouldn't even comment on this, but I will: then let's remove inout because it can be done with pointers.

If you're suggesting this, even in jest then my attempt to show that 'inout' adds value whereas "byref" does not has failed. My point is this: 'out' and 'inout' add value over a pointer in the output and input+output cases. "byref" does not add any value over a pointer _in the input case_ (which is where "byref" would be used).
 You stated "pointers are vague" could you elaborate on  that, how   
 exactly is a pointer vague?

Byref vs. pointer is like class vs allocated part of memory plus a couple of functions that think they are doing something usefull to that part of memory, but we don't say we don't need classes.


I'm saying that int the end evrything can be done another way. You could program everything in for example assembler, without having classes, inout, delegates and other stuff but achieving the same effect.

Of course, but, and here is the point I am trying to make. We do things in different ways because they are "better", correct? I do not believe "byref" is "better" than a pointer in the "input" case. 'out' and 'inout' are certainly better in the output and input+output cases, thus why we use them.
 Pointers are sometimes a usefull thing to have, but refereneces are   
 often enough. To pass a pointer to a function you have to take the   
 adress of what you are passing,

 and in the function you need to dereference a pointer to get to the   
 thing it is pointing at.

correct, however lets consider the scenarios: 'int' void foo(int a) //input void foo(out int a) //output void foo(inout int a) //input and output no need for pointers here so no need to dereference 'a'. 'struct A' void foo(A* a) //input

Again that same assumption, why do you trust the writer of 'foo' that much? Did you write it? I wouldn't even trust myself that I'm using 'a' only as input. :)

There is no difference here between an "A*" and a class reference. Do you trust this function: class B {} void foo(B b) {} //input Without some sort of data protection there is no way to guarantee the function writer won't modify the data referenced by either 'a' or 'b', but, what does that have to do with "byref" it doesn't solve that problem and more than a pointer does.
 void foo(out A a)   //output
 void foo(inout A a) //input and output
  in the case using a pointer, there is no need to dereference 'a'  
 because D  allows us to use '.' on the pointer to access the members.  
 The only time  you'd dereference 'a' is to get the address of the  
 structure.

Ups. Forgot that :)

Some of the best things about D are the simplest, the '.' operator everywhere is one of them :) Regan

Feb 22 2006
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor wrote:

 This recent thread about unsafe, and some of my own coding has recently 
 pointed out a feature D lacks:
 
 In by reference

I've just noticed this in the D documentation, in the ABI reference... --------------- Reference Types When passing a static array to a function, the result, although declared as a static array, will actually be a reference to a static array. For example: int abc[3]; Passing abc to functions results in these implicit conversions: void func(int array[3]); // actually <reference to><array[3] of><int> void func(int *p); // abc[3] is converted to a pointer // to the first element void func(int array[]); // abc[3] is converted to a dynamic array ---------------- -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 16/02/2006 10:54:01 AM
Feb 15 2006
parent reply Sean Kelly <sean f4.ca> writes:
Derek Parnell wrote:
 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor wrote:
 
 This recent thread about unsafe, and some of my own coding has recently 
 pointed out a feature D lacks:

 In by reference

I've just noticed this in the D documentation, in the ABI reference... --------------- Reference Types When passing a static array to a function, the result, although declared as a static array, will actually be a reference to a static array.

This seems identical to array passing in C, where the same thing occurs. Sean
Feb 15 2006
parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 15 Feb 2006 16:12:22 -0800, Sean Kelly wrote:

 Derek Parnell wrote:
 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor wrote:
 
 This recent thread about unsafe, and some of my own coding has recently 
 pointed out a feature D lacks:

 In by reference

I've just noticed this in the D documentation, in the ABI reference... --------------- Reference Types When passing a static array to a function, the result, although declared as a static array, will actually be a reference to a static array.

This seems identical to array passing in C, where the same thing occurs.

Okay. It's just that it seems to me then that S.'s concerns about passing a huge array using the 'in' format are not warranted. However, this doesn't help out with passing huge structures -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 16/02/2006 11:25:06 AM
Feb 15 2006
next sibling parent Sean Kelly <sean f4.ca> writes:
Derek Parnell wrote:
 On Wed, 15 Feb 2006 16:12:22 -0800, Sean Kelly wrote:
 
 Derek Parnell wrote:
 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor wrote:

 This recent thread about unsafe, and some of my own coding has recently 
 pointed out a feature D lacks:

 In by reference

--------------- Reference Types When passing a static array to a function, the result, although declared as a static array, will actually be a reference to a static array.


Okay. It's just that it seems to me then that S.'s concerns about passing a huge array using the 'in' format are not warranted. However, this doesn't help out with passing huge structures

Agreed. Though I agree that if something happens then it must be in the ABI. The last thing I want in D is binary incompatibility between compilers. Sean
Feb 15 2006
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 16 Feb 2006 11:27:45 +1100, Derek Parnell wrote:

 On Wed, 15 Feb 2006 16:12:22 -0800, Sean Kelly wrote:
 
 Derek Parnell wrote:
 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor wrote:
 
 This recent thread about unsafe, and some of my own coding has recently 
 pointed out a feature D lacks:

 In by reference

I've just noticed this in the D documentation, in the ABI reference... --------------- Reference Types When passing a static array to a function, the result, although declared as a static array, will actually be a reference to a static array.

This seems identical to array passing in C, where the same thing occurs.

Okay. It's just that it seems to me then that S.'s concerns about passing a huge array using the 'in' format are not warranted. However, this doesn't help out with passing huge structures

Oops, spoke too soon. I just tried this little test ... ----------------- import std.stdio; char[100000] a = void; void func(in char[100000] x) { x[0] = 'x'; } void main() { a[0] = 'a'; func(a); writefln("%s", a[0]); } ----------------- So although the huge array might actually be passed via a reference, it seems that the 'in' modifier is not respected. The output was 'x'. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 16/02/2006 11:32:51 AM
Feb 15 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 16 Feb 2006 11:34:39 +1100, Derek Parnell <derek psych.ward> wrote:
 On Thu, 16 Feb 2006 11:27:45 +1100, Derek Parnell wrote:

 On Wed, 15 Feb 2006 16:12:22 -0800, Sean Kelly wrote:

 Derek Parnell wrote:
 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor wrote:

 This recent thread about unsafe, and some of my own coding has  
 recently
 pointed out a feature D lacks:

 In by reference

I've just noticed this in the D documentation, in the ABI reference... --------------- Reference Types When passing a static array to a function, the result, although declared as a static array, will actually be a reference to a static array.

This seems identical to array passing in C, where the same thing occurs.

Okay. It's just that it seems to me then that S.'s concerns about passing a huge array using the 'in' format are not warranted. However, this doesn't help out with passing huge structures

Oops, spoke too soon. I just tried this little test ... ----------------- import std.stdio; char[100000] a = void; void func(in char[100000] x) { x[0] = 'x'; } void main() { a[0] = 'a'; func(a); writefln("%s", a[0]); } ----------------- So although the huge array might actually be passed via a reference, it seems that the 'in' modifier is not respected. The output was 'x'.

The 'in' modifier applies to the array reference, not the data. Regan
Feb 15 2006
parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 16 Feb 2006 13:39:56 +1300, Regan Heath wrote:

 On Thu, 16 Feb 2006 11:34:39 +1100, Derek Parnell <derek psych.ward> wrote:
 On Thu, 16 Feb 2006 11:27:45 +1100, Derek Parnell wrote:

 On Wed, 15 Feb 2006 16:12:22 -0800, Sean Kelly wrote:

 Derek Parnell wrote:
 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor wrote:

 This recent thread about unsafe, and some of my own coding has  
 recently
 pointed out a feature D lacks:

 In by reference

I've just noticed this in the D documentation, in the ABI reference... --------------- Reference Types When passing a static array to a function, the result, although declared as a static array, will actually be a reference to a static array.

This seems identical to array passing in C, where the same thing occurs.

Okay. It's just that it seems to me then that S.'s concerns about passing a huge array using the 'in' format are not warranted. However, this doesn't help out with passing huge structures

Oops, spoke too soon. I just tried this little test ... ----------------- import std.stdio; char[100000] a = void; void func(in char[100000] x) { x[0] = 'x'; } void main() { a[0] = 'a'; func(a); writefln("%s", a[0]); } ----------------- So although the huge array might actually be passed via a reference, it seems that the 'in' modifier is not respected. The output was 'x'.

The 'in' modifier applies to the array reference, not the data.

Yes I know that! But I didn't pass a reference, I passed an array. The compiler passed the reference. But yeah, I know...this is the whole point that people have been on about for ages. I just thought I'd highlight another trap for coders. You may think your passing the array but you aren't really. Nasty things could happen here. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 16/02/2006 12:04:28 PM
Feb 15 2006
next sibling parent S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-15 17:06:26 -0800, Derek Parnell <derek psych.ward> said:

 On Thu, 16 Feb 2006 13:39:56 +1300, Regan Heath wrote:
 
 On Thu, 16 Feb 2006 11:34:39 +1100, Derek Parnell <derek psych.ward> wrote:
 On Thu, 16 Feb 2006 11:27:45 +1100, Derek Parnell wrote:
 
 On Wed, 15 Feb 2006 16:12:22 -0800, Sean Kelly wrote:
 
 Derek Parnell wrote:
 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor wrote:
 
 This recent thread about unsafe, and some of my own coding has  recently
 pointed out a feature D lacks:
 
 In by reference

I've just noticed this in the D documentation, in the ABI reference... --------------- Reference Types When passing a static array to a function, the result, although declared as a static array, will actually be a reference to a static array.

This seems identical to array passing in C, where the same thing occurs.

Okay. It's just that it seems to me then that S.'s concerns about passing a huge array using the 'in' format are not warranted. However, this doesn't help out with passing huge structures

Oops, spoke too soon. I just tried this little test ... ----------------- import std.stdio; char[100000] a = void; void func(in char[100000] x) { x[0] = 'x'; } void main() { a[0] = 'a'; func(a); writefln("%s", a[0]); } ----------------- So although the huge array might actually be passed via a reference, it seems that the 'in' modifier is not respected. The output was 'x'.

The 'in' modifier applies to the array reference, not the data.

Yes I know that! But I didn't pass a reference, I passed an array. The compiler passed the reference. But yeah, I know...this is the whole point that people have been on about for ages. I just thought I'd highlight another trap for coders. You may think your passing the array but you aren't really. Nasty things could happen here.

Which is specifically why I wrapped the array into a structure. Static arrays within structures are contiguous with the rest of the structure, or should be. Try it again that way. My main point had nothing to do with passing arrays specifically, but passing NON-REFERENCE data types such as structures via in keywords. I filled the structure with a big static array to illustrate that it was big. -S.
Feb 15 2006
prev sibling parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Derek Parnell wrote:
 On Thu, 16 Feb 2006 13:39:56 +1300, Regan Heath wrote:
 
 On Thu, 16 Feb 2006 11:34:39 +1100, Derek Parnell <derek psych.ward> wrote:
 On Thu, 16 Feb 2006 11:27:45 +1100, Derek Parnell wrote:

 On Wed, 15 Feb 2006 16:12:22 -0800, Sean Kelly wrote:

 Derek Parnell wrote:
 On Tue, 14 Feb 2006 05:11:42 -0800, S. Chancellor wrote:

 This recent thread about unsafe, and some of my own coding has  
 recently
 pointed out a feature D lacks:

 In by reference

--------------- Reference Types When passing a static array to a function, the result, although declared as a static array, will actually be a reference to a static array.

occurs.

passing a huge array using the 'in' format are not warranted. However, this doesn't help out with passing huge structures

----------------- import std.stdio; char[100000] a = void; void func(in char[100000] x) { x[0] = 'x'; } void main() { a[0] = 'a'; func(a); writefln("%s", a[0]); } ----------------- So although the huge array might actually be passed via a reference, it seems that the 'in' modifier is not respected. The output was 'x'.


Yes I know that! But I didn't pass a reference, I passed an array. The compiler passed the reference. But yeah, I know...this is the whole point that people have been on about for ages. I just thought I'd highlight another trap for coders. You may think your passing the array but you aren't really. Nasty things could happen here.

How is that surprising, or another trap for coders ? It's the way it is done since old C to any modern day C-family language. Static arrays are (like) reference types. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Feb 16 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Fri, 17 Feb 2006 00:51:05 +1100, Bruno Medeiros  
<daiphoenixNO SPAMlycos.com> wrote:


[snip]

 The 'in' modifier applies to the array reference, not the data.

compiler passed the reference. But yeah, I know...this is the whole point that people have been on about for ages. I just thought I'd highlight another trap for coders. You may think your passing the array but you aren't really. Nasty things could happen here.

How is that surprising, or another trap for coders ? It's the way it is done since old C to any modern day C-family language. Static arrays are (like) reference types.

It is surprising if one does not have a C background and one uses normal reasoning. My code said "pass this array to the function". The compiler didn't do that. We are told that fixed length arrays and structs are created on the stack not the heap but that classes and variable length arrays are heap things. We are told that heap entities are passed by reference. We are told that structs are passed by value, so one could innocently assume that fixed length arrays, being stack entities like structs, are also passed by value. This topic doesn't warrant further consideration. -- Derek Parnell Melbourne, Australia
Feb 16 2006
next sibling parent reply S. Chancellor <S._member pathlink.com> writes:
In article <op.s42nznti6b8z09 ginger.vic.bigpond.net.au>, Derek Parnell says...
On Fri, 17 Feb 2006 00:51:05 +1100, Bruno Medeiros  
<daiphoenixNO SPAMlycos.com> wrote:


[snip]

 The 'in' modifier applies to the array reference, not the data.

compiler passed the reference. But yeah, I know...this is the whole point that people have been on about for ages. I just thought I'd highlight another trap for coders. You may think your passing the array but you aren't really. Nasty things could happen here.

How is that surprising, or another trap for coders ? It's the way it is done since old C to any modern day C-family language. Static arrays are (like) reference types.

It is surprising if one does not have a C background and one uses normal reasoning. My code said "pass this array to the function". The compiler didn't do that. We are told that fixed length arrays and structs are created on the stack not the heap but that classes and variable length arrays are heap things. We are told that heap entities are passed by reference. We are told that structs are passed by value, so one could innocently assume that fixed length arrays, being stack entities like structs, are also passed by value. This topic doesn't warrant further consideration.

It's interesting to note that classes passed via 'in' parameters are still passed by VALUE. Not reference. Just some food for thought. -S.
Feb 16 2006
parent reply S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-16 09:23:17 -0800, S. Chancellor <S._member pathlink.com> said:

 In article <op.s42nznti6b8z09 ginger.vic.bigpond.net.au>, Derek Parnell says...
 
 On Fri, 17 Feb 2006 00:51:05 +1100, Bruno Medeiros  
 <daiphoenixNO SPAMlycos.com> wrote:
 
 
 [snip]
 
 The 'in' modifier applies to the array reference, not the data.

compiler passed the reference. But yeah, I know...this is the whole point that people have been on about for ages. I just thought I'd highlight another trap for coders. You may think your passing the array but you aren't really. Nasty things could happen here.

How is that surprising, or another trap for coders ? It's the way it is done since old C to any modern day C-family language. Static arrays are (like) reference types.

It is surprising if one does not have a C background and one uses normal reasoning. My code said "pass this array to the function". The compiler didn't do that. We are told that fixed length arrays and structs are created on the stack not the heap but that classes and variable length arrays are heap things. We are told that heap entities are passed by reference. We are told that structs are passed by value, so one could innocently assume that fixed length arrays, being stack entities like structs, are also passed by value. This topic doesn't warrant further consideration.

It's interesting to note that classes passed via 'in' parameters are still passed by VALUE. Not reference. Just some food for thought. -S.

Ignore my dipshit comment. I ran my test incorrectly. -S.
Feb 16 2006
parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
S. Chancellor wrote:
 On 2006-02-16 09:23:17 -0800, S. Chancellor <S._member pathlink.com> said:
 
 In article <op.s42nznti6b8z09 ginger.vic.bigpond.net.au>, Derek 
 Parnell says...
 On Fri, 17 Feb 2006 00:51:05 +1100, Bruno Medeiros  
 <daiphoenixNO SPAMlycos.com> wrote:


 [snip]

 The 'in' modifier applies to the array reference, not the data.

compiler passed the reference. But yeah, I know...this is the whole point that people have been on about for ages. I just thought I'd highlight another trap for coders. You may think your passing the array but you aren't really. Nasty things could happen here.

How is that surprising, or another trap for coders ? It's the way it is done since old C to any modern day C-family language. Static arrays are (like) reference types.

It is surprising if one does not have a C background and one uses normal reasoning. My code said "pass this array to the function". The compiler didn't do that. We are told that fixed length arrays and structs are created on the stack not the heap but that classes and variable length arrays are heap things. We are told that heap entities are passed by reference. We are told that structs are passed by value, so one could innocently assume that fixed length arrays, being stack entities like structs, are also passed by value. This topic doesn't warrant further consideration.

It's interesting to note that classes passed via 'in' parameters are still passed by VALUE. Not reference. Just some food for thought. -S.

Ignore my dipshit comment. I ran my test incorrectly. -S.

your notion of value/reference types and their argument passing. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Feb 17 2006
parent reply S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-17 06:29:43 -0800, Bruno Medeiros <daiphoenixNO SPAMlycos.com> said:

 S. Chancellor wrote:
 On 2006-02-16 09:23:17 -0800, S. Chancellor <S._member pathlink.com> said:
 
 In article <op.s42nznti6b8z09 ginger.vic.bigpond.net.au>, Derek Parnell says...
 
 On Fri, 17 Feb 2006 00:51:05 +1100, Bruno Medeiros  
 <daiphoenixNO SPAMlycos.com> wrote:
 
 
 [snip]
 
 The 'in' modifier applies to the array reference, not the data.

compiler passed the reference. But yeah, I know...this is the whole point that people have been on about for ages. I just thought I'd highlight another trap for coders. You may think your passing the array but you aren't really. Nasty things could happen here.

How is that surprising, or another trap for coders ? It's the way it is done since old C to any modern day C-family language. Static arrays are (like) reference types.

It is surprising if one does not have a C background and one uses normal reasoning. My code said "pass this array to the function". The compiler didn't do that. We are told that fixed length arrays and structs are created on the stack not the heap but that classes and variable length arrays are heap things. We are told that heap entities are passed by reference. We are told that structs are passed by value, so one could innocently assume that fixed length arrays, being stack entities like structs, are also passed by value. This topic doesn't warrant further consideration.

It's interesting to note that classes passed via 'in' parameters are still passed by VALUE. Not reference. Just some food for thought. -S.

Ignore my dipshit comment. I ran my test incorrectly. -S.

your notion of value/reference types and their argument passing.

The point is the class is not passed by value. The pointer to the class is passed by value. What good is that? -S. P.S. I have enough humility to admit my error, and you come back with a snide remark like that? I don't even know you.
Feb 17 2006
parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
S. Chancellor wrote:
 On 2006-02-17 06:29:43 -0800, Bruno Medeiros 
 <daiphoenixNO SPAMlycos.com> said:
 
 S. Chancellor wrote:
 On 2006-02-16 09:23:17 -0800, S. Chancellor <S._member pathlink.com> 
 said:
 It's interesting to note that classes passed via 'in' parameters are 
 still
 passed by VALUE.  Not reference.

 Just some food for thought.

 -S.

Ignore my dipshit comment. I ran my test incorrectly. -S.

your notion of value/reference types and their argument passing.

The point is the class is not passed by value. The pointer to the class is passed by value. What good is that?

 -S.
 
 P.S.  I have enough humility to admit my error, and you come back with a 
 snide remark like that?  I don't even know you.
 

uninsulting way. If you do not agree, then tell me: how could have I said what I said, in a non-snide way? -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Feb 18 2006
parent S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-18 06:09:22 -0800, Bruno Medeiros <daiphoenixNO SPAMlycos.com> said:

 S. Chancellor wrote:
 On 2006-02-17 06:29:43 -0800, Bruno Medeiros <daiphoenixNO SPAMlycos.com> said:
 
 S. Chancellor wrote:
 On 2006-02-16 09:23:17 -0800, S. Chancellor <S._member pathlink.com> said:
 
 
 It's interesting to note that classes passed via 'in' parameters are still
 passed by VALUE.  Not reference.
 
 Just some food for thought.
 
 -S.

Ignore my dipshit comment. I ran my test incorrectly. -S.

your notion of value/reference types and their argument passing.

The point is the class is not passed by value. The pointer to the class is passed by value. What good is that?


No it's not. The "class" is a bunch of allocated data on the heap. The pointer is just that, a pointer. I have to agree with Derek on this one.
 
 -S.
 
 P.S.  I have enough humility to admit my error, and you come back with 
 a snide remark like that?  I don't even know you.
 

uninsulting way. If you do not agree, then tell me: how could have I said what I said, in a non-snide way?

You couldn't have, because your implication was snide. You shouldn't have said it at all. -S.
Feb 22 2006
prev sibling parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Derek Parnell wrote:
 On Fri, 17 Feb 2006 00:51:05 +1100, Bruno Medeiros 
 <daiphoenixNO SPAMlycos.com> wrote:
 
 
 [snip]
 
 The 'in' modifier applies to the array reference, not the data.

compiler passed the reference. But yeah, I know...this is the whole point that people have been on about for ages. I just thought I'd highlight another trap for coders. You may think your passing the array but you aren't really. Nasty things could happen here.

How is that surprising, or another trap for coders ? It's the way it is done since old C to any modern day C-family language. Static arrays are (like) reference types.

It is surprising if one does not have a C background and one uses normal reasoning.

languages background, we could clarify (by "we" I mean foremost the docs) this issue by clearly stating that static arrays are reference types, just like it's kin dynamic arrays.
 My code said "pass this array to the function". The compiler didn't do 
 that. We are told that fixed length arrays and structs are created on 
 the stack not the heap but that classes and variable length arrays are 
 heap things. We are told that heap entities are passed by reference. We 
 are told that structs are passed by value, so one could innocently 
 assume that fixed length arrays, being stack entities like structs, are 
 also passed by value.
 

means to discern parameter behavior. What we should think of, is if the data type is a value type, or a reference type. And also: *all* variables in D are by default passed by value, including classes and arrays. What happens is that they are reference values. This conceptualization may look similar, but it's not, and it's a very important notion to have.
 This topic doesn't warrant further consideration.
 

relevant. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Feb 17 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Sat, 18 Feb 2006 01:28:01 +1100, Bruno Medeiros  
<daiphoenixNO SPAMlycos.com> wrote:

 Derek Parnell wrote:
 On Fri, 17 Feb 2006 00:51:05 +1100, Bruno Medeiros  
 <daiphoenixNO SPAMlycos.com> wrote:
   [snip]

 The 'in' modifier applies to the array reference, not the data.

The compiler passed the reference. But yeah, I know...this is the whole point that people have been on about for ages. I just thought I'd highlight another trap for coders. You may think your passing the array but you aren't really. Nasty things could happen here.

How is that surprising, or another trap for coders ? It's the way it is done since old C to any modern day C-family language. Static arrays are (like) reference types.

normal reasoning.

languages background, we could clarify (by "we" I mean foremost the docs) this issue by clearly stating that static arrays are reference types, just like it's kin dynamic arrays.
 My code said "pass this array to the function". The compiler didn't do  
 that. We are told that fixed length arrays and structs are created on  
 the stack not the heap but that classes and variable length arrays are  
 heap things. We are told that heap entities are passed by reference. We  
 are told that structs are passed by value, so one could innocently  
 assume that fixed length arrays, being stack entities like structs, are  
 also passed by value.

means to discern parameter behavior. What we should think of, is if the data type is a value type, or a reference type. And also: *all* variables in D are by default passed by value, including classes and arrays. What happens is that they are reference values. This conceptualization may look similar, but it's not, and it's a very important notion to have.

That is very wrong. When passing a class instance, the data which is owned by that object is not passed (its value) but as you say, an address of a RAM structure that represents the object is passed (its reference). The 'reference' is not the 'value'. When passing an array, the bits that go in into making the value of the data that is owned by the array is not passed (its value) but an address of an 8-byte structure (in the case of variable length arrays) or the address of the data (in the case of fixed length arrays) is passed (its reference). The 'reference' is not the 'value'. So, some things are passed by reference (which is not its value) and some things are passed by value (which is not its reference).
 This topic doesn't warrant further consideration.

relevant.

Because we, and others, have been saying the same things over and over again without resolution or advancement. None of these discussions is going to change D. The 'in' qualifier ensures that whatever changes are made to whatever that is literally passed as a function parameter will not be returned to the caller in that same parameter. Both the 'out' and 'inout' qualifier ensures that whatever changes are made to whatever that is literally passed as a function parameter will be returned to the caller in that same parameter. Thus, in the case of 'in' and an array, what is literally passed is the reference and that reference is what is protected. The original poster, I think, was just saying it would be useful to have another option available for those things that are currently passed by value, and that option being that we can specify that instead of being passed by value that we want it to be passed by reference *and* that we don't want to use pointer notation to do that. -- Derek Parnell Melbourne, Australia
Feb 17 2006
next sibling parent reply S. Chancellor <S._member pathlink.com> writes:
In article <op.s44i7ehj6b8z09 ginger.vic.bigpond.net.au>, Derek Parnell says...
The original poster, I think, was just saying it would be useful to have  
another option available for those things that are currently passed by  
value, and that option being that we can specify that instead of being  
passed by value that we want it to be passed by reference *and* that we  
don't want to use pointer notation to do that.

Being the original poster, I can say this is almost exactly what I meant! At least someone understands what I was talking about! Also, I was stating not only that we don't want to use pointers, but we also don't want to use inout, because inout means we're going to change the value. -S.
Feb 17 2006
next sibling parent Dave <Dave_member pathlink.com> writes:
In article <dt55qh$bq0$1 digitaldaemon.com>, S. Chancellor says...
In article <op.s44i7ehj6b8z09 ginger.vic.bigpond.net.au>, Derek Parnell says...
The original poster, I think, was just saying it would be useful to have  
another option available for those things that are currently passed by  
value, and that option being that we can specify that instead of being  
passed by value that we want it to be passed by reference *and* that we  
don't want to use pointer notation to do that.

Being the original poster, I can say this is almost exactly what I meant! At least someone understands what I was talking about! Also, I was stating not only that we don't want to use pointers, but we also don't want to use inout, because inout means we're going to change the value. -S.

That's what I understood it as, and why I suggested 'byref' as a replacement. From your follow-up, I think the main problem you had with just 'byref' is that it is not as 'self-documenting' and also maybe that sometimes one would really want 'inref' (like const & in C++)? <I hope I'm not confusing things more here with that 'inref' part> I *think* from Walter's POV, he wants in/out/inout to only describe the intent and doesn't want to get into the source-code level optimization implications of things like 'byref', preferring instead to let compiler implementations battle that out. Kind-of like D not having 'inline' - I think 'byref' or some form of 'inref' would be adding a keyword to the language that optimizing compilers can generally do a good job of figuring out as it's something that is becoming well understood (like inline) by compiler developers. *If* that is Walter's POV, then I'd have to agree with him, I guess, because sprinkling C++ code with 'const &' everywhere for performance reasons sucks. In other words, just use 'in' for now and if DMD doesn't perform as well, try GDC and bitch about the performance of DMD ;) FWIW, a few months ago I agreed with your sentiment but now I think it is an area that should be addressed by the compiler optimizer if possible. - Dave
Feb 17 2006
prev sibling next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Fri, 17 Feb 2006 18:48:49 +0000 (UTC), S. Chancellor  
<S._member pathlink.com> wrote:
 In article <op.s44i7ehj6b8z09 ginger.vic.bigpond.net.au>, Derek Parnell  
 says...
 The original poster, I think, was just saying it would be useful to have
 another option available for those things that are currently passed by
 value, and that option being that we can specify that instead of being
 passed by value that we want it to be passed by reference *and* that we
 don't want to use pointer notation to do that.

Being the original poster, I can say this is almost exactly what I meant! At least someone understands what I was talking about!

I have understood what you're suggesting since your original post, my only problem is that "byref" seems to be a duplication of what a pointer gives us for no benefit.
 Also, I was stating not only that we don't want to use pointers, but we  
 also don't want to use inout, because inout means we're going to change  
 the value.

I agree we certainly don't want 'inout' but what reason do you have for not using a pointer? Regan
Feb 17 2006
parent reply S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-17 19:58:09 -0800, "Regan Heath" <regan netwin.co.nz> said:

 On Fri, 17 Feb 2006 18:48:49 +0000 (UTC), S. Chancellor  
 <S._member pathlink.com> wrote:
 In article <op.s44i7ehj6b8z09 ginger.vic.bigpond.net.au>, Derek Parnell 
  says...
 
 The original poster, I think, was just saying it would be useful to have
 another option available for those things that are currently passed by
 value, and that option being that we can specify that instead of being
 passed by value that we want it to be passed by reference *and* that we
 don't want to use pointer notation to do that.

Being the original poster, I can say this is almost exactly what I meant! At least someone understands what I was talking about!

I have understood what you're suggesting since your original post, my only problem is that "byref" seems to be a duplication of what a pointer gives us for no benefit.
 Also, I was stating not only that we don't want to use pointers, but we 
  also don't want to use inout, because inout means we're going to 
 change  the value.

I agree we certainly don't want 'inout' but what reason do you have for not using a pointer?

Because pointers are vague! Not only that, D set the precedent for new parameter passing syntax with in/inout/out and you need to break from that to use pointers. Thirdly D also set a precedent by treating pointers as a new type (D changed declarations so that pointers are with the type rather than the instance now.) Presuming that a int* is a different type, then what you are saying is that you want something other than an int to manipulate. That's untrue though. So, when using a pointer in D you are doing a few things. You are being vague about what you do to the original value. You also want to deal with a pointer to an int, and not actually an int. While in some cases this is the case, most of the time all you wanted was the value. Note that you can have parameters of type in that are pointers, since pointers are associated with variable types, and not passing method. -S.
Feb 17 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Fri, 17 Feb 2006 23:58:54 -0800, S. Chancellor  
<dnewsgr mephit.kicks-ass.org> wrote:
 On 2006-02-17 19:58:09 -0800, "Regan Heath" <regan netwin.co.nz> said:

 On Fri, 17 Feb 2006 18:48:49 +0000 (UTC), S. Chancellor   
 <S._member pathlink.com> wrote:
 In article <op.s44i7ehj6b8z09 ginger.vic.bigpond.net.au>, Derek  
 Parnell  says...
  The original poster, I think, was just saying it would be useful to  
 have
 another option available for those things that are currently passed by
 value, and that option being that we can specify that instead of being
 passed by value that we want it to be passed by reference *and* that  
 we
 don't want to use pointer notation to do that.

meant! At least someone understands what I was talking about!

only problem is that "byref" seems to be a duplication of what a pointer gives us for no benefit.
 Also, I was stating not only that we don't want to use pointers, but  
 we  also don't want to use inout, because inout means we're going to  
 change  the value.

for not using a pointer?

Because pointers are vague!

Please elaborate. I don't see how this: struct A {} void foo(A* p) {} is any more or less vague than this: struct A {} void foo(byref A p) {}
 Not only that, D set the precedent for new parameter passing syntax with  
 in/inout/out and you need to break from that to use pointers.

'out' and 'inout' do replace the use of pointers (or passing by reference) for 2 cases of parameter, that is true. By I do not think that constitutes a precedent, it's simply a better way to handle each of those cases. The same cannot be said for "byref", it's not any _better_ than a pointer.
 Thirdly D also set a precedent by treating pointers as a new type (D  
 changed declarations so that pointers are with the type rather than the  
 instance now.)

Pointers have always been a distinct type. The change D made was in how the declaration of types is parsed, nothing more.
 Presuming that a int* is a different type

It is.
 , then what you are saying is that you want something other than an int  
 to manipulate. That's untrue though.

I'm not sure what you meant by this statement. Can you re-phrase please.
 So, when using a pointer in D you are doing a few things.  You are being  
 vague about what you do to the original value.

Not any more or less vague than a class reference. Both a pointer and a class reference are passed 'in' and you cannot effect their value outside the function call. Therefore the original reference/pointer is safe from manipulation. In neither case is the content of the class/struct safe from manipulation. eg. struct A { int a; } class B { int b; } void foo(A* a) { a.a = 1; } void foo(B b) { b.b = 1; } void main() { A a; B b = new B(); foo(&a); foo(b); } the two cases above are essentially identical, both functions accept a reference to the data type they wish to access, both references are passed 'in'. The only difference is that A is a value type and to get a reference you must use a pointer.
 You also want to deal with a pointer to an int, and not actually an int.  
 While in some cases this is the case, most of the time all you wanted  
 was the value.

You have no need of pointers when passing an int: - if you want to read it, you use 'in'. - if you want to write to it, you use 'out'. - if you want to read and write it, you use 'inout'. In what case would you use "byref" with an 'int'? If you want to read, write, or read+write it you'd use one of the existing modes in/out/inout, right?
 Note that you can have parameters of type in that are pointers,  since  
 pointers are associated with variable types, and not passing method.

A pointer _is_ a variable type. Regan
Feb 18 2006
next sibling parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Regan Heath wrote:
 Please elaborate. I don't see how this:
 
 struct A {}
 void foo(A* p) {}
 
 is any more or less vague than this:
 
 struct A {}
 void foo(byref A p) {}

It is less vague. The problem is you see pointer as input, but it obviously isn't.
 
 Not only that, D set the precedent for new parameter passing syntax 
 with  in/inout/out and you need to break from that to use pointers.

'out' and 'inout' do replace the use of pointers (or passing by reference) for 2 cases of parameter, that is true. By I do not think that constitutes a precedent, it's simply a better way to handle each of those cases. The same cannot be said for "byref", it's not any _better_ than a pointer.

It is, because pointer doesn't say input.
Feb 18 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 18 Feb 2006 12:44:28 +0100, Ivan Senji  
<ivan.senji_REMOVE_ _THIS__gmail.com> wrote:
 Regan Heath wrote:
 Please elaborate. I don't see how this:
  struct A {}
 void foo(A* p) {}
  is any more or less vague than this:
  struct A {}
 void foo(byref A p) {}

It is less vague. The problem is you see pointer as input, but it obviously isn't.

Given that we have 'out' for output, and 'inout' for input+output what does that leave?
 Not only that, D set the precedent for new parameter passing syntax  
 with  in/inout/out and you need to break from that to use pointers.

reference) for 2 cases of parameter, that is true. By I do not think that constitutes a precedent, it's simply a better way to handle each of those cases. The same cannot be said for "byref", it's not any _better_ than a pointer.

It is, because pointer doesn't say input.

There is only 1 case where it is needed. Passing a large struct by reference, in this case what else can the use of a pointer mean? A pointer gives a reference to the struct. A reference much like a class reference. So class B {} void foo(B b) {} is 'b' not input? why not? Regan
Feb 18 2006
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Regan Heath wrote:
 On Sat, 18 Feb 2006 12:44:28 +0100, Ivan Senji  
 <ivan.senji_REMOVE_ _THIS__gmail.com> wrote:
 
 Regan Heath wrote:


I'll reply to this post because it is shorter than the other one ;)
 Please elaborate. I don't see how this:
  struct A {}
 void foo(A* p) {}
  is any more or less vague than this:
  struct A {}
 void foo(byref A p) {}

It is less vague. The problem is you see pointer as input, but it obviously isn't.

Given that we have 'out' for output, and 'inout' for input+output what does that leave?

Maybe pointer == input && output && input-output and what ever you want. The good thing about inout is when writing generic code you don't have to know if you are dealing with a class or a struct or array or something else. I am begining to think that byref would also have to mean compiler protecting the data from change, but then it is a C++ const story that Walter doesn't want in D.
 
 Not only that, D set the precedent for new parameter passing syntax  
 with  in/inout/out and you need to break from that to use pointers.

'out' and 'inout' do replace the use of pointers (or passing by reference) for 2 cases of parameter, that is true. By I do not think that constitutes a precedent, it's simply a better way to handle each of those cases. The same cannot be said for "byref", it's not any _better_ than a pointer.

It is, because pointer doesn't say input.

There is only 1 case where it is needed. Passing a large struct by reference, in this case what else can the use of a pointer mean?

It could mean inout-but-i-come-from-c-and-really really like pointers :)
 
 A pointer gives a reference to the struct. A reference much like a 
 class  reference. So
 
 class B {}
 void foo(B b) {}
 
 is 'b' not input? why not?

Yes it is. But if you want a generic method that takes input parameter and write it like that, it means struct will be copyied, if you write it like (B* b) it means uglyfication of code. So conclusion: i have no idea what to do about it? Maybe just use inout in that case and fool everybody into thinking that the function changes something wich it doesn't.
Feb 18 2006
parent "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 18 Feb 2006 23:42:33 +0100, Ivan Senji  
<ivan.senji_REMOVE_ _THIS__gmail.com> wrote:
 Regan Heath wrote:
 On Sat, 18 Feb 2006 12:44:28 +0100, Ivan Senji   
 <ivan.senji_REMOVE_ _THIS__gmail.com> wrote:

 Regan Heath wrote:


I'll reply to this post because it is shorter than the other one ;)

Good idea, we have sort of duplicated the effort in both places :)
 Please elaborate. I don't see how this:
  struct A {}
 void foo(A* p) {}
  is any more or less vague than this:
  struct A {}
 void foo(byref A p) {}

It is less vague. The problem is you see pointer as input, but it obviously isn't.

what does that leave?

Maybe pointer == input && output && input-output and what ever you want.

It can, that is true. I shouldn't because we have 'out' and 'inout'. No guarantees though.
 The good thing about inout is when writing generic code you don't have  
 to know if you are dealing with a class or a struct or array or  
 something else.

Agreed. "byref" would also benefit generic programming for the same reasons. A similar situation in the past resulted in template specialization being added and it should solve this problem also. I can't help but think that "byref" would be more elegant however.
 I am begining to think that byref would also have to mean compiler  
 protecting the data from change, but then it is a C++ const story that  
 Walter doesn't want in D.

Agreed. If "byref" could protect the data I would very much like to see it. In the past I suggested that 'in' default to protecting data to force the use of 'out' and 'inout' where appropriate. That disucssion resulted in the same conclusion, that it would require a fill 'const' like implementation and Walter wasn't ready for that, yet.
 Not only that, D set the precedent for new parameter passing syntax   
 with  in/inout/out and you need to break from that to use pointers.

'out' and 'inout' do replace the use of pointers (or passing by reference) for 2 cases of parameter, that is true. By I do not think that constitutes a precedent, it's simply a better way to handle each of those cases. The same cannot be said for "byref", it's not any _better_ than a pointer.

It is, because pointer doesn't say input.

reference, in this case what else can the use of a pointer mean?

It could mean inout-but-i-come-from-c-and-really really like pointers :)

LOL.. yeah, you can't really guarantee anything can you.
  A pointer gives a reference to the struct. A reference much like a  
 class  reference. So
  class B {}
 void foo(B b) {}
  is 'b' not input? why not?

Yes it is. But if you want a generic method that takes input parameter and write it like that, it means struct will be copyied, if you write it like (B* b) it means uglyfication of code. So conclusion: i have no idea what to do about it? Maybe just use inout in that case and fool everybody into thinking that the function changes something wich it doesn't.

For template programming "byref" would solve this nicely, without it template specialization is required, I guess. Regan
Feb 18 2006
prev sibling parent S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-18 02:34:24 -0800, "Regan Heath" <regan netwin.co.nz> said:

 Please elaborate. I don't see how this:
 
 struct A {}
 void foo(A* p) {}
 
 is any more or less vague than this:
 
 struct A {}
 void foo(byref A p) {}

That's because that's not what I asked for. I asked for something that was InByRef or whatever is agreed upon. Just ByRef Is just as vague.
 
 Not only that, D set the precedent for new parameter passing syntax 
 with  in/inout/out and you need to break from that to use pointers.

'out' and 'inout' do replace the use of pointers (or passing by reference) for 2 cases of parameter, that is true. By I do not think that constitutes a precedent, it's simply a better way to handle each of those cases. The same cannot be said for "byref", it's not any _better_ than a pointer.
 Thirdly D also set a precedent by treating pointers as a new type (D  
 changed declarations so that pointers are with the type rather than the 
  instance now.)

Pointers have always been a distinct type. The change D made was in how the declaration of types is parsed, nothing more.
 Presuming that a int* is a different type

It is.
 , then what you are saying is that you want something other than an int 
  to manipulate. That's untrue though.

I'm not sure what you meant by this statement. Can you re-phrase please.

My argument is that asking for an Type* means you want to work on an Type*. Usually you just want to work on the Type, not actually it's location.
 
 So, when using a pointer in D you are doing a few things.  You are 
 being  vague about what you do to the original value.

Not any more or less vague than a class reference. Both a pointer and a class reference are passed 'in' and you cannot effect their value outside the function call. Therefore the original reference/pointer is safe from manipulation. In neither case is the content of the class/struct safe from manipulation. eg. struct A { int a; } class B { int b; } void foo(A* a) { a.a = 1; } void foo(B b) { b.b = 1; } void main() { A a; B b = new B(); foo(&a); foo(b); } the two cases above are essentially identical, both functions accept a reference to the data type they wish to access, both references are passed 'in'. The only difference is that A is a value type and to get a reference you must use a pointer.

Of course, I'm not arguing about that. I want something that SAYS the structure is still being unmanipulated. Whether walter could implement something like that or not is irrelevant to me.
 
 You also want to deal with a pointer to an int, and not actually an 
 int.  While in some cases this is the case, most of the time all you 
 wanted  was the value.

You have no need of pointers when passing an int: - if you want to read it, you use 'in'. - if you want to write to it, you use 'out'. - if you want to read and write it, you use 'inout'. In what case would you use "byref" with an 'int'? If you want to read, write, or read+write it you'd use one of the existing modes in/out/inout, right?

Of course, which is why my original message used a structure as an example. You are indeed correct that it's useless for an int, since the storage required is the same for a pointer.
 
 Note that you can have parameters of type in that are pointers,  since  
 pointers are associated with variable types, and not passing method.

A pointer _is_ a variable type.

Indeed, which is why i want to define a passing method: "InRef" -S.
Feb 22 2006
prev sibling parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
S. Chancellor wrote:
 In article <op.s44i7ehj6b8z09 ginger.vic.bigpond.net.au>, Derek Parnell says...
 The original poster, I think, was just saying it would be useful to have  
 another option available for those things that are currently passed by  
 value, and that option being that we can specify that instead of being  
 passed by value that we want it to be passed by reference *and* that we  
 don't want to use pointer notation to do that.

Being the original poster, I can say this is almost exactly what I meant! At least someone understands what I was talking about! Also, I was stating not only that we don't want to use pointers, but we also don't want to use inout, because inout means we're going to change the value. -S.

What you want is exactly a "const type &", which means this discussion boils down to the const/readonly/immutable debate (isn't it so?). The failure to realize this sooner, which you haven't still (despite someone mentioning const already) means you've been thinking/discussing the problem under a unclear and/or short-sighted perspective. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Feb 18 2006
parent "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 18 Feb 2006 14:25:03 +0000, Bruno Medeiros  
<daiphoenixNO SPAMlycos.com> wrote:
 S. Chancellor wrote:
 In article <op.s44i7ehj6b8z09 ginger.vic.bigpond.net.au>, Derek Parnell  
 says...
 The original poster, I think, was just saying it would be useful to  
 have  another option available for those things that are currently  
 passed by  value, and that option being that we can specify that  
 instead of being  passed by value that we want it to be passed by  
 reference *and* that we  don't want to use pointer notation to do that.

meant! At least someone understands what I was talking about! Also, I was stating not only that we don't want to use pointers, but we also don't want to use inout, because inout means we're going to change the value. -S.

What you want is exactly a "const type &", which means this discussion boils down to the const/readonly/immutable debate (isn't it so?). The failure to realize this sooner, which you haven't still (despite someone mentioning const already) means you've been thinking/discussing the problem under a unclear and/or short-sighted perspective.

I thought the discussion had reached the point where it was acknowledged that "byref" cannot provide const/readonly protection. (without a lot more being added). But was still being suggested simply as a way to pass a struct by reference with no data protection attempted or guaranteed. Regan
Feb 18 2006
prev sibling next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 18 Feb 2006 02:41:28 +1100, Derek Parnell <derek psych.ward> wrote:
 The original poster, I think, was just saying it would be useful to have  
 another option available for those things that are currently passed by  
 value, and that option being that we can specify that instead of being  
 passed by value that we want it to be passed by reference *and* that we  
 don't want to use pointer notation to do that.

What I want to know is why not use a pointer? A pointer says to me: pass a reference to <thing>. What is wrong with using a pointer? A pointer is no more or less dangerous than a reference in this usage/case. D allows us to access members using '.' so the code looks no different whether a pointer is passed or a reference or a value. I can't see the downside... unless it's simply an aversion to them due to the danger they can represent in other cases typically in C. Regan
Feb 17 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Sat, 18 Feb 2006 14:56:47 +1100, Regan Heath <regan netwin.co.nz> wrote:

 On Sat, 18 Feb 2006 02:41:28 +1100, Derek Parnell <derek psych.ward>  
 wrote:
 The original poster, I think, was just saying it would be useful to  
 have another option available for those things that are currently  
 passed by value, and that option being that we can specify that instead  
 of being passed by value that we want it to be passed by reference  
 *and* that we don't want to use pointer notation to do that.

What I want to know is why not use a pointer?

I'm probably reading into this, but maybe what's being requested is a special sort of pointer. One that allows you to use it to fetch data with, but does not allow to use it to store data. In other words, one that (pretends?) to point to read-only RAM. -- Derek Parnell Melbourne, Australia
Feb 17 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 18 Feb 2006 16:35:40 +1100, Derek Parnell <derek psych.ward> wrote:
 On Sat, 18 Feb 2006 14:56:47 +1100, Regan Heath <regan netwin.co.nz>  
 wrote:

 On Sat, 18 Feb 2006 02:41:28 +1100, Derek Parnell <derek psych.ward>  
 wrote:
 The original poster, I think, was just saying it would be useful to  
 have another option available for those things that are currently  
 passed by value, and that option being that we can specify that  
 instead of being passed by value that we want it to be passed by  
 reference *and* that we don't want to use pointer notation to do that.

What I want to know is why not use a pointer?

I'm probably reading into this, but maybe what's being requested is a special sort of pointer. One that allows you to use it to fetch data with, but does not allow to use it to store data. In other words, one that (pretends?) to point to read-only RAM.

I believe we've been there before and discovered that it's simply not possible to implement this, or rather that Walter could implement C++ "const" but is not happy that C++ "const" actually solves the problem. That a partial solution doesn't cover enough, or not enough for many people. I thought we'd come to that conclusion (again) in this thread. And that "byref" was being proposed regardless. Am I mistaken? If not, my question is simply. What does "byref" add that a pointer does not? because from what I can see it's identical except for the keyword "byref" and the * character in the pointer syntax. To my mind a function taking a pointer, eg. struct A {} void foo(A* ptr) {} says, takes a reference/pointer to an A. Isn't that what "byref" means? void foo(byref A ptr) {} So, if they mean the same thing, and they do the same thing... I prefer the pointer, it's known, it's shorter and easier to type, it exists already. Regan
Feb 17 2006
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 18 Feb 2006 20:18:05 +1300, Regan Heath <regan netwin.co.nz> wrote:
 On Sat, 18 Feb 2006 16:35:40 +1100, Derek Parnell <derek psych.ward>  
 wrote:
 On Sat, 18 Feb 2006 14:56:47 +1100, Regan Heath <regan netwin.co.nz>  
 wrote:

 On Sat, 18 Feb 2006 02:41:28 +1100, Derek Parnell <derek psych.ward>  
 wrote:
 The original poster, I think, was just saying it would be useful to  
 have another option available for those things that are currently  
 passed by value, and that option being that we can specify that  
 instead of being passed by value that we want it to be passed by  
 reference *and* that we don't want to use pointer notation to do that.

What I want to know is why not use a pointer?

I'm probably reading into this, but maybe what's being requested is a special sort of pointer. One that allows you to use it to fetch data with, but does not allow to use it to store data. In other words, one that (pretends?) to point to read-only RAM.

I believe we've been there before and discovered that it's simply not possible to implement this, or rather that Walter could implement C++ "const" but is not happy that C++ "const" actually solves the problem. That a partial solution doesn't cover enough, or not enough for many people. I thought we'd come to that conclusion (again) in this thread. And that "byref" was being proposed regardless. Am I mistaken?

To clarify. My impression of the proposal is that "byref" would cause a value type to be passed by reference and that it would not guarantee or attempt any protection whatsoever. Regan
Feb 17 2006
parent reply S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-02-17 23:20:14 -0800, "Regan Heath" <regan netwin.co.nz> said:

 On Sat, 18 Feb 2006 20:18:05 +1300, Regan Heath <regan netwin.co.nz> wrote:
 On Sat, 18 Feb 2006 16:35:40 +1100, Derek Parnell <derek psych.ward>  wrote:
 On Sat, 18 Feb 2006 14:56:47 +1100, Regan Heath <regan netwin.co.nz>  wrote:
 
 On Sat, 18 Feb 2006 02:41:28 +1100, Derek Parnell <derek psych.ward>  wrote:
 The original poster, I think, was just saying it would be useful to  
 have another option available for those things that are currently  
 passed by value, and that option being that we can specify that  
 instead of being passed by value that we want it to be passed by  
 reference *and* that we don't want to use pointer notation to do that.

What I want to know is why not use a pointer?

I'm probably reading into this, but maybe what's being requested is a special sort of pointer. One that allows you to use it to fetch data with, but does not allow to use it to store data. In other words, one that (pretends?) to point to read-only RAM.

I believe we've been there before and discovered that it's simply not possible to implement this, or rather that Walter could implement C++ "const" but is not happy that C++ "const" actually solves the problem. That a partial solution doesn't cover enough, or not enough for many people. I thought we'd come to that conclusion (again) in this thread. And that "byref" was being proposed regardless. Am I mistaken?

To clarify. My impression of the proposal is that "byref" would cause a value type to be passed by reference and that it would not guarantee or attempt any protection whatsoever.

That is correct. That's not to say that protections would be unwelcomed if they were implementable, or good ones could be defined. -S.
Feb 18 2006
parent "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 18 Feb 2006 00:01:37 -0800, S. Chancellor  
<dnewsgr mephit.kicks-ass.org> wrote:
 On 2006-02-17 23:20:14 -0800, "Regan Heath" <regan netwin.co.nz> said:

 On Sat, 18 Feb 2006 20:18:05 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:
 On Sat, 18 Feb 2006 16:35:40 +1100, Derek Parnell <derek psych.ward>   
 wrote:
 On Sat, 18 Feb 2006 14:56:47 +1100, Regan Heath <regan netwin.co.nz>   
 wrote:

 On Sat, 18 Feb 2006 02:41:28 +1100, Derek Parnell  
 <derek psych.ward>  wrote:
 The original poster, I think, was just saying it would be useful  
 to  have another option available for those things that are  
 currently  passed by value, and that option being that we can  
 specify that  instead of being passed by value that we want it to  
 be passed by  reference *and* that we don't want to use pointer  
 notation to do that.


a special sort of pointer. One that allows you to use it to fetch data with, but does not allow to use it to store data. In other words, one that (pretends?) to point to read-only RAM.

not possible to implement this, or rather that Walter could implement C++ "const" but is not happy that C++ "const" actually solves the problem. That a partial solution doesn't cover enough, or not enough for many people. I thought we'd come to that conclusion (again) in this thread. And that "byref" was being proposed regardless. Am I mistaken?

a value type to be passed by reference and that it would not guarantee or attempt any protection whatsoever.

That is correct. That's not to say that protections would be unwelcomed if they were implementable, or good ones could be defined.

Thanks for clarifying. Lets continue in the other 2 threads. Regan
Feb 18 2006
prev sibling parent reply "Derek Parnell" <derek psych.ward> writes:
On Sat, 18 Feb 2006 18:18:05 +1100, Regan Heath <regan netwin.co.nz> wrote:

[snip]

 To my mind a function taking a pointer, eg.

 struct A {}
 void foo(A* ptr) {}

 says, takes a reference/pointer to an A. Isn't that what "byref" means?

 void foo(byref A ptr) {}

 So, if they mean the same thing, and they do the same thing... I prefer  
 the pointer, it's known, it's shorter and easier to type, it exists  
 already.

The only difference I can suggest is that by using a pointer you are telling the compiler that any type of access to the referred to data is ok, but 'byref' could be saying that any attempt to change the data referred to is a mistake. The 'byref' is sugar for a pointer, true. But it adds to the compiler's understanding of the coder's intentions, namely that if the code uses 'ptr' to change the data then issue a message because it means that the coder has just made a coding mistake. The 'byref' idea can add value to the language. -- Derek Parnell Melbourne, Australia
Feb 18 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 18 Feb 2006 23:15:10 +1100, Derek Parnell <derek psych.ward> wrote:
 On Sat, 18 Feb 2006 18:18:05 +1100, Regan Heath <regan netwin.co.nz>  
 wrote:

 [snip]

 To my mind a function taking a pointer, eg.

 struct A {}
 void foo(A* ptr) {}

 says, takes a reference/pointer to an A. Isn't that what "byref" means?

 void foo(byref A ptr) {}

 So, if they mean the same thing, and they do the same thing... I prefer  
 the pointer, it's known, it's shorter and easier to type, it exists  
 already.

The only difference I can suggest is that by using a pointer you are telling the compiler that any type of access to the referred to data is ok, but 'byref' could be saying that any attempt to change the data referred to is a mistake. The 'byref' is sugar for a pointer, true. But it adds to the compiler's understanding of the coder's intentions, namely that if the code uses 'ptr' to change the data then issue a message because it means that the coder has just made a coding mistake. The 'byref' idea can add value to the language.

If data protection is added then I agree wholeheartedly. But at this stage we cannot be sure it will be, or even that it will take a form that can use "byref", so adding it might result in "another way to do the same thing" and nothing more, that is my concern. Regan
Feb 18 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Sun, 19 Feb 2006 08:26:47 +1100, Regan Heath <regan netwin.co.nz> wrote:

 On Sat, 18 Feb 2006 23:15:10 +1100, Derek Parnell <derek psych.ward>  
 wrote:
 On Sat, 18 Feb 2006 18:18:05 +1100, Regan Heath <regan netwin.co.nz>  
 wrote:

 [snip]

 To my mind a function taking a pointer, eg.

 struct A {}
 void foo(A* ptr) {}

 says, takes a reference/pointer to an A. Isn't that what "byref" means?

 void foo(byref A ptr) {}

 So, if they mean the same thing, and they do the same thing... I  
 prefer the pointer, it's known, it's shorter and easier to type, it  
 exists already.

The only difference I can suggest is that by using a pointer you are telling the compiler that any type of access to the referred to data is ok, but 'byref' could be saying that any attempt to change the data referred to is a mistake. The 'byref' is sugar for a pointer, true. But it adds to the compiler's understanding of the coder's intentions, namely that if the code uses 'ptr' to change the data then issue a message because it means that the coder has just made a coding mistake. The 'byref' idea can add value to the language.

If data protection is added then I agree wholeheartedly. But at this stage we cannot be sure it will be, or even that it will take a form that can use "byref", so adding it might result in "another way to do the same thing" and nothing more, that is my concern.

You seem to be saying that unless, and until, D can absolutely guarantee data protection then there is no value in trying to have the compiler also (in addition) detect coding mistakes of the type where the coder has expressed her desire to not attempt to change the data owned by a passed parameter, but due to an honest mistake, her code actually contains a construct that attempts to do just that *and* the compiler can detect that. (Sheesh! That has got to be the longest sentence I've ever written! <g>) If this is so, then I must register my total disagreement. I hold to the idea that a major part of any compiler's job is to make life easier for coders. One obvious way it can do that is to highlight code that is contrary to the coder's stated intentions. The 'byref' idea could be used to declare that the intention of the coder is to not modify the parameter's data. This is very different to having the compiler make sure that every possible method of data protection is blocked. I'm just and only talking about explicit attempts to modify 'byref' parameter data. Such attempts mean that either the 'byref' was a mistake to add or that the code is a mistake - either way the coder is helped. -- Derek Parnell Melbourne, Australia
Feb 18 2006
next sibling parent Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Derek Parnell wrote:
 On Sun, 19 Feb 2006 08:26:47 +1100, Regan Heath <regan netwin.co.nz> wrote:
 
 On Sat, 18 Feb 2006 23:15:10 +1100, Derek Parnell <derek psych.ward>  
 wrote:

 On Sat, 18 Feb 2006 18:18:05 +1100, Regan Heath <regan netwin.co.nz>  
 wrote:

 [snip]

 To my mind a function taking a pointer, eg.

 struct A {}
 void foo(A* ptr) {}

 says, takes a reference/pointer to an A. Isn't that what "byref" means?

 void foo(byref A ptr) {}

 So, if they mean the same thing, and they do the same thing... I  
 prefer the pointer, it's known, it's shorter and easier to type, it  
 exists already.

The only difference I can suggest is that by using a pointer you are telling the compiler that any type of access to the referred to data is ok, but 'byref' could be saying that any attempt to change the data referred to is a mistake. The 'byref' is sugar for a pointer, true. But it adds to the compiler's understanding of the coder's intentions, namely that if the code uses 'ptr' to change the data then issue a message because it means that the coder has just made a coding mistake. The 'byref' idea can add value to the language.

If data protection is added then I agree wholeheartedly. But at this stage we cannot be sure it will be, or even that it will take a form that can use "byref", so adding it might result in "another way to do the same thing" and nothing more, that is my concern.

You seem to be saying that unless, and until, D can absolutely guarantee data protection then there is no value in trying to have the compiler also (in addition) detect coding mistakes of the type where the coder has expressed her desire to not attempt to change the data owned by a passed parameter, but due to an honest mistake, her code actually contains a construct that attempts to do just that *and* the compiler can detect that. (Sheesh! That has got to be the longest sentence I've ever written! <g>) If this is so, then I must register my total disagreement. I hold to the idea that a major part of any compiler's job is to make life easier for coders. One obvious way it can do that is to highlight code that is contrary to the coder's stated intentions. The 'byref' idea could be used to declare that the intention of the coder is to not modify the parameter's data. This is very different to having the compiler make sure that every possible method of data protection is blocked. I'm just and only talking about explicit attempts to modify 'byref' parameter data. Such attempts mean that either the 'byref' was a mistake to add or that the code is a mistake - either way the coder is helped.

That feature would be nice to have, but unlikely to happen. Byref thing realistcally can only be the same thing as inout but used when you wan't input params. Or a better solution to rename inout to 'ref' to capture both meanings or document inout better so that it is explained that it actually means input-by-ref or inout. Data protection probably will remain a distant dream.
Feb 18 2006
prev sibling parent "Regan Heath" <regan netwin.co.nz> writes:
On Sun, 19 Feb 2006 08:47:21 +1100, Derek Parnell <derek psych.ward> wrote:
 On Sun, 19 Feb 2006 08:26:47 +1100, Regan Heath <regan netwin.co.nz>  
 wrote:

 On Sat, 18 Feb 2006 23:15:10 +1100, Derek Parnell <derek psych.ward>  
 wrote:
 On Sat, 18 Feb 2006 18:18:05 +1100, Regan Heath <regan netwin.co.nz>  
 wrote:

 [snip]

 To my mind a function taking a pointer, eg.

 struct A {}
 void foo(A* ptr) {}

 says, takes a reference/pointer to an A. Isn't that what "byref"  
 means?

 void foo(byref A ptr) {}

 So, if they mean the same thing, and they do the same thing... I  
 prefer the pointer, it's known, it's shorter and easier to type, it  
 exists already.

The only difference I can suggest is that by using a pointer you are telling the compiler that any type of access to the referred to data is ok, but 'byref' could be saying that any attempt to change the data referred to is a mistake. The 'byref' is sugar for a pointer, true. But it adds to the compiler's understanding of the coder's intentions, namely that if the code uses 'ptr' to change the data then issue a message because it means that the coder has just made a coding mistake. The 'byref' idea can add value to the language.

If data protection is added then I agree wholeheartedly. But at this stage we cannot be sure it will be, or even that it will take a form that can use "byref", so adding it might result in "another way to do the same thing" and nothing more, that is my concern.

You seem to be saying that unless, and until, D can absolutely guarantee data protection then there is no value in trying to have the compiler also (in addition) detect coding mistakes of the type where the coder has expressed her desire to not attempt to change the data owned by a passed parameter, but due to an honest mistake, her code actually contains a construct that attempts to do just that *and* the compiler can detect that. (Sheesh! That has got to be the longest sentence I've ever written! <g>)

:) I suspect for the compiler to detect the attempt to change it, a partial or complete 'const' like solution would have to be added. I don't think detecting an attempt to change it is easy, and I think that there may even be some cases which are impossible to detect (the same param passed twice, and/or several levels of indirection). Resulting in a system that works "most of the time". Such a system might be of benefit, but I don't think Walter is convinced, I suspect he is hoping to come up with a solution that can provide a real guarantee. In the meantime adding another method to pass a reference to a struct without any attempt at data protection seems to me to be "another way to do the same thing" and I don't really see the point. Although.. Ivan did point out that it would be useful in generic programming and I agree there.
 If this is so, then I must register my total disagreement. I hold to the  
 idea that a major part of any compiler's job is to make life easier for  
 coders.

I agree completely.
 One obvious way it can do that is to highlight code that is contrary to  
 the coder's stated intentions.

I agree completely.
 The 'byref' idea could be used to declare that the intention of the  
 coder is to not modify the parameter's data.

Currently 'in' serves that purpose. I believe the default passing method should be readonly. So, rather than "byref" I would like 'in' to enforce whatever data protection we eventually have. However there is still the problem of seperating the 'reference' from the 'data' itself and being able to apply the usage to each part seperately, i.e. "not going to modify the referece, will modify the data" vs "not going to modify the reference or the data" etc. Without some way to do that we're stuck passing class references as 'in' and it's not obvious what that means, or if it even means the same thing to everyone.
 This is very different to having the compiler make sure that every  
 possible method of data protection is blocked. I'm just and only talking  
 about explicit attempts to modify 'byref' parameter data. Such attempts  
 mean that either the 'byref' was a mistake to add or that the code is a  
 mistake - either way the coder is helped.

Such a solution would only catch things some percentage of the time, perhaps it's a large percentage, not sure. I think we'd all prefer a guaranteed method, if possible, it may not be. Either way it's (as always) in Walters hands. Regan
Feb 18 2006
prev sibling parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Derek Parnell wrote:
 On Sat, 18 Feb 2006 01:28:01 +1100, Bruno Medeiros
 <daiphoenixNO SPAMlycos.com> wrote:

 Derek Parnell wrote:
 This topic doesn't warrant further consideration.

comment relevant.

Because we, and others, have been saying the same things over and over again without resolution or advancement. None of these discussions is going to change D. The 'in' qualifier [...]

actually related to this thread's topic. [...]
 And also: *all* variables in D are by default passed by value, 
 including classes and arrays. What happens is that they are reference 
 values. This   conceptualization may look similar, but it's not, and 
 it's a very important notion to have.

That is very wrong. When passing a class instance, the data which is owned by that object is not passed (its value) but as you say, an address of a RAM structure that represents the object is passed (its reference). The 'reference' is not the 'value'. When passing an array, the bits that go in into making the value of the data that is owned by the array is not passed (its value) but an address of an 8-byte structure (in the case of variable length arrays) or the address of the data (in the case of fixed length arrays) is passed (its reference). The 'reference' is not the 'value'.

divergence lies only in the terminology, see below:
 So, some things are passed by reference (which is not its value) and 
 some things are passed by value (which is not its reference).
 

not it's referenced data, but it's reference/pointer itself. I.e. the value of a class variable is it's reference, not it's referenced instance data. .NET Common Type System Overview : http://msdn.microsoft.com/library/en-us/cpguide/html/cpconcommontypesystemoverview.asp "Values are binary representations of data, and types provide a way of interpreting this data. A value type is stored directly as a binary representation of the type's data. The value of a reference type is the location of the sequence of bits that represent the type's data." Java Types, Values, and Variables: http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html "The types of the Java programming language are divided into two categories: primitive types and reference types. [...] An object (§4.3.1) is a dynamically created instance of a class type or a dynamically created array. The values of a reference type are references to objects." In C++ the reference types are all explicit pointers, so it is more clear what the values of the types are. This is the standard definition for a good reason. It is a more simple/symmetric/orthogonal one (although the terminology is still quite tricky). It allows one to say that assignments work on the variable's value, for any type. It allows one to say that all variables/parameters in D (or any C-family language) are by default passed by value (or called-by-value). And conversely that "inout" or "out" in D, "type &" in C++, "ref" and "out" in C# make a parameter passed by reference (or called-by-reference). (http://en.wikipedia.org/wiki/Call_by_reference#Call_by_value) (http://en.wikipedia.org/wiki/Call_by_reference#Call_by_reference) So, looking back at what you said before, that class instance data(aka object data) is passed by reference. In a way it is right in that it is "... by reference" but the problem is that a class instance data is not "passed" at all. There are no variables types (and thus no parameters) of the kind "class instance data" (unlike C++). There are only reference types, which, like all other variables are passed by value. It's a tricky duality. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Feb 18 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Sun, 19 Feb 2006 04:29:50 +1100, Bruno Medeiros  
<daiphoenixNO SPAMlycos.com> wrote:


[snip]

 Here is the main point of contention. The value of a reference type is  
 not it's referenced data, but it's reference/pointer itself. I.e. the  
 value of a class variable is it's reference, not it's referenced  
 instance data.

 .NET Common Type System Overview :
 http://msdn.microsoft.com/library/en-us/cpguide/html/cpconcommontypesystemoverview.asp
 "Values are binary representations of data, and types provide a way of  
 interpreting this data. A value type is stored directly as a binary  
 representation of the type's data. The value of a reference type is the  
 location of the sequence of bits that represent the type's data."

 Java Types, Values, and Variables:
 http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html
 "The types of the Java programming language are divided into two  
 categories: primitive types and reference types. [...] An object  
 (§4.3.1) is a dynamically created instance of a class type or a  
 dynamically created array. The values of a reference type are references  
 to objects."

Welcome to the world of Alice. It seems that the good and intelligent people at Microsoft and Sun and taken perfectly good English word and redefined it to make it easier to sell their product. It like I gave you an ISBN and told you that I've really given you the book. Ok, assuming their perverted definition of 'value', it boils down to saying that when passing parameters to a function, the function is getting something that enables the function to access the parameter's data. Really? Who would have guessed that! Well, I'm afraid I'm continue to be a rebel and refuse to bow down to these mighty organisations and their mock-turtles.
 In C++ the reference types are all explicit pointers, so it is more  
 clear what the values of the types are.

 This is the standard definition for a good reason. It is a more  
 simple/symmetric/orthogonal one (although the terminology is still quite  
 tricky).

And by 'tricky' you mean 'stupid' right?
 It allows one to say that assignments work on the variable's value, for  
 any type. It allows one to say that all variables/parameters in D (or  
 any C-family language) are by default passed by value (or  
 called-by-value).

Yes, the redefined meaning of 'value' does allow one to say this. But what is gained by being so 'clever'.
 And conversely that  "inout" or "out" in D, "type &" in C++, "ref" and  
 "out" in C# make a parameter passed by reference (or  
 called-by-reference).
 (http://en.wikipedia.org/wiki/Call_by_reference#Call_by_value)
 (http://en.wikipedia.org/wiki/Call_by_reference#Call_by_reference)

 So, looking back at what you said before, that class instance data(aka  
 object data) is passed by reference. In a way it is right in that it is  
 "... by reference" but the problem is that a class instance data is not  
 "passed" at all. There are no variables types (and thus no parameters)  
 of the kind "class instance data" (unlike C++). There are only reference  
 types, which, like all other variables are passed by value.

 It's a tricky duality.

If one passes the address of an int to a function, is it passing a reference or value or data or what? Dumb question, no? -- Derek Parnell Melbourne, Australia
Feb 18 2006
next sibling parent Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Derek Parnell wrote:
 If one passes the address of an int to a function, is it passing a  
 reference or value or data or what? Dumb question, no?

It is passing a pointer to int by value, and passing an int by reference at the same time. :)
Feb 18 2006
prev sibling parent Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Derek Parnell wrote:
 On Sun, 19 Feb 2006 04:29:50 +1100, Bruno Medeiros
 <daiphoenixNO SPAMlycos.com> wrote:

 In C++ the reference types are all explicit pointers, so it is more
 clear what the values of the types are.

 This is the standard definition for a good reason. It is a more
 simple/symmetric/orthogonal one (although the terminology is still
 quite tricky).

And by 'tricky' you mean 'stupid' right?

 If one passes the address of an int to a function, is it passing a
 reference or value or data or what? Dumb question, no?

 --Derek Parnell
 Melbourne, Australia

 
 
 [snip]
 
 Here is the main point of contention. The value of a reference type is 
 not it's referenced data, but it's reference/pointer itself. I.e. the 
 value of a class variable is it's reference, not it's referenced 
 instance data.

 .NET Common Type System Overview :
 http://msdn.microsoft.com/library/en-us/cpguide/html/cpconcommonty
esystemoverview.asp 

 "Values are binary representations of data, and types provide a way of 
 interpreting this data. A value type is stored directly as a binary 
 representation of the type's data. The value of a reference type is 
 the location of the sequence of bits that represent the type's data."

 Java Types, Values, and Variables:
 http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html 

 "The types of the Java programming language are divided into two 
 categories: primitive types and reference types. [...] An object 
 (§4.3.1) is a dynamically created instance of a class type or a 
 dynamically created array. The values of a reference type are 
 references to objects."

Welcome to the world of Alice. It seems that the good and intelligent people at Microsoft and Sun and taken perfectly good English word and redefined it to make it easier to sell their product. It like I gave you an ISBN and told you that I've really given you the book. Ok, assuming their perverted definition of 'value', it boils down to saying that when passing parameters to a function, the function is getting something that enables the function to access the parameter's data. Really? Who would have guessed that! Well, I'm afraid I'm continue to be a rebel and refuse to bow down to these mighty organizations and their mock-turtles.

Perverted definition of 'value'? That's very subjective and very arguable, and I disagree with it. I think the Java and C# engineers chose the appropriate definition, regardless of corporate interests (uh... in fact, how does a 'perverted' definition of value makes it any easier to sell their products at all?..). *Actually*, saying they "chose" is misleading, because this is something that just immediately and naturally follows from the C/C++ language roots, and thus not even related to any possible corporate greediness. Indeed, and I regret not having remembered this earlier, in Kernighan and Ritchie's "The C Programming Language", it is said, is the first paragraph of page 99, that "By definition, the value of a variable or expression of type array is the address of element zero of the array.", so there ya go. Anyway, I'm starting to get bit dizzy now. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Feb 24 2006