www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Copy by value semantics

reply Arcane Jill <Arcane_member pathlink.com> writes:
One final(ish) push for :=

I have suggested that "a := b;" be rewritten by the compiler as "a = new A(b)".
I'm told that this would be merely syntactic sugar.

Well yeah, it is. But the phrase "syntactic sugar" is a loaded phrase, implying
"bad thing". The fact is that we can write "a = b + c" instead of "a =
b.opAdd(c)", and we LIKE it. Syntactic sugar is sometimes nice.

It's a very simple idea:

       a = b;      // copy by reference
       a := b;     // copy by value

This syntactic sugar would ALSO allow you to things like:
       Int n := 5;

(Int is my big integer class) instead of:
       Int n = new Int(5);

That sugary code is much more /smooth/. It /flows/. If no-one likes this idea, I'll drop it, but realise that this would also work for arrays. That is, if a and b are arrays, then
       a := b;

would be equivalent to:
       a.length = b.length;
       a[] = b[];

And as for structs, there would be no harm in allowing structs to have constructors (but not destructors), so it could work for them too. Arcane Jill (throwing caution to the wind).
May 27 2004
next sibling parent DemmeGod <me demmegod.com> writes:
mmmmm.... sugar... so sweet....

I like the idea.  Why anyone would object to it? (I'm sure I'll find out
soon enough)

On Thu, 27 May 2004 07:30:55 +0000, Arcane Jill wrote:

 One final(ish) push for :=
 
 I have suggested that "a := b;" be rewritten by the compiler as "a = new
 A(b)". I'm told that this would be merely syntactic sugar.
 
 Well yeah, it is. But the phrase "syntactic sugar" is a loaded phrase,
 implying "bad thing". The fact is that we can write "a = b + c" instead of
 "a = b.opAdd(c)", and we LIKE it. Syntactic sugar is sometimes nice.
 
 It's a very simple idea:
 
       a = b;      // copy by reference
       a := b;     // copy by value

This syntactic sugar would ALSO allow you to things like:
       Int n := 5;

(Int is my big integer class) instead of:
       Int n = new Int(5);

That sugary code is much more /smooth/. It /flows/. If no-one likes this idea, I'll drop it, but realise that this would also work for arrays. That is, if a and b are arrays, then
       a := b;

would be equivalent to:
       a.length = b.length;
       a[] = b[];

And as for structs, there would be no harm in allowing structs to have constructors (but not destructors), so it could work for them too. Arcane Jill (throwing caution to the wind).

May 27 2004
prev sibling next sibling parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
Sorry. I must strongly disagree with you. For a variety of reasons, D has opted
to represent objects as references to instances. Given that I think it in
appropriate to support any kind of implicit value semantics. It just leads to
too
many subtle contradictions. I recognise and agree that it can be inconvenient,
but it's just impossible to have a perfect language, and the cost benefit for
this feature doesn't warrant it.




"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c945ff$1q4a$1 digitaldaemon.com...
 One final(ish) push for :=

 I have suggested that "a := b;" be rewritten by the compiler as "a = new A(b)".
 I'm told that this would be merely syntactic sugar.

 Well yeah, it is. But the phrase "syntactic sugar" is a loaded phrase, implying
 "bad thing". The fact is that we can write "a = b + c" instead of "a =
 b.opAdd(c)", and we LIKE it. Syntactic sugar is sometimes nice.

 It's a very simple idea:

       a = b;      // copy by reference
       a := b;     // copy by value

This syntactic sugar would ALSO allow you to things like:
       Int n := 5;

(Int is my big integer class) instead of:
       Int n = new Int(5);

That sugary code is much more /smooth/. It /flows/. If no-one likes this idea, I'll drop it, but realise that this would also work for arrays. That is, if a and b are arrays, then
       a := b;

would be equivalent to:
       a.length = b.length;
       a[] = b[];

And as for structs, there would be no harm in allowing structs to have constructors (but not destructors), so it could work for them too. Arcane Jill (throwing caution to the wind).

May 27 2004
next sibling parent reply DemmeGod <me demmegod.com> writes:
I don't see any of those subtle contradictions... can you give an example?

On Thu, 27 May 2004 18:00:35 +1000, Matthew wrote:

 Sorry. I must strongly disagree with you. For a variety of reasons, D has
 opted to represent objects as references to instances. Given that I think
 it in appropriate to support any kind of implicit value semantics. It just
 leads to too many subtle contradictions. I recognise and agree that it can
 be inconvenient, but it's just impossible to have a perfect language, and
 the cost benefit for this feature doesn't warrant it.
 
 
 
 
 "Arcane Jill" <Arcane_member pathlink.com> wrote in message
 news:c945ff$1q4a$1 digitaldaemon.com...
 One final(ish) push for :=

 I have suggested that "a := b;" be rewritten by the compiler as "a = new
 A(b)". I'm told that this would be merely syntactic sugar.

 Well yeah, it is. But the phrase "syntactic sugar" is a loaded phrase,
 implying "bad thing". The fact is that we can write "a = b + c" instead
 of "a = b.opAdd(c)", and we LIKE it. Syntactic sugar is sometimes nice.

 It's a very simple idea:

       a = b;      // copy by reference
       a := b;     // copy by value

This syntactic sugar would ALSO allow you to things like:
       Int n := 5;

(Int is my big integer class) instead of:
       Int n = new Int(5);

That sugary code is much more /smooth/. It /flows/. If no-one likes this idea, I'll drop it, but realise that this would also work for arrays. That is, if a and b are arrays, then
       a := b;

would be equivalent to:
       a.length = b.length;
       a[] = b[];

And as for structs, there would be no harm in allowing structs to have constructors (but not destructors), so it could work for them too. Arcane Jill (throwing caution to the wind).


May 27 2004
parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
Alas I cannot.

I'm one of those vexing people who do a lot of things
subconsciously, and often have just "feelings" about things for ages. I've had
qualms about certain things that have literally taken months to bubble up
through
my tangled grey matter.

The way it works for me is that I'll remember that there are misgivings about
this issue, and when I come across the related issue(s) on which those
misgivings
are
(unconsciously) founded, the bells will ring, and I'll rush back and write it
down, or post an NG message.

This works well for writing books/articles, and for developing software, but it
can be quite a problem when having debates in person, or on newsgroups.

Given that, please feel free to ignore me as an irritating prick!

:-)

(I'm going a bike ride in a minute, and that often helps things bubble up ...)



"DemmeGod" <me demmegod.com> wrote in message
news:pan.2004.05.27.21.56.47.935562 demmegod.com...
 I don't see any of those subtle contradictions... can you give an example?

 On Thu, 27 May 2004 18:00:35 +1000, Matthew wrote:

 Sorry. I must strongly disagree with you. For a variety of reasons, D has
 opted to represent objects as references to instances. Given that I think
 it in appropriate to support any kind of implicit value semantics. It just
 leads to too many subtle contradictions. I recognise and agree that it can
 be inconvenient, but it's just impossible to have a perfect language, and
 the cost benefit for this feature doesn't warrant it.




 "Arcane Jill" <Arcane_member pathlink.com> wrote in message
 news:c945ff$1q4a$1 digitaldaemon.com...
 One final(ish) push for :=

 I have suggested that "a := b;" be rewritten by the compiler as "a = new
 A(b)". I'm told that this would be merely syntactic sugar.

 Well yeah, it is. But the phrase "syntactic sugar" is a loaded phrase,
 implying "bad thing". The fact is that we can write "a = b + c" instead
 of "a = b.opAdd(c)", and we LIKE it. Syntactic sugar is sometimes nice.

 It's a very simple idea:

       a = b;      // copy by reference
       a := b;     // copy by value

This syntactic sugar would ALSO allow you to things like:
       Int n := 5;

(Int is my big integer class) instead of:
       Int n = new Int(5);

That sugary code is much more /smooth/. It /flows/. If no-one likes this idea, I'll drop it, but realise that this would also work for arrays. That is, if a and b are arrays, then
       a := b;

would be equivalent to:
       a.length = b.length;
       a[] = b[];

And as for structs, there would be no harm in allowing structs to have constructors (but not destructors), so it could work for them too. Arcane Jill (throwing caution to the wind).



May 27 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
Woops! My bad.

       a.length = b.length;
       a[] = b[];





That's a bug. Surprised no-one spotted it. (Actually, no, I'm I not - /I/ didn't spot it until just now). Of course, the only correct way to copy an array by value is this:
       a = null;              // Very important statement
       a.length = b.length;
       a[] = b[];

Without that all important first line, you could easily be corrupting something else, if a happened to be a shared reference. (I hope the compiler doesn't optimize it away!) The fact that it takes three separate statements to safely copy an array is certainly an argument in favor of a simpler syntax for copy-by-value, methinks. Arcane Jill
May 28 2004
parent reply Andy Friesen <andy ikagames.com> writes:
Arcane Jill wrote:

 ... the only correct way to copy an array by value is this:
 
 
      a = null;              // Very important statement
      a.length = b.length;
      a[] = b[];

Without that all important first line, you could easily be corrupting something else, if a happened to be a shared reference. (I hope the compiler doesn't optimize it away!) The fact that it takes three separate statements to safely copy an array is certainly an argument in favor of a simpler syntax for copy-by-value, methinks.

What about a=b.dup;? -- andy
May 28 2004
parent Arcane Jill <Arcane_member pathlink.com> writes:
In article <c97tu8$2385$2 digitaldaemon.com>, Andy Friesen says...
What about a=b.dup;?

  -- andy

You're right. I missed that one. Jill
May 29 2004
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 27 May 2004 18:00:35 +1000, Matthew wrote:

 Sorry. I must strongly disagree with you. For a variety of reasons, D has opted
 to represent objects as references to instances. Given that I think it in
 appropriate to support any kind of implicit value semantics. It just leads to
too
 many subtle contradictions. I recognise and agree that it can be inconvenient,
 but it's just impossible to have a perfect language, and the cost benefit for
 this feature doesn't warrant it.
 

Que? Strongly disagree with what? Its only a syntax change not a semantic one. It doesn't break any exiting code. It doesn't make life harder. I'm not sure what you mean by "conrtadiction". Are you saying that, in some situations, you can envisage that the phrase " a := b " will not mean what we expect it to mean? It will always mean " Set the value of whatever 'a' refers to, to be identical to the value of whatever 'b' refers to". In other words, make a duplicate of b's object. If 'b' is an integer then take a copy of the integer value. If 'b' is a class object then create a new object of the same class, copy the RAM values to the new object and then assign 'a' to refer to the new object. Just like you might do in longhand. Maybe the compiler can check if the class has a 'dup' method and use that if it does exist? We aren't expecting the "perfect language", just a better one. And which cost-benefit study are you referring to? What are the costs? What are the benefits? And how do you measure them against each other? -- Derek 28/May/04 10:32:46 AM
May 27 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <c96240$2cc5$1 digitaldaemon.com>, Derek Parnell says...
Maybe the compiler can check if the class has a 'dup' method and use that
if it does exist? 

Actually, I've never completely understood the difference between a "dup" method and a copy constructor. Ok, so A.dup(parameters) calls one function and new A(parameters) calls a different function, and they /might/ be defined to do different things (just as opAdd and opAddAssign /might/ be defined to do different things, but that would be counter to common sense). So shouldn't a copy constructor and dup both DO the same thing? Why wouldn't they? I mean, if I were implementing dup, I'd implement it as:
       class A
       {
           this(A a)
           {
               // initialize this by taking details from a
           }

           A dup()
           {
               return new A(this);
           }
       }

What other meaning is there for a copy constructor other than to duplicate something? And doesn't that make dup redundant? (Of course, a.dup is less typing than new A(dup), for those who care about such things). Arcane Jill
May 28 2004
next sibling parent Derek Parnell <derek psych.ward> writes:
On Fri, 28 May 2004 07:10:48 +0000 (UTC), Arcane Jill wrote:

 In article <c96240$2cc5$1 digitaldaemon.com>, Derek Parnell says...
Maybe the compiler can check if the class has a 'dup' method and use that
if it does exist? 

Actually, I've never completely understood the difference between a "dup" method and a copy constructor. Ok, so A.dup(parameters) calls one function and new A(parameters) calls a different function, and they /might/ be defined to do different things (just as opAdd and opAddAssign /might/ be defined to do different things, but that would be counter to common sense). So shouldn't a copy constructor and dup both DO the same thing? Why wouldn't they? I mean, if I were implementing dup, I'd implement it as:
       class A
       {
           this(A a)
           {
               // initialize this by taking details from a
           }

           A dup()
           {
               return new A(this);
           }
       }

What other meaning is there for a copy constructor other than to duplicate something? And doesn't that make dup redundant? (Of course, a.dup is less typing than new A(dup), for those who care about such things).

Sorry for the confusion. It could be argued that 'dup' is not the same as a copy constructor because it doesn't actually *construct* anything. It assumes that the object already exists and just copies the bits across to the existing target location. Anyhow, 'dup' is a D term and 'copy constructor' is a C++/Java term. I don't really care either way, just so long as the bigger picture is still in focus (namely ':='). -- Derek 28/May/04 5:50:56 PM
May 28 2004
prev sibling parent reply J Anderson <REMOVEanderson badmama.com.au> writes:
Arcane Jill wrote:

In article <c96240$2cc5$1 digitaldaemon.com>, Derek Parnell says...
  

Maybe the compiler can check if the class has a 'dup' method and use that
if it does exist? 
    

Actually, I've never completely understood the difference between a "dup" method and a copy constructor.

never know what a copy constructor is going to be used for (is it a deep copy, shallow copy ect...). At least with methods like dup you can be more sure its going to make a duplicate and you can always define other copy methods for other types of copies if nessary. -- -Anderson: http://badmama.com.au/~anderson/
May 28 2004
parent reply "Carlos Santander B." <carlos8294 msn.com> writes:
"J Anderson" <REMOVEanderson badmama.com.au> escribió en el mensaje
news:c97426$t2o$1 digitaldaemon.com
| Walters reasoning for a dup instead of a copy constructor was that you
| never know what a copy constructor is going to be used for (is it a deep
| copy, shallow copy ect...).  At least with methods like dup you can be
| more sure its going to make a duplicate and you can always define other
| copy methods for other types of copies if nessary.
|
| --
| -Anderson: http://badmama.com.au/~anderson/

Sorry for asking, but what's the difference between a deep copy and a
shallow copy? Then only case I can think of something like this:

class A { A dup () { return new A; } }
class B
{
    A a;
    B shallow_dup ()
    {
        B b = new B;
        b.a = a;
        return b;
    }
    B deep_dup ()
    {
        B b = new B;
        b.a = a.dup;
        return b;
    }
}

Have I guessed right?

-----------------------
Carlos Santander Bernal
May 29 2004
parent J Anderson <REMOVEanderson badmama.com.au> writes:
Carlos Santander B. wrote:

"J Anderson" <REMOVEanderson badmama.com.au> escribió en el mensaje
news:c97426$t2o$1 digitaldaemon.com
| Walters reasoning for a dup instead of a copy constructor was that you
| never know what a copy constructor is going to be used for (is it a deep
| copy, shallow copy ect...).  At least with methods like dup you can be
| more sure its going to make a duplicate and you can always define other
| copy methods for other types of copies if nessary.
|
| --
| -Anderson: http://badmama.com.au/~anderson/

Sorry for asking, but what's the difference between a deep copy and a
shallow copy? Then only case I can think of something like this:

class A { A dup () { return new A; } }
class B
{
    A a;
    B shallow_dup ()
    {
        B b = new B;
        b.a = a;
        return b;
    }
    B deep_dup ()
    {
        B b = new B;
        b.a = a.dup;
        return b;
    }
}

Have I guessed right?

-----------------------
Carlos Santander Bernal
  

Right, but a shallow copy can be as low as a pointer copy which happens now. How shallow is shallow and how deep is deep. -- -Anderson: http://badmama.com.au/~anderson/
May 29 2004
prev sibling next sibling parent Juan C <Juan_member pathlink.com> writes:
One final(ish) push for :=

I have suggested that "a := b;" be rewritten by the compiler as "a = new A(b)".
I'm told that this would be merely syntactic sugar.

Yech. I still want := to be the assignment operator, and a bare = be invalid.
May 27 2004
prev sibling next sibling parent "Ben Hinkle" <bhinkle mathworks.com> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c945ff$1q4a$1 digitaldaemon.com...
 One final(ish) push for :=

 I have suggested that "a := b;" be rewritten by the compiler as "a = new

 I'm told that this would be merely syntactic sugar.

Is A the dynamic type or the static type? In other words if "b" is an instance of a subclass of A would "a" be an instance of the same subclass? If the compiler hard-codes in "new A(b)" then it looks like it wouldn't be. One way to get "value semantics" that gives the subclass complete control is to use a ".dup" property a = b.dup; The biggest difference from your proposal is that the class writer would have to define the .dup property instead of having the compiler generate one. I don't think that is so bad since dup'ing is fairly rare. -Ben
May 27 2004
prev sibling next sibling parent Derek Parnell <derek psych.ward> writes:
On Thu, 27 May 2004 07:30:55 +0000 (UTC), Arcane Jill wrote:

 One final(ish) push for :=
 
 I have suggested that "a := b;" be rewritten by the compiler as "a = new A(b)".
 I'm told that this would be merely syntactic sugar.
 
 Well yeah, it is. But the phrase "syntactic sugar" is a loaded phrase, implying
 "bad thing". The fact is that we can write "a = b + c" instead of "a =
 b.opAdd(c)", and we LIKE it. Syntactic sugar is sometimes nice.

I'm with you on this one too. What you are suggesting is a SHORTHAND method of doing something which is commonly written out in long hand. You are not saying that the current way should be abandonded, just supplemented with an alternative to make life easier for coders, and readers of code alike.
 It's a very simple idea:
 
       a = b;      // copy by reference
       a := b;     // copy by value


Yes. Nothing to taxing for my brain here. Sometimes we need to copy the reference to 'X' and sometimes we need to copy the value contained in 'X'. Or in other words, using the examples above, in the first one we want to copy what 'b' is, and in the second we want to copy what 'b' refers to. For simple datatypes (int, float, char, etc...) the two are identical in meaning. The difference appears when we are talking about classes, arrays, and structs.
 This syntactic sugar would ALSO allow you to things like:
 
       Int n := 5;

(Int is my big integer class) instead of:
       Int n = new Int(5);

That sugary code is much more /smooth/. It /flows/.

Yep, sure does. And it doesn't stop somebody from coding the long way or from coding ... Int n = new BaseInt(5); when Int and BaseInt are related.
 If no-one likes this idea, I'll drop it, but realise that this would also work
 for arrays. That is, if a and b are arrays, then
 
       a := b;

would be equivalent to:
       a.length = b.length;
       a[] = b[];


Much shorter and to the point. You are simply saying that you wish to make a duplicate of the array 'b'.
 And as for structs, there would be no harm in allowing structs to have
 constructors (but not destructors), so it could work for them too.

Still makes sense to me. I'm all in favour in making writing code and reading code easier. -- Derek 28/May/04 10:19:50 AM
May 27 2004
prev sibling next sibling parent James McComb <alan jamesmccomb.id.au> writes:
Arcane Jill wrote:
 One final(ish) push for :=
 
 I have suggested that "a := b;" be rewritten by the compiler as "a = new A(b)".
 I'm told that this would be merely syntactic sugar.

I like the way the word "new" alerts me to fact that I'm creating a new object. Also, if I'm wondering where I create new objects, I can just search for "new". James McComb
May 27 2004
prev sibling parent imr1984 <imr1984_member pathlink.com> writes:
ok syntactic sugar is often very nice, but it almost always causes more
complications and hassle for the compiler writer than it deserves. As well as
making the language more complicated therefore more prone to bugs.

In article <c945ff$1q4a$1 digitaldaemon.com>, Arcane Jill says...
One final(ish) push for :=

I have suggested that "a := b;" be rewritten by the compiler as "a = new A(b)".
I'm told that this would be merely syntactic sugar.

Well yeah, it is. But the phrase "syntactic sugar" is a loaded phrase, implying
"bad thing". The fact is that we can write "a = b + c" instead of "a =
b.opAdd(c)", and we LIKE it. Syntactic sugar is sometimes nice.

It's a very simple idea:

       a = b;      // copy by reference
       a := b;     // copy by value

This syntactic sugar would ALSO allow you to things like:
       Int n := 5;

(Int is my big integer class) instead of:
       Int n = new Int(5);

That sugary code is much more /smooth/. It /flows/. If no-one likes this idea, I'll drop it, but realise that this would also work for arrays. That is, if a and b are arrays, then
       a := b;

would be equivalent to:
       a.length = b.length;
       a[] = b[];

And as for structs, there would be no harm in allowing structs to have constructors (but not destructors), so it could work for them too. Arcane Jill (throwing caution to the wind).

May 28 2004