View mode: basic / threaded / horizontal-split · Log in · Help
April 15, 2005
Re: How to bridge the gap between user defined types and built in types?
BTW, the simple workaround about general templates. Inside template one
could write
a=b+0;
instead of
a=b;
to emulate assignment by value.

But in my opinion having something like ":=" operator is much more
convenient.

-- 
         Vladimir
April 15, 2005
Re: How to bridge the gap between user defined types and built in types?
Ah, a Pascal fan.  Hehe.

Seriously though, yes... having an unambiguous assignment operator would be a real plus, and since the ":=" operator is already established as such elsewhere, it would be a good choice to add support for.  Use of the "=" operator could then be discouraged, in favor of the the ":=" operator, to help avoid many common errors, and eventually perhaps the "=" operator would be phased out to the point where it would make sense to flag a warning at compile time if one is found.

Yes, I know what you mean about assignment by value... but I am even more intregued by your mention of the ":=" assignment operator.  I'll give my thoughts on that first, and then I'm going to ask for a slight clarification of yours...

I'm not suggesting or condoning the change from "=" for assignment and "==" for comparison to ":=" for assignment and "=" for comparison, as found in Pascal and it's derivatives, but I would "strongly" recommend the simple addition of ":=" as an alternative assignment operator, and encouraging people to adapt it's use, while continuing to use "==" as the equality comparison operator.  This could be the best idea I've heard in years... Thanks Ben.

Okay, now... Ben... did you mean to have ":=" added as an "assign by value" operator or just as an "assignment" operator?  Also, if you meant it as "assign by value" (copy of the original data) then would you also have a specific "assign by reference" operator in mind?... Furthermore, I'm curious what you had in mind for the "=" operator.  Just leave it as is, or somethining else?  Please, elaborate a bit.

TechnoZeus

TechnoZeus

"Vladimir" <kv11111@mail.ru> wrote in message news:d3o2ho$al$1@digitaldaemon.com...
> BTW, the simple workaround about general templates. Inside template one
> could write
> a=b+0;
> instead of
> a=b;
> to emulate assignment by value.
>
> But in my opinion having something like ":=" operator is much more
> convenient.
>
> -- 
>           Vladimir
April 15, 2005
Re: How to bridge the gap between user defined types and built in types?
Oops... my apologies, Vladimir.  I thought I was reading Ben's post.  Had clicked on it in the list, and somehow got yours... didn't notice the signature, until just as I clicked the "send" button.

Sorry about the confusion.  Anyway... Thanks for the great idea Vladimir.  Please elaborate.

TechnoZeus

"TechnoZeus" <TechnoZeus@PeoplePC.com> wrote in message news:d3o93s$6n5$1@digitaldaemon.com...
> Ah, a Pascal fan.  Hehe.
>
> Seriously though, yes... having an unambiguous assignment operator would be a real plus, and since the ":=" operator is already established as such elsewhere, it would be a good choice to add support for.  Use of the "=" operator could then be discouraged, in favor of the the ":=" operator, to help avoid many common errors, and eventually perhaps the "=" operator would be phased out to the point where it would make sense to flag a warning at compile time if one is found.
>
> Yes, I know what you mean about assignment by value... but I am even more intregued by your mention of the ":=" assignment operator.  I'll give my thoughts on that first, and then I'm going to ask for a slight clarification of yours...
>
> I'm not suggesting or condoning the change from "=" for assignment and "==" for comparison to ":=" for assignment and "=" for comparison, as found in Pascal and it's derivatives, but I would "strongly" recommend the simple addition of ":=" as an alternative assignment operator, and encouraging people to adapt it's use, while continuing to use "==" as the equality comparison operator.  This could be the best idea I've heard in years... Thanks Ben.
>
> Okay, now... Ben... did you mean to have ":=" added as an "assign by value" operator or just as an "assignment" operator?  Also, if you meant it as "assign by value" (copy of the original data) then would you also have a specific "assign by reference" operator in mind?... Furthermore, I'm curious what you had in mind for the "=" operator.  Just leave it as is, or somethining else?  Please, elaborate a bit.
>
> TechnoZeus
>
> TechnoZeus
>
> "Vladimir" <kv11111@mail.ru> wrote in message news:d3o2ho$al$1@digitaldaemon.com...
> > BTW, the simple workaround about general templates. Inside template one
> > could write
> > a=b+0;
> > instead of
> > a=b;
> > to emulate assignment by value.
> >
> > But in my opinion having something like ":=" operator is much more
> > convenient.
> >
> > -- 
> >           Vladimir
>
>
April 15, 2005
Re: How to bridge the gap between user defined types and built in types?
> Thanks Ben.
>
> Okay, now... Ben...

I think you mean Vladimir. My post was the one with no ideas in it :-)
April 15, 2005
Re: How to bridge the gap between user defined types and built in types?
Hahaha.  Cute, Ben.  Yes, I was responding to Vladimir's post, and thought it was yours.  Mouse click error, I think.  Already responded to my own post with information to that effect.  Sorry for the error.

TZ

"Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:d3o9bc$711$1@digitaldaemon.com...
> > Thanks Ben.
> >
> > Okay, now... Ben...
>
> I think you mean Vladimir. My post was the one with no ideas in it :-)
>
>
April 15, 2005
Re: How to bridge the gap between user defined types and built in types?
TechnoZeus wrote:

> Oops... my apologies, Vladimir.  I thought I was reading Ben's post.  Had
> clicked on it in the list, and somehow got yours... didn't notice the
> signature, until just as I clicked the "send" button.
> 
> Sorry about the confusion.  Anyway... Thanks for the great idea Vladimir. 
> Please elaborate.

Actually this is not my idea, look at the thread called opValue at the and
of discussion. But I really like this idea and think it's very important.
The only trouble is to convince Walter to allow this operator.

For quick explanation, this it the extraction from that thread:

,--------------- Forwarded message (begin)

Subject: Re: opValue()
From: Regan Heath <regan@netwin.co.nz>
Date: Thu, 07 Apr 2005 05:34:52 +0400
Newsgroup: digitalmars.D

On Thu, 07 Apr 2005 08:45:21 +1200, <brad@domain.invalid> wrote:
> rter syntax:
>>  class T { T opShlAssign(Foo c) { /*...*/ return this; } }
>>  a<<=b; // almost like a=b, if you ask me
>>  I guess in 99.99999% cases, shifting an object to left with another  
>> object doesn't make sense anyway, so the operator might as well get  
>> another use..
>>   xs0
>
> Argh!  Surely not!  I thought one of the philosophies of D was that  
> operators should _always_ do what you expect.  The <<= operator should  
> always shift left & assign.
>
> Derek - am I right in saying that you want an assignment operator that  
> doesn't create a new object, but instead alters an existing one?  At the  
> moment, when you deal with objects/references, the = operator always  
> means "set this reference to this object".  I don't think that it makes  
> sense to overload this meaning, because you then end up with an operator  
> that in some cases does
> "set this reference to this object" and in other cases
> "alter the internal data layout of object A, based on the values in  
> object B"
> And then you end up with a whole lot of special rules to try and  
> remember which assignment operator is applying.  Overwriting the  
> contents of an object when you really ment to assign to a new object  
> could ruin your day if you hold multiple references to the object you  
> are stomping on.
>
> I am in favour of having an operator that means "take object B, get some  
> values out of it and setup object A accordingly"

And if they're the same type, it could be used for a "deep-copy"?
I think we can combine this casting concern with the deep-copy concern,  
they seem closely related to me.

> Something like
> Foo a = new Foo ();
> Bar b = new Bar ();
> a <- b // which calls a.opConvert(b);
>
> I guess you could also end up with nasty
> a = (new Foo())<- b;

It seems 'correct' if 'ugly', done in 2 steps looks nicer and incurs no  
additional penalty (that I can see).

a = new Foo();
a <- b;

this operator is really a "copy RHS into LHS" operator, which implys that  
LHS must exists beforehand.
Or using the "<-" operator could implicitly call new if the LHS is null...  
not sure how feasible that is.

> <- is probably not the operator to choose, probably hard to parse. Maybe  
> someone else can think of a good operator if this functionality is  
> required.

I agree, I think the main concern against this in Walters case was that  
implicit conversion when "=" is used can cause subtle behaviour and bugs.  
(correct me if I am wrong).

So, if a new operator was used, eg. ":=" or something then this concern  
vanishes, as "=" does what it currently does:
  - shallow copy for arrays.
  - reference assignment for classes etc
  - deep copy for value types

The new ":=" operator always means "copy RHS into LHS" AKA:
  - deep copy for arrays (provided items in array have deep-copy method  
defined)
  - deep copy for classes (provided class has deep-copy method defined)
  - same as "=" for value types.

Thoughts?

Regan

`--------------- Forwarded message (end)



-- 
         Vladimir
April 16, 2005
Re: How to bridge the gap between user defined types and built in types?
To get some idea of context you're best to read the entire thread, tho  
it's a big one.. so, to make life easier I'm going to attempt to summarise  
it. (if anyone has corrections, please make them)

In essence Derek wanted to assign the value of an object with another. His  
initial idea was to use an overload of the assingment operator, as is done  
in C++.

D does not allow you to overload the assignment operator, I believe,  
because Walter dislikes the subtle behaviour this introduces, and in his  
experience subtle bugs can arise out of it.

Classes are references and assignment '=' does a reference assignment.  
Overloading '=' to do a value assignment for a class would change this  
behaviour.

So, how to solve Dereks requirement of a value assignment for a reference  
type.

It occured to me that this was identical to a "deep copy" where the object  
being assigned was the same type as the value being assigned.

So, "to kill 2 birds with one stone" (AKA solve both problems at once) I  
figured a value assignment operator was required. I remember someone  
talking about ":=" and it's use in other languages, tho I've never used  
them, so I suggested it.

It also occured to me that we have "==" and "is" for value and identity  
comparisons (albeit with exceptions - IMO sensible ones) and it therefore  
makes sense to have ":=" and "=" for value and identity assignments  
(interestingly with all the same exceptions as "==" and "is" operate  
under).

My take on "==" and "is" (for reference):

1. "==" does value comparison.
2. "is" does identity comparison.

Exception to 1, a reference type with no defined method of comparison is  
compared using identity. If identity is equal, value will be equal. If  
identity is not equal then given no way to compare value one must assume  
inequality or throw an exception. (D assumes inequality, an exception can  
be thrown by coding it manually)

Exception to 2, a value type. No 2 values types can compare equal in  
identity. Technically this could be an error? However, D does a value  
comparison. A lint program could catch and error on this. I see little  
point and quite like the way "if (a is 5)" (where a is an 'int' or  
similar) reads.

How these exceptions apply to "=" and ":=":

1. ":=" does value assignment
2. "="  does identity assignment

Exception to 1, a reference type with no defined method of assignment.  
Best behaviour here would be an error IMO.

Exception to 2, a value type. You cannot assign identity to a value type,  
so you assign value (current D behaviour).

So, as you can see the exceptions are parallel, the behvaiour of "=" need  
not change, all that is added is ":=" and opAssign overloads for reference  
types.

Regan

On Fri, 15 Apr 2005 21:00:25 +0400, Vladimir <kv11111@mail.ru> wrote:
> TechnoZeus wrote:
>
>> Oops... my apologies, Vladimir.  I thought I was reading Ben's post.   
>> Had
>> clicked on it in the list, and somehow got yours... didn't notice the
>> signature, until just as I clicked the "send" button.
>>
>> Sorry about the confusion.  Anyway... Thanks for the great idea  
>> Vladimir.
>> Please elaborate.
>
> Actually this is not my idea, look at the thread called opValue at the  
> and
> of discussion. But I really like this idea and think it's very important.
> The only trouble is to convince Walter to allow this operator.
>
> For quick explanation, this it the extraction from that thread:
>
> ,--------------- Forwarded message (begin)
>
>  Subject: Re: opValue()
>  From: Regan Heath <regan@netwin.co.nz>
>  Date: Thu, 07 Apr 2005 05:34:52 +0400
>  Newsgroup: digitalmars.D
>
>  On Thu, 07 Apr 2005 08:45:21 +1200, <brad@domain.invalid> wrote:
>  > rter syntax:
>  >>  class T { T opShlAssign(Foo c) { /*...*/ return this; } }
>  >>  a<<=b; // almost like a=b, if you ask me
>  >>  I guess in 99.99999% cases, shifting an object to left with another
>  >> object doesn't make sense anyway, so the operator might as well get
>  >> another use..
>  >>   xs0
>  >
>  > Argh!  Surely not!  I thought one of the philosophies of D was that
>  > operators should _always_ do what you expect.  The <<= operator should
>  > always shift left & assign.
>  >
>  > Derek - am I right in saying that you want an assignment operator that
>  > doesn't create a new object, but instead alters an existing one?  At  
> the
>  > moment, when you deal with objects/references, the = operator always
>  > means "set this reference to this object".  I don't think that it  
> makes
>  > sense to overload this meaning, because you then end up with an  
> operator
>  > that in some cases does
>  > "set this reference to this object" and in other cases
>  > "alter the internal data layout of object A, based on the values in
>  > object B"
>  > And then you end up with a whole lot of special rules to try and
>  > remember which assignment operator is applying.  Overwriting the
>  > contents of an object when you really ment to assign to a new object
>  > could ruin your day if you hold multiple references to the object you
>  > are stomping on.
>  >
>  > I am in favour of having an operator that means "take object B, get  
> some
>  > values out of it and setup object A accordingly"
> And if they're the same type, it could be used for a "deep-copy"?
>  I think we can combine this casting concern with the deep-copy concern,
>  they seem closely related to me.
> > Something like
>  > Foo a = new Foo ();
>  > Bar b = new Bar ();
>  > a <- b // which calls a.opConvert(b);
>  >
>  > I guess you could also end up with nasty
>  > a = (new Foo())<- b;
> It seems 'correct' if 'ugly', done in 2 steps looks nicer and incurs no
>  additional penalty (that I can see).
> a = new Foo();
>  a <- b;
> this operator is really a "copy RHS into LHS" operator, which implys that
>  LHS must exists beforehand.
>  Or using the "<-" operator could implicitly call new if the LHS is  
> null...
>  not sure how feasible that is.
> > <- is probably not the operator to choose, probably hard to parse.  
> Maybe
>  > someone else can think of a good operator if this functionality is
>  > required.
> I agree, I think the main concern against this in Walters case was that
>  implicit conversion when "=" is used can cause subtle behaviour and  
> bugs.
>  (correct me if I am wrong).
> So, if a new operator was used, eg. ":=" or something then this concern
>  vanishes, as "=" does what it currently does:
>    - shallow copy for arrays.
>    - reference assignment for classes etc
>    - deep copy for value types
> The new ":=" operator always means "copy RHS into LHS" AKA:
>    - deep copy for arrays (provided items in array have deep-copy method
>  defined)
>    - deep copy for classes (provided class has deep-copy method defined)
>    - same as "=" for value types.
> Thoughts?
> Regan
>
> `--------------- Forwarded message (end)
>
>
>
April 16, 2005
Re: How to bridge the gap between user defined types and built in types?
Thanks a lot for good summary.

Regan Heath wrote:
> My take on "==" and "is" (for reference):
> 
> 1. "==" does value comparison.
> 2. "is" does identity comparison.
> 
> Exception to 1, a reference type with no defined method of comparison is
> compared using identity. If identity is equal, value will be equal. If
> identity is not equal then given no way to compare value one must assume
> inequality or throw an exception. (D assumes inequality, an exception can
> be thrown by coding it manually)
> 
> Exception to 2, a value type. No 2 values types can compare equal in
> identity. Technically this could be an error? However, D does a value
> comparison. A lint program could catch and error on this. I see little
> point and quite like the way "if (a is 5)" (where a is an 'int' or
> similar) reads.
I thought that equality by identity means that if I change one of two equal
objects, the second will be changed too. But know I understand that this is
wrong for built-in types. This could be another problem for general
template programming.

> How these exceptions apply to "=" and ":=":
> 
> 1. ":=" does value assignment
> 2. "="  does identity assignment
> 
> Exception to 1, a reference type with no defined method of assignment.
> Best behaviour here would be an error IMO.
> 
> Exception to 2, a value type. You cannot assign identity to a value type,
> so you assign value (current D behaviour).
> 
> So, as you can see the exceptions are parallel, the behvaiour of "=" need
> not change, all that is added is ":=" and opAssign overloads for reference
> types.
> 
> Regan
> 

-- 
         Vladimir
April 16, 2005
Re: How to bridge the gap between user defined types and built in types?
On Sat, 16 Apr 2005 12:21:28 +0400, Vladimir <kv11111@mail.ru> wrote:
> Thanks a lot for good summary.
>
> Regan Heath wrote:
>> My take on "==" and "is" (for reference):
>>
>> 1. "==" does value comparison.
>> 2. "is" does identity comparison.
>>
>> Exception to 1, a reference type with no defined method of comparison is
>> compared using identity. If identity is equal, value will be equal. If
>> identity is not equal then given no way to compare value one must assume
>> inequality or throw an exception. (D assumes inequality, an exception  
>> can
>> be thrown by coding it manually)
>>
>> Exception to 2, a value type. No 2 values types can compare equal in
>> identity. Technically this could be an error? However, D does a value
>> comparison. A lint program could catch and error on this. I see little
>> point and quite like the way "if (a is 5)" (where a is an 'int' or
>> similar) reads.

> I thought that equality by identity means that if I change one of two  
> equal objects, the second will be changed too.

If they're objects (AKA references, AKA reference types), and you change  
the "value", yes.

> But know I understand that this is
> wrong for built-in types.

But not for all built in types. "char[]" is a built in tpye, an array. It  
is a "reference type".
"int" is a built in type. It is a "value type".

> This could be another problem for general
> template programming.

Agreed. I like having both value and reference types, they have thier  
uses. Having the ability to restrict templates, and/or having  
operators/methods with identical behaviour for both types of types solves  
the template issues. I believe having a ":=" value assignment operator  
helps.

Regan
April 20, 2005
Re: How to bridge the gap between user defined types and built in types?
Nice summary.  Thanks.

Two points I would like to bring up....

First, is that value types do have an identity.  Even a litteral has an identity, because it has to be stored "somewhere" to be used. Therefore, it may be "possible" but undesireable to allow identity assignemnts to value types in general.  In cases where it is desireable, pointers would suffice.  Not an argument for or against anything you said... just a detail that I thought should be mentioned.

Second, is that while I think adding ":=" as a value assignemt operator would be a great idea, I also think that making "=" into something that it's not would be a very bad idea.  If there is to be a "reference assignment" operator, I think it should be something that is not currently in use.

In other words, as messy as it is, I would say leave the "=" operator have it's current quirks, for backward compatibility if nothing else, but add ":=" for value assignments, and add an identity assignment operator so that explicit identity assignments or would be possible without having to resort to using value assignments on pointer types and without having to use the "=" operator if the programmer chooses to avoid it.  This way, perhaps a compiler switch could even be added that would warn on the use of the "=" operator, so that people who have found it to be involved in the production of too many bugs could phase it out if they so choose.

Also, I would personally recommend that the following two default members be supported on everything that is capable of supporting them:  ".value" to explicitly access or assign the item's value, and ".identity" to explicitly access or assign the item's identity.

Most important though of all that's been mentioned in this thread, in my opinion, would be the addition of a ":=" value assigment operator.  (Perhaps =:= could be added also as an explicit value comparison operator.  Also, >:= and <:= and so on, as well as the natural extension to +:= and -:= and so on for explicit "modify and assign value" operators.  Just a thought.)

TZ

"Regan Heath" <regan@netwin.co.nz> wrote in message news:opspblnau423k2f5@nrage.netwin.co.nz...
> On Sat, 16 Apr 2005 12:21:28 +0400, Vladimir <kv11111@mail.ru> wrote:
> > Thanks a lot for good summary.
> >
> > Regan Heath wrote:
> >> My take on "==" and "is" (for reference):
> >>
> >> 1. "==" does value comparison.
> >> 2. "is" does identity comparison.
> >>
> >> Exception to 1, a reference type with no defined method of comparison is
> >> compared using identity. If identity is equal, value will be equal. If
> >> identity is not equal then given no way to compare value one must assume
> >> inequality or throw an exception. (D assumes inequality, an exception
> >> can
> >> be thrown by coding it manually)
> >>
> >> Exception to 2, a value type. No 2 values types can compare equal in
> >> identity. Technically this could be an error? However, D does a value
> >> comparison. A lint program could catch and error on this. I see little
> >> point and quite like the way "if (a is 5)" (where a is an 'int' or
> >> similar) reads.
>
> > I thought that equality by identity means that if I change one of two
> > equal objects, the second will be changed too.
>
> If they're objects (AKA references, AKA reference types), and you change
> the "value", yes.
>
> > But know I understand that this is
> > wrong for built-in types.
>
> But not for all built in types. "char[]" is a built in tpye, an array. It
> is a "reference type".
> "int" is a built in type. It is a "value type".
>
> > This could be another problem for general
> > template programming.
>
> Agreed. I like having both value and reference types, they have thier
> uses. Having the ability to restrict templates, and/or having
> operators/methods with identical behaviour for both types of types solves
> the template issues. I believe having a ":=" value assignment operator
> helps.
>
> Regan
1 2 3 4 5 6
Top | Discussion index | About this forum | D home