June 01, 2004
In article <c9ingg$24uc$1@digitaldaemon.com>, Daniel Horn says...
>
>For my BigRational struct it passes by value if you use an int or a long, but it passes by reference if you use a Int class

That should be harmless in this particular case, since Ints are immutable, so copying a reference is safe in the sense that the original will never get clobbered. However, I agree with you completely on the general point. Sometimes you do need to copy by value.


>It would be nice to get consistent behavior no matter the template argument.

I agree with you again. There should ideally be some consistent mechanism for copying by value. I don't care if it's opEquals, copy-constructor, dup method, my suggested := operator, or whatever, but there should be a way of copying by value that has the same syntax for *any* type. (And it should fail at compile-time if you try to copy-by-value a class for which dup() or copy constructor is not defined).




June 01, 2004
In article <c9in1e$2461$1@digitaldaemon.com>, Walter says...
>
>Most of the assignment operator overloading in C++ seems to be needed to just keep track of who owns the memory. So by using reference types coupled with GC, most of this just gets replaced with copying the reference itself. For example, given an array of class objects, the array's contents can be moved, sorted, shifted, etc., all without any need for overloaded assignments. Ditto for function parameters and return values. The references themselves just get moved about. There just doesn't seem to be any need for copying the entire contents of one class object into another pre-existing class object.

I'm tempted to ask, then, why the operators +=, *=, ++, and so on, are at all overloadable.

It is a general expectation of programmers that the following sequence of statements:

>       a = b;
>       ++a;

will not modify b. C++ achieves this by allowing the = in the first statement to be overloaded to copy by value. D doesn't, which is why I had to forbid such operators on Int. (A struct would not have sufficed because I needed to have a destructor).

If, as you say, "There just doesn't seem to be any need for copying the entire contents of one class object into another pre-existing class object", then what need do we have of assigning operator overloads. It would make sense to ban them altogether, but continue to allow them for structs.

..and for structs, of course, opAssign() also makes sense.

Arcane Jill


June 02, 2004
One other purpose of overloaded assignments in C++ not mentioned here are implicit type conversions:

---------
        onetype A;
        anothertype B = A;
           // will call the constructor anothertype::anothertype(onetype)
        B = A;
           // will call the assignment anothertype::operator=(onetype)
---------

I don't have this matter completely sorted out for D, but it seems constructors for structs are a badly missing feature. Having both constructors and overloaded assignments would probably not be necessary (I've never seen anything useful but just duplicated code there in C++.) But one of the two definitely would be needed.

Rationale: The expression template technique needs rather intelligent assignements to work. Actually, all the action happens on assignment/conversion. The whole expression is built up as one tree-structure and only in the end it is decided how it should be calculated. Without overloadable assignment/conversion, this will not be possible.

June 02, 2004
In article <c9in1e$2461$1@digitaldaemon.com>, Walter says...
>
>
>"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message news:c0d3ti$22u6$1@digitaldaemon.com...
>> The = operator on objects has a specific meaning as far as D is concerned - to copy object references, not the objects (or parts thereof) themselves.
>>
>> I think the only reason C++ allows overloading of = is that variables _are_ objects, not just references to them.  Combining this with C++'s lack of GC, assignments sometimes need special handling.
>>
>> OTOH, in D, with its objects by reference and GC, being able to overload = was deemed pointless for anything but code obfuscation.
>
>Most of the assignment operator overloading in C++ seems to be needed to just keep track of who owns the memory. So by using reference types coupled with GC, most of this just gets replaced with copying the reference itself. For example, given an array of class objects, the array's contents can be moved, sorted, shifted, etc., all without any need for overloaded assignments. Ditto for function parameters and return values. The references themselves just get moved about. There just doesn't seem to be any need for copying the entire contents of one class object into another pre-existing class object.
>
>Sometimes, one does need to create a copy of a class object, and for that one can still write a copy constructor in D, but they just don't seem to be needed remotely as much as in C++.
>
>Structs, being value objects, do get copied about. A copy is defined in D to be a bit copy. I've never been comfortable with any object in C++ that does something other than a bit copy when copied. Most of this other behavior stems from that old problem of trying to manage memory. Absent that, there doesn't seem to be a compelling rationale for allowing anything other than a bit copy.

99% agreed, but objects that hold an open file, mmap, etc might want to at least handle the "I've been dupped" case, i.e. make a note not to close the file.

Kevin


June 02, 2004
Kevin Bealer wrote:

> 99% agreed, but objects that hold an open file, mmap, etc might want to at least handle the "I've been dupped" case, i.e. make a note not to close the file.

There are two ways to interpret this statement:

1. If you are talking about structs, then this approach would mean that you also need struct destructors. This again means lots of overhead and complications when copying around data (like for arguments, etc)

2. If you are talking about classes, this may either mean
   a) keeping track of references - again lots of overhead when copying
      around
   b) copying objects - in this case it is no problem keeping track of
      copies. Every construction and destruction of an object goes along
      with the call of constructors and destructors.

June 02, 2004
Arcane Jill wrote:

<snip>
> I'm tempted to ask, then, why the operators +=, *=, ++, and so on, are at all
> overloadable.
<snip>

Only postfix ++ and -- are overloadable.  Prefix ++ and -- do the sensible thing.

Just looking at the docs,

" Assignment operator expressions, such as:

	a op= b	

are semantically equivalent to:

	a = a op b
	
except that operand a is only evaluated once."

Makes sense and is in line with C.  But does this actually apply just as well if a is a class object, and doesn't have its own op<op>Assign?

I guess that overloading is useful if you want to modify the object in place....

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.
June 02, 2004
"Kevin Bealer" <Kevin_member@pathlink.com> wrote in message news:c9juaj$rir$1@digitaldaemon.com...
> >Structs, being value objects, do get copied about. A copy is defined in D
to
> >be a bit copy. I've never been comfortable with any object in C++ that
does
> >something other than a bit copy when copied. Most of this other behavior stems from that old problem of trying to manage memory. Absent that,
there
> >doesn't seem to be a compelling rationale for allowing anything other
than a
> >bit copy.
>
> 99% agreed, but objects that hold an open file, mmap, etc might want to at
least
> handle the "I've been dupped" case, i.e. make a note not to close the
file.

In such cases, an auto class should fill the bill instead of a struct.


June 02, 2004
"Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:c9iv40$2ftu$1@digitaldaemon.com...
> I'm tempted to ask, then, why the operators +=, *=, ++, and so on, are at
all
> overloadable.
>
> It is a general expectation of programmers that the following sequence of statements:
>
> >       a = b;
> >       ++a;
>
> will not modify b. C++ achieves this by allowing the = in the first
statement to
> be overloaded to copy by value. D doesn't, which is why I had to forbid
such
> operators on Int.

I got tripped up myself on this when I learned Java. Reference semantics are a different mindset, there's just no way around that. But once one gets comfortable with that different mindset, it isn't a problem anymore.



June 02, 2004
But what about overriding opAssign for structs...structs may or may not have
arrays inside...and this will determine whether they copy or not.
case in point is my template class that accepts an Int or a long...
depending on template arg the struct will do a shallow or deep copy
I agree that classes should be consistent: but the same goes for structs.



In article <c9l5ci$2ko3$2@digitaldaemon.com>, Walter says...
>
>
>"Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:c9iv40$2ftu$1@digitaldaemon.com...
>> I'm tempted to ask, then, why the operators +=, *=, ++, and so on, are at
>all
>> overloadable.
>>
>> It is a general expectation of programmers that the following sequence of statements:
>>
>> >       a = b;
>> >       ++a;
>>
>> will not modify b. C++ achieves this by allowing the = in the first
>statement to
>> be overloaded to copy by value. D doesn't, which is why I had to forbid
>such
>> operators on Int.
>
>I got tripped up myself on this when I learned Java. Reference semantics are a different mindset, there's just no way around that. But once one gets comfortable with that different mindset, it isn't a problem anymore.
>
>
>


June 02, 2004
In article <c9l836$2oob$1@digitaldaemon.com>, hellcatv@hotmail.com says...
>
>But what about overriding opAssign for structs...structs may or may not have
>arrays inside...and this will determine whether they copy or not.
>case in point is my template class that accepts an Int or a long...
>depending on template arg the struct will do a shallow or deep copy

Ah - well, I'm off topic for the thread title here, but just quickly to mention...

In the latest version I've actually removed the copy constructor and dup from Int, so you can't deep copy it any more. I did this because you don't need to deep copy it, ever, and I realized (in the end, after some prompting) that the presence of those functions might mislead people into thinking copy-by-value for this class did anything useful.

Arcane Jill