www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Ref and class function calls?

reply "Tofu Ninja" <emmons0 purdue.edu> writes:
I could not think of what to call this because I don't know if it 
has a name to call it by.

Basicly what I was wondering is if their was a way in D to make a 
class function pass the object being called on by reference.

might be easier to show code, basically I want something like 
this to be possible

class A
{
      //some how signify that this function passes 'this' by 
reference
      public void replace()
      {
           this = new A();
      }
}

...

A a = new A();
A b = a;
b.replace();
assert(b != a);

I don't know if I am being clear or if their is something better 
to call this.

Thanks for the help
Tofu
Apr 15 2013
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 16 April 2013 at 05:37:48 UTC, Tofu Ninja wrote:
 I could not think of what to call this because I don't know if 
 it has a name to call it by.

 Basicly what I was wondering is if their was a way in D to make 
 a class function pass the object being called on by reference.

 might be easier to show code, basically I want something like 
 this to be possible

 class A
 {
      //some how signify that this function passes 'this' by 
 reference
      public void replace()
      {
           this = new A();
      }
 }

 ...

 A a = new A();
 A b = a;
 b.replace();
 assert(b != a);

 I don't know if I am being clear or if their is something 
 better to call this.

 Thanks for the help
 Tofu
A member function cannot modify it's own 'this' pointer. However, a free function can do it happily, which when combined with UFCS gives you the same syntax and behaviour: class A { //...... } void replace(ref A a) { a = new A(); } void main() { A a = new A(); A b = a; assert(b is a); b.replace(); assert(!(b is a)); } http://dpaste.dzfl.pl/147f69e1
Apr 16 2013
next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 16 April 2013 at 14:33:21 UTC, John Colvin wrote:
 A member function cannot modify it's own 'this' pointer.

 However, a free function can do it happily, which when combined 
 with UFCS gives you the same syntax and behaviour:

 class A {
 	//......
 }

 void replace(ref A a)
 {
 	a = new A();
 }

 void main() {
 	A a = new A();
 	A b = a;
 	assert(b is a);
 	b.replace();
 	assert(!(b is a));
 }

 http://dpaste.dzfl.pl/147f69e1
Alternatively, if you don't actually need it to be a completely seperate new object, just re-initialised, you can just call this() inside a member function. E.g. class A { public void replace() { this(); } }
Apr 16 2013
prev sibling parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
On Tuesday, 16 April 2013 at 14:33:21 UTC, John Colvin wrote:
 A member function cannot modify it's own 'this' pointer.

 However, a free function can do it happily, which when combined 
 with UFCS gives you the same syntax and behaviour:

 class A {
 	//......
 }

 void replace(ref A a)
 {
 	a = new A();
 }

 void main() {
 	A a = new A();
 	A b = a;
 	assert(b is a);
 	b.replace();
 	assert(!(b is a));
 }

 http://dpaste.dzfl.pl/147f69e1
Yes... this is what I feared. I knew I could do it like that but I was hoping a more elegant solution was available, seems like bad design to have a function that is fully intended to be a class function but not actually be able to declare it within the class block.
Apr 16 2013
next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 16 April 2013 at 14:57:11 UTC, Tofu Ninja wrote:
 On Tuesday, 16 April 2013 at 14:33:21 UTC, John Colvin wrote:
 A member function cannot modify it's own 'this' pointer.

 However, a free function can do it happily, which when 
 combined with UFCS gives you the same syntax and behaviour:

 class A {
 	//......
 }

 void replace(ref A a)
 {
 	a = new A();
 }

 void main() {
 	A a = new A();
 	A b = a;
 	assert(b is a);
 	b.replace();
 	assert(!(b is a));
 }

 http://dpaste.dzfl.pl/147f69e1
Yes... this is what I feared. I knew I could do it like that but I was hoping a more elegant solution was available, seems like bad design to have a function that is fully intended to be a class function but not actually be able to declare it within the class block.
I would argue that it is better as a separate function. Having a member function that reassigns 'this' seems a long way from least-surprise (although with UFCS the user might be none the wiser anyway).
Apr 16 2013
prev sibling next sibling parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Tue, 16 Apr 2013 15:57:09 +0100, Tofu Ninja <emmons0 purdue.edu> wrote:

 On Tuesday, 16 April 2013 at 14:33:21 UTC, John Colvin wrote:
 A member function cannot modify it's own 'this' pointer.

 However, a free function can do it happily, which when combined with  
 UFCS gives you the same syntax and behaviour:

 class A {
 	//......
 }

 void replace(ref A a)
 {
 	a = new A();
 }

 void main() {
 	A a = new A();
 	A b = a;
 	assert(b is a);
 	b.replace();
 	assert(!(b is a));
 }

 http://dpaste.dzfl.pl/147f69e1
Yes... this is what I feared. I knew I could do it like that but I was hoping a more elegant solution was available, seems like bad design to have a function that is fully intended to be a class function but not actually be able to declare it within the class block.
I would question always question "fully intended" on a case by case basis: http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197 I agree that grouping functions together that should be used together, or on the same type of object is a good idea from an organisational point of view but that shouldn't be the only reason for making them class member functions. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Apr 16 2013
parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
On Tuesday, 16 April 2013 at 15:23:56 UTC, Regan Heath wrote:
 I would question always question "fully intended" on a case by 
 case basis:
 http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197

 I agree that grouping functions together that should be used 
 together, or on the same type of object is a good idea from an 
 organisational point of view but that shouldn't be the only 
 reason for making them class member functions.

 R
I think a lot of people give too much credit to encapsulation. I mean don't get me wrong its cool and all and it has its place, but it seems like some people make it seem a lot more important than it really is. I mean having lots of encapsulation really doesn't do anything for your program, it won't run faster or do more things. If any thing, more often than not, it makes things run slower, as you can't see what's in the black box. Thats just my opinion on the whole thing... I am actually hesitant to post this because I don't want to start a debate over encapsulation.... I really hope i don't start a debate...
Apr 16 2013
parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Tue, 16 Apr 2013 18:51:06 +0100, Tofu Ninja <emmons0 purdue.edu> wrote:

 On Tuesday, 16 April 2013 at 15:23:56 UTC, Regan Heath wrote:
 I would question always question "fully intended" on a case by case  
 basis:
 http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197

 I agree that grouping functions together that should be used together,  
 or on the same type of object is a good idea from an organisational  
 point of view but that shouldn't be the only reason for making them  
 class member functions.

 R
I think a lot of people give too much credit to encapsulation. I mean don't get me wrong its cool and all and it has its place, but it seems like some people make it seem a lot more important than it really is. I mean having lots of encapsulation really doesn't do anything for your program, it won't run faster or do more things. If any thing, more often than not, it makes things run slower, as you can't see what's in the black box. Thats just my opinion on the whole thing...
True, but this is what I'd call a short term view of encapsulation and code quality. Thinking about encapsulation in the short term is important because it forces you to properly design things for the long term. If you don't care at all about encapsulation (or orthogonality) you probably wont bother to actually define the interface between two potentially orthogonal pieces of code. If there is no separation "designed in" to start with then code tends to tie itself together in sometimes surprising ways typically creating unintended dependencies or complexity. Essentially the code becomes harder to reason about, harder to change and therefore harder to improve. So, ultimately encapsulation (one aspect of good design) should lead to code which is better in every measurable way, including running faster. Sure, there will be the odd case where encapsulation decreases performance, in those cases I would take the practical route of breaking encapsulation to solve the issue. In short, encapsulation is important and useful but not paramount. :) R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Apr 17 2013
next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Wed, 17 Apr 2013 12:02:25 +0100, Regan Heath <regan netmail.co.nz>  
wrote:
 So, ultimately encapsulation (one aspect of good design) should lead to  
 code which is better in every measurable way, including running faster.
It may not have been 100% clear what I was implying here. Because encapsulation makes the code easier to reason about, it makes it easier to change, and improve. Therefore, it's easier to improve the performance of the code. That, plus the idea that you can and should break encapsulation for a higher priority concern - which may be performance for example - mean that encapsulation should not negatively impact any code base. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Apr 17 2013
prev sibling parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
On Wednesday, 17 April 2013 at 11:02:24 UTC, Regan Heath wrote:
 True, but this is what I'd call a short term view of 
 encapsulation and code quality.

 Thinking about encapsulation in the short term is important 
 because it forces you to properly design things for the long 
 term.  If you don't care at all about encapsulation (or 
 orthogonality) you probably wont bother to actually define the 
 interface between two potentially orthogonal pieces of code.

 If there is no separation "designed in" to start with then code 
 tends to tie itself together in sometimes surprising ways 
 typically creating unintended dependencies or complexity.  
 Essentially the code becomes harder to reason about, harder to 
 change and therefore harder to improve.

 So, ultimately encapsulation (one aspect of good design) should 
 lead to code which is better in every measurable way, including 
 running faster.  Sure, there will be the odd case where 
 encapsulation decreases performance, in those cases I would 
 take the practical route of breaking encapsulation to solve the 
 issue.  In short, encapsulation is important and useful but not 
 paramount.

 :)

 R
You misunderstand me, I think encapsulation is great and important, but just not as great and important as a lot of people seem to think. I agree that encapsulation has a lot of good qualities, but i also think it would be a little naive to say that it doesn't have some bad qualities as well. All i am going to say... really doesn't have much to do with the thread.
Apr 17 2013
parent "Regan Heath" <regan netmail.co.nz> writes:
On Wed, 17 Apr 2013 12:17:03 +0100, Tofu Ninja <emmons0 purdue.edu> wrote:

 On Wednesday, 17 April 2013 at 11:02:24 UTC, Regan Heath wrote:
 True, but this is what I'd call a short term view of encapsulation and  
 code quality.

 Thinking about encapsulation in the short term is important because it  
 forces you to properly design things for the long term.  If you don't  
 care at all about encapsulation (or orthogonality) you probably wont  
 bother to actually define the interface between two potentially  
 orthogonal pieces of code.

 If there is no separation "designed in" to start with then code tends  
 to tie itself together in sometimes surprising ways typically creating  
 unintended dependencies or complexity.  Essentially the code becomes  
 harder to reason about, harder to change and therefore harder to  
 improve.

 So, ultimately encapsulation (one aspect of good design) should lead to  
 code which is better in every measurable way, including running  
 faster.  Sure, there will be the odd case where encapsulation decreases  
 performance, in those cases I would take the practical route of  
 breaking encapsulation to solve the issue.  In short, encapsulation is  
 important and useful but not paramount.

 :)

 R
You misunderstand me, I think encapsulation is great and important, but just not as great and important as a lot of people seem to think.
No, I got all that :) My point was that it can in fact make your program run faster, indirectly. :P R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Apr 17 2013
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 04/16/2013 07:57 AM, Tofu Ninja wrote:

 seems like bad design to
 have a function that is fully intended to be a class function but not
 actually be able to declare it within the class block.
It would be bad design if a class variable decided to refer to another object without the owner of that variable knowing about it. I think the most accurate reason why this is not possible is that the 'this' reference inside a member function is just a local class variable (or "handle"). If you could make it refer to a new object, then only that local reference would be affected and the outside variable would not know about it. Ali
Apr 16 2013
parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
On Tuesday, 16 April 2013 at 15:27:10 UTC, Ali Çehreli wrote:
 On 04/16/2013 07:57 AM, Tofu Ninja wrote:
 It would be bad design if a class variable decided to refer to 
 another object without the owner of that variable knowing about 
 it.
I don't know, It seems like the caller of the function should know what he/she is calling. I don't make practice of calling a function with out knowing what it will do first, the caller should know that their is a chance the variable would be reassigned if its a 'ref this function'. The same thing can be said about normal ref arguments. The caller knows that if they pass a variable into a function that has a ref argument, then there's a chance that the variable will be reassigned. Its the responsibility of the caller to know what they are calling and what might happen because of it. And their are plenty of cases that a 'ref this function' is desirable. Simple example, a linked list head with a push function. It reassigns the head variable to what you are pushing and chains the rest after it. It makes logical sense to be able to do head.push(...) and it makes sense for this to be a class function. Tofu
Apr 16 2013
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 04/16/2013 08:44 AM, Tofu Ninja wrote:

 On Tuesday, 16 April 2013 at 15:27:10 UTC, Ali Çehreli wrote:
 On 04/16/2013 07:57 AM, Tofu Ninja wrote:
 It would be bad design if a class variable decided to refer to another
 object without the owner of that variable knowing about it.
I don't know, It seems like the caller of the function should know what he/she is calling. I don't make practice of calling a function with out knowing what it will do first, the caller should know that their is a chance the variable would be reassigned if its a 'ref this function'.
You are right. I think the problem then is that 'this' is yet another handle to the object. Changing it wouldn't make any effect on the outside world: auto a = new Class(); auto b = a; // now two handles b.foo(); // let's assume that foo can assign to 'this' When that happens, would you expect a and b also become handles to the new object? It could I guess, but it sounds impractical in a system language. The runtime does not maintain a record of what handles share the same object.
 The same thing can be said about normal ref arguments. The caller knows
 that if they pass a variable into a function that has a ref argument,
 then there's a chance that the variable will be reassigned. Its the
 responsibility of the caller to know what they are calling and what
 might happen because of it.
Agreed.
 And their are plenty of cases that a 'ref this function' is desirable.
 Simple example, a linked list head with a push function. It reassigns
 the head variable to what you are pushing and chains the rest after it.
What happens to other references to the old head? Do they continue pointing at the neck? Maybe that is understandable...
 It makes logical sense to be able to do head.push(...)
I can't see it that way yet.
 and it makes
 sense for this to be a class function.
And it wouldn't make sense if it were a non-member function? If so, I don't see it yet.
 Tofu
Ali
Apr 16 2013
parent "Tofu Ninja" <emmons0 purdue.edu> writes:
On Tuesday, 16 April 2013 at 21:14:16 UTC, Ali Çehreli wrote:
 On 04/16/2013 08:44 AM, Tofu Ninja wrote:
 When that happens, would you expect a and b also become handles 
 to the new object? It could I guess, but it sounds impractical 
 in a system language. The runtime does not maintain a record of 
 what handles share the same object.
No, I wouldn't expect a to change. If I did b.replace() I would only expect b to be changed, a would still be pointing back at the original object.
Apr 16 2013