digitalmars.D - How to bridge the gap between user defined types and built in types?
- brad domain.invalid (29/29) Apr 13 2005 I think this needs a new thread. Here is a snip of what I previously
- xs0 (3/39) Apr 14 2005 Isn't a struct exactly what you want? It can have methods and operators
- Jan-Eric Duden (3/46) Apr 14 2005 Except that structs don't have constructors and destructors... which
- TechnoZeus (22/68) Apr 14 2005 [----]
- brad domain.invalid (10/10) Apr 14 2005 I'm afraid that only solves portions of the problem as I see it. The
- pragma (14/23) Apr 14 2005 Just a thought: would having ".dup" available universally help the assig...
- TechnoZeus (10/36) Apr 14 2005 How about giving all items, including litterals, two properties as follo...
- brad domain.invalid (8/25) Apr 14 2005 That has a lot of appeal, but certainly is a lot of typing. It would be...
- TechnoZeus (4/29) Apr 14 2005 I haven't worked with it since it was still in it's beta development, so...
- Ben Hinkle (9/12) Apr 14 2005 I didn't have many problems mimicing a primitive numeric type when
- Vladimir (10/10) Apr 15 2005 BTW, the simple workaround about general templates. Inside template one
- TechnoZeus (8/18) Apr 15 2005 Ah, a Pascal fan. Hehe.
- TechnoZeus (4/24) Apr 15 2005 Oops... my apologies, Vladimir. I thought I was reading Ben's post. Ha...
- Vladimir (51/92) Apr 15 2005 Actually this is not my idea, look at the thread called opValue at the a...
- Regan Heath (50/143) Apr 15 2005 To get some idea of context you're best to read the entire thread, tho
- Vladimir (8/41) Apr 16 2005 I thought that equality by identity means that if I change one of two eq...
- Regan Heath (12/37) Apr 16 2005 If they're objects (AKA references, AKA reference types), and you change...
- TechnoZeus (9/47) Apr 20 2005 Nice summary. Thanks.
- brad beveridge (9/24) Apr 20 2005 I think we should campaign for ":=" right now. I don't think we need a
- TechnoZeus (4/28) Apr 20 2005 Yes, I agree fully.
- Regan Heath (65/149) Apr 20 2005 Agreed.
- Vladimir (16/21) Apr 20 2005 Yes, but suppose someone (for example with python background) after read...
- Regan Heath (9/30) Apr 20 2005 If your intention is to assign "value" then you'd use ":=" not "=".
- Regan Heath (16/40) Apr 20 2005 If they read this, it was poorly written because it's untrue. (I did try...
- TechnoZeus (5/48) Apr 20 2005 Not sure whether this would be advantageous or not,
- Vladimir (52/102) Apr 21 2005 But not in general templates. For classes type C* means pointer to refer...
-
brad beveridge
(9/10)
Apr 21 2005
- TechnoZeus (5/15) Apr 21 2005 Define "better" in that context.
- Ben Hinkle (3/8) Apr 21 2005 http://www.digitalmars.com/d/faq.html#assignmentoverloading
- TechnoZeus (4/15) Apr 21 2005 Hi Ben.
- Ben Hinkle (4/9) Apr 21 2005 That's what this discussion on := and opAssign are about. Walter has alr...
- Vladimir (14/25) Apr 21 2005 This discussion is not about opAssign overloading, but about problems wh...
- TechnoZeus (8/18) Apr 21 2005 It's a big thread... that might have been in it somewhere.
- Ben Hinkle (7/16) Apr 21 2005 hehe. Sorry but it sounds funny to say an operator called := with overlo...
- Regan Heath (38/56) Apr 21 2005 But they don't as far as I can see. Reading:
- Ben Hinkle (16/72) Apr 21 2005 I agree it's a matter of opinion what counts as subtle and what doesn't....
- Regan Heath (22/34) Apr 21 2005 Yes. Derek originally wanted to overload opCast by return type or
- TechnoZeus (3/3) Apr 22 2005 Using := as a value assignment operator would have more uses than just t...
- TechnoZeus (3/21) Apr 22 2005 Yes, you're right. If that had been what we were saying, it would have ...
- Georg Wrede (72/79) Apr 21 2005 This post essentially sums up what I've been talking about for some time...
-
Brad Beveridge
(18/28)
Apr 21 2005
- Derek Parnell (21/24) Apr 21 2005 BTW, I've resigned myself to using a 'Value' property in the classes I'm
- Ben Hinkle (17/29) Apr 21 2005 Without knowing anything about the context, would using toFoo and toBar
- Derek Parnell (9/30) Apr 21 2005 Yes it would work, but I use templates a lot, and there are more classes
- TechnoZeus (17/96) Apr 22 2005 The problem isn't a lack of understanding.
- Vladimir (18/28) Apr 21 2005 value-type can't be null
- TechnoZeus (23/23) Apr 20 2005 I should have been more clear in what I stated about pointers.
- Regan Heath (10/31) Apr 20 2005 Just like "=" does currently.
- TechnoZeus (13/45) Apr 20 2005 Yes, for the most part, we are in agreement... is one of the things I wa...
- Brad Beveridge (12/12) Apr 20 2005 I am soliticting help from the senior members of the NG. As I mention
- TechnoZeus (3/15) Apr 20 2005 I'll do one better than that.
- Christian Schüler (3/156) Apr 20 2005 With respect to the established mathematical notation,
- TechnoZeus (3/179) Apr 20 2005 Why?
- Christian Schüler (6/195) Apr 20 2005 Just as I was expecting that a google search on "mathematical identity" ...
- Brad Beveridge (10/18) Apr 20 2005 From a practical programmers point of view, I don't think that the
- TechnoZeus (4/22) Apr 20 2005 Yep... I totally agree. Better to let "=" act as it does now, and let "...
- Kevin Bealer (6/24) Apr 22 2005 What can you do with deep copy that you can't do with:
- Brad Beveridge (10/20) Apr 22 2005 Yes, I think that you should be able to override a function so that a
- TechnoZeus (28/48) Apr 23 2005 As I pointed out in another thread, the following code doesn't work...
- Carlos Santander B. (5/36) Apr 23 2005 Also already answered: dest[] = source[8..12]
- TechnoZeus (13/49) Apr 23 2005 That's not an answer. It's a work-around.
- Derek Parnell (24/77) Apr 24 2005 Are doing this deliberately?
- TechnoZeus (16/24) Apr 24 2005 Among othger things, yes... that is what I am saying I would like it to ...
- Ben Hinkle (1/3) Apr 15 2005 I think you mean Vladimir. My post was the one with no ideas in it :-)
- TechnoZeus (3/7) Apr 15 2005 Hahaha. Cute, Ben. Yes, I was responding to Vladimir's post, and thoug...
- TechnoZeus (12/22) Apr 20 2005 Anders mentioned the addition of a ":=" operator on April 12th,
- TechnoZeus (3/3) Apr 20 2005 I'm inviting anyone who wants to summarize their thoughts or comments on...
- Brad Beveridge (14/20) Apr 20 2005 My only comment is thus:
- TechnoZeus (5/25) Apr 20 2005 Cool. Hadn't thought of that. :)
- Ben Hinkle (2/8) Apr 21 2005 array.dup would still be needed (like any dup property) in expressions t...
- Ben Hinkle (17/20) Apr 20 2005 What exactly is the proposed behavior? For instance what would it do for...
- Brad Beveridge (11/16) Apr 20 2005 Built-in types will behave exactly as they do with ":=" as they
- TechnoZeus (3/19) Apr 20 2005 Thanks. You explained that much better than I did. :)
- TechnoZeus (15/35) Apr 20 2005 My understanding of the overal concensus is that := would be used to cop...
- pragma (28/30) Apr 21 2005 Ben, thank you. You took the words right out of my mouth. :)
- Vladimir (10/52) Apr 21 2005 Formally you are right, but always typing a=b.dup is not convenient and ...
- pragma (12/15) Apr 21 2005 The only wart here is that you'll run into small problems with ':' when
- Vladimir (10/32) Apr 21 2005 But what is so fundamental difference between "create a new property for
- pragma (14/29) Apr 21 2005 Largely, the compiler impact is the biggest difference; a universal dup(...
- TechnoZeus (3/34) Apr 22 2005 As it turns out, the .dup member function returns a reference, rather th...
- TechnoZeus (5/44) Apr 22 2005 oops... brain thought one thing, and hands typed another.
- Vladimir (8/45) Apr 22 2005 All these changes are trivial. I've done a patch for gdc-0.10 to allow
- Brad Beveridge (11/11) Apr 22 2005 Vladimir - can you please explain the new behaviour of your patch?
- Vladimir (12/23) Apr 22 2005 Correct.
- TechnoZeus (3/25) Apr 23 2005 That's important too. :) Much appriated, of course.
- TechnoZeus (7/11) Apr 23 2005 Sorry. I should snipped the quote.
- Derek Parnell (27/39) Apr 22 2005 This '@' proposal is the one that I'm liking the most so far.
- Brad Beveridge (8/52) Apr 22 2005 The @ operator is currently unary, so there really is no notion of
- Brad Beveridge (6/14) Apr 22 2005 Poor form answering my own question, perhaps we should add @= as an
- TechnoZeus (10/62) Apr 23 2005 Any binary operator could be made to act unary,
- TechnoZeus (3/42) Apr 23 2005 Ironically, since the "@" symbol is usually pronounced "at" (in English ...
- TechnoZeus (18/69) Apr 21 2005 Correct me if I'm mistaken, but I think what you are saying only takes r...
- pragma (17/25) Apr 21 2005 The problem with your example in this argument is that it's ambiguous.
- pragma (4/33) Apr 21 2005 I should've double-checked before posting.
- TechnoZeus (5/50) Apr 22 2005 Actually, it's not ambiguous at all. At least, not to me... and I'm gue...
- Regan Heath (4/24) Apr 21 2005 It means call: b.opAssign(a+7);
- Brad Beveridge (3/13) Apr 21 2005 Which, is exactly the same as regular "=" precidence, ie the assignment
- TechnoZeus (3/16) Apr 22 2005 Yep.
- xs0 (26/48) Apr 21 2005 Hmm, isn't there a problem that if you do
- Vladimir (5/72) Apr 21 2005 Please, look at my post in different branch of this thread:
- xs0 (16/33) Apr 21 2005 With .init on classes:
- Vladimir (17/55) Apr 22 2005 Yes, you are right and I was wrong.
- TechnoZeus (4/37) Apr 22 2005 No, if the variable is uninitialized and a value is assigned, then assig...
- xs0 (19/73) Apr 25 2005 How exactly do you expect the compiler to know what is and what isn't
- TechnoZeus (8/12) Apr 27 2005 I don't expect the compiler to know the difference at that level. Right...
- xs0 (23/51) Apr 28 2005 No, it always copies the value. You just seem to think that the value of...
- TechnoZeus (12/63) Apr 29 2005 I realize more than you are aparently capable of comprehending.
- TechnoZeus (3/14) Apr 22 2005 No, there's no problem with it at all. You're thinking in C.
- Ben Hinkle (9/23) Apr 21 2005 [snip]
- Vladimir (12/14) Apr 21 2005 One of examples you can find at the end of my post in different branch o...
- Ben Hinkle (15/29) Apr 21 2005 A complete example from an actual project was what I had in mind. The po...
- Brad Beveridge (14/18) Apr 21 2005 I haven't written this yet, but I am pretty sure it is impossible:
- Ben Hinkle (19/36) Apr 21 2005 My first reaction is that the simplest solution is to use a regular link...
- TechnoZeus (4/30) Apr 22 2005 := wouldn't assign the value of a struct pointed to by it's right operan...
- Regan Heath (14/49) Apr 21 2005 Assuming .dup is added for intrinsics. However... Dereks original goal w...
- Vladimir (34/34) Apr 25 2005 Hello All !
- pragma (10/17) Apr 25 2005 Vlad,
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (7/9) Apr 25 2005 Change to the "d" directory (where you unpacked GDC 0.10) and:
- Vladimir (6/17) Apr 25 2005 Thanks for your support !
- Vladimir (31/39) Apr 25 2005 After thinking again:
I think this needs a new thread. Here is a snip of what I previously posted... I got to thinking about what languages try to achieve with allowing operator overloading, I think that they try to make user defined types behave exactly as intrinsics. This is especially important for a language that allows templates, as your templates should work with built in types and user defined types. A while ago Derek ran across a problem (thread title "opValue()") where his templates wouldn't work with aggregates because "=" does a reference copy, when he infact wanted a deep copy. I think that this is a similar problem - do programmers want their operators to do a reference compare, or a deep compare? In thinking along these lines I realised that D (at the moment) does not allow you to create user defined types that behave exactly as built in types, because user defined types (ie classes) are references, and built in types are not. It looks to me like there is a huge change in thinking required between using built in types and user defined types. Now, for most objects I think that references are correct and efficient. However for the objects that are designed to look at act like built in types (ie, BigNum implementation), then they will NEVER behave exactly like built ins. So I think the real question might be - how do we bridge the gap between user defined types and built in types? This gap doesn't only show up in operators, but in passing values/references to functions. ... I'll now solicit opinions and thoughts from the floor :) I don't know enough about OO, or do enough pure software programming to know the right answer. Brad
Apr 13 2005
brad domain.invalid wrote:I think this needs a new thread. Here is a snip of what I previously posted... I got to thinking about what languages try to achieve with allowing operator overloading, I think that they try to make user defined types behave exactly as intrinsics. This is especially important for a language that allows templates, as your templates should work with built in types and user defined types. A while ago Derek ran across a problem (thread title "opValue()") where his templates wouldn't work with aggregates because "=" does a reference copy, when he infact wanted a deep copy. I think that this is a similar problem - do programmers want their operators to do a reference compare, or a deep compare? In thinking along these lines I realised that D (at the moment) does not allow you to create user defined types that behave exactly as built in types, because user defined types (ie classes) are references, and built in types are not. It looks to me like there is a huge change in thinking required between using built in types and user defined types. Now, for most objects I think that references are correct and efficient. However for the objects that are designed to look at act like built in types (ie, BigNum implementation), then they will NEVER behave exactly like built ins. So I think the real question might be - how do we bridge the gap between user defined types and built in types? This gap doesn't only show up in operators, but in passing values/references to functions. .... I'll now solicit opinions and thoughts from the floor :) I don't know enough about OO, or do enough pure software programming to know the right answer. BradIsn't a struct exactly what you want? It can have methods and operators and whatnot, yet has value semantics instead of reference semantics...
Apr 14 2005
xs0 wrote:brad domain.invalid wrote:Except that structs don't have constructors and destructors... which makes them second class objects.I think this needs a new thread. Here is a snip of what I previously posted... I got to thinking about what languages try to achieve with allowing operator overloading, I think that they try to make user defined types behave exactly as intrinsics. This is especially important for a language that allows templates, as your templates should work with built in types and user defined types. A while ago Derek ran across a problem (thread title "opValue()") where his templates wouldn't work with aggregates because "=" does a reference copy, when he infact wanted a deep copy. I think that this is a similar problem - do programmers want their operators to do a reference compare, or a deep compare? In thinking along these lines I realised that D (at the moment) does not allow you to create user defined types that behave exactly as built in types, because user defined types (ie classes) are references, and built in types are not. It looks to me like there is a huge change in thinking required between using built in types and user defined types. Now, for most objects I think that references are correct and efficient. However for the objects that are designed to look at act like built in types (ie, BigNum implementation), then they will NEVER behave exactly like built ins. So I think the real question might be - how do we bridge the gap between user defined types and built in types? This gap doesn't only show up in operators, but in passing values/references to functions. .... I'll now solicit opinions and thoughts from the floor :) I don't know enough about OO, or do enough pure software programming to know the right answer. BradIsn't a struct exactly what you want? It can have methods and operators and whatnot, yet has value semantics instead of reference semantics...
Apr 14 2005
"Jan-Eric Duden" <jeduden whisset.com> wrote in message news:425E4730.5080908 whisset.com...xs0 wrote:[----] I posted a solution to this problem in another thread, but it's such a long thread that most people probably skipped all or most of it. I know I only skimmed it myself, and missed the beginning of the thread entirely. Anyway, here it is again, since I think it should answer your question well (with additions and improvements)... For anything that the default opCmp() function (and therefore the "==" operator) currently compares the addresses rather than the contents, Change the opCmp() function to perform as follows (in this order, exiting when a return value has been established) when comparing (first_item == second_item)... If both items being compared are void, return 0 (equals). If first_item is void then return -1 (less than). If second_item is void then return 1 (greater than). Compare identities and return 0 (equals) if identical. Compare sizes and scan for the first difference within the smaller size number of bytes. If no differences are found, return the sign of the difference between the sizes. Otherwise return the sign of the difference at that location where the first difference was found. Furthermore, for any items that the "is" operator currently compares the contents by default, change it to instead compare the locations that they are stored at, if known. As nonsensical as that may seem, it would at least me consistant functionality of the operator, and there may even turn out to be emergent uses for it. Perhaps some simple override could allow programmers to change "is" back to comparing the contents for things like numeric litterals rather than their addresses, for those that choose to use it that way, or to support backward compatability... but I would consider that a minor issue. If the location of one or more of the items being compared is unknown (if this is even possible, but I don't see how it could be), then default to comparing the value or contents of the items. This way, all of the comparator operators would function predictably in a way that could be defined independant of what is being compared. The comparison would be efficient when possible, and would always be an accurate and predictable comparison that can be described without knowledge of what kinds of things are being compared. The least efficient case would be when the entire contents of the two items is searched for differences, and that would only happen if no differences were found before that and the two items were not one and the same. This could actually be accomplished rather quickly even if the items have very large contents, since the default comparison would be doing a very straight forward comparison independant of what kind of items are being compared. Optionally (this part may need some input) an exception could be raised is the contents of two items are found to be identical but no cast from one item to the other is known, since this would in some ways indicate that they may not actually be really "equal" afterall. There would no longer be ambiguous overlap between the "==" operator and the "is" operator, as each would have a clearly defined default function. In cases where the old functionality is wanted, or where a faster or otherwise different functionality is wanted, the operators could still be overriden, and any built-in overrides for certain kinds of items could be made where possible to conform to the same criteria of using "is" to compare addresses or locations for equality and the operators based on opCmp() to compare values or contents for equality or inequality. Perhaps "is" could also have a corrsponding "is<" and "is>" added to give more information... or maybe "precedes", "follows" and "isnt" but for now, I think what I have offered here can be converted into an actual solution to the current ambiguity and overlap of the "is" and "==" functionality. Okay... I'm tired, and I know I've made some mistakes in typing this... some of them potentially rather substantial.. for example, I am pretty sure I made a reference to an integer NAN value. If so... take that to mean something like "raise and exception" or what ever would make sense, because I'm just too tired to go back and edit it. I'm sending this as is, because I don't want to risk passing out at the keyboard from exhaustion, and hopefully it will still turn out to be helpful. It's been a rough day... but tomorrows another one. Oh, that didn't come out right at all. Hehe. Goodnight. TechnoZeusbrad domain.invalid wrote:Except that structs don't have constructors and destructors... which makes them second class objects.I think this needs a new thread. Here is a snip of what I previously posted... I got to thinking about what languages try to achieve with allowing operator overloading, I think that they try to make user defined types behave exactly as intrinsics. This is especially important for a language that allows templates, as your templates should work with built in types and user defined types. A while ago Derek ran across a problem (thread title "opValue()") where his templates wouldn't work with aggregates because "=" does a reference copy, when he infact wanted a deep copy. I think that this is a similar problem - do programmers want their operators to do a reference compare, or a deep compare? In thinking along these lines I realised that D (at the moment) does not allow you to create user defined types that behave exactly as built in types, because user defined types (ie classes) are references, and built in types are not. It looks to me like there is a huge change in thinking required between using built in types and user defined types. Now, for most objects I think that references are correct and efficient. However for the objects that are designed to look at act like built in types (ie, BigNum implementation), then they will NEVER behave exactly like built ins. So I think the real question might be - how do we bridge the gap between user defined types and built in types? This gap doesn't only show up in operators, but in passing values/references to functions. .... I'll now solicit opinions and thoughts from the floor :) I don't know enough about OO, or do enough pure software programming to know the right answer. BradIsn't a struct exactly what you want? It can have methods and operators and whatnot, yet has value semantics instead of reference semantics...
Apr 14 2005
I'm afraid that only solves portions of the problem as I see it. The main dividing line is that all builtin objects (and structs) are always value, but Objects are always by reference. Which means - the assignment operator "=" can behave differently - function arguments can be either value or reference And other things I am sure are broken as well. This kind of thing mostly (I think) bites you when writing templates that can take both built-in types and user defined types. Brad
Apr 14 2005
In article <d3mjsr$1obd$1 digitaldaemon.com>, brad domain.invalid says...I'm afraid that only solves portions of the problem as I see it. The main dividing line is that all builtin objects (and structs) are always value, but Objects are always by reference. Which means - the assignment operator "=" can behave differently - function arguments can be either value or reference And other things I am sure are broken as well. This kind of thing mostly (I think) bites you when writing templates that can take both built-in types and user defined types.Just a thought: would having ".dup" available universally help the assignment problem? int a,b; Integer c,d; a = b.dup; // duplicate the value of b c = d.dup; // duplicate the value of object d ('deep' copy) I would expect the signature "T opDup()" to be used in case of objects; providing it as a base member on Object would force the return type to "Object" (messy). As for function arguments, you could try using "inout" for all parameters to ensure that value types are given reference semantics. It's not the best workaround, but it gets the job done. - EricAnderton at yahoo
Apr 14 2005
"pragma" <pragma_member pathlink.com> wrote in message news:d3ml8g$1pgv$1 digitaldaemon.com...In article <d3mjsr$1obd$1 digitaldaemon.com>, brad domain.invalid says...How about giving all items, including litterals, two properties as follows? .contents and .address such that .conents always means the internal value or contents of an item, and .address always means the location of that item in memory? For example, if X is an integer, then (X.address == 0) would compare the address of X with the integer value 0, while (X.contents == 0) would conpare the integer value of X with the integer value 0, and Y is an object, then (Y.address == 0) would compare the address in memory where the contents of Y are stored to the integer value 0, while (Y.contents == 0) would by default compare the bit pattern of the contents of Y with the bit pattern of the numeric litteral 0. This concept can actually be generallized to the point where one can code things like "if (12.address >= "hello".address){printf("the string was stored at a lower memory address than the number.");}" and there it allows instant removal of ambiguity no matter what kinds of things you're working with, as well as the ability to copy the contents of any object with a simple assignment such as "Y.contents = Z.contents" without wondering if you're going to end up making Y and Z point to the same object. Of course, I still think that the ambiguity should be removed from operators like "is" and "==" as much as reasonably possible, but a set of universal attributes like this would also help to facilitate that goal. TechnoZeusI'm afraid that only solves portions of the problem as I see it. The main dividing line is that all builtin objects (and structs) are always value, but Objects are always by reference. Which means - the assignment operator "=" can behave differently - function arguments can be either value or reference And other things I am sure are broken as well. This kind of thing mostly (I think) bites you when writing templates that can take both built-in types and user defined types.Just a thought: would having ".dup" available universally help the assignment problem? int a,b; Integer c,d; a = b.dup; // duplicate the value of b c = d.dup; // duplicate the value of object d ('deep' copy) I would expect the signature "T opDup()" to be used in case of objects; providing it as a base member on Object would force the return type to "Object" (messy). As for function arguments, you could try using "inout" for all parameters to ensure that value types are given reference semantics. It's not the best workaround, but it gets the job done. - EricAnderton at yahoo
Apr 14 2005
How about giving all items, including litterals, two properties as follows? .contents and .address such that .conents always means the internal value or contents of an item, and .address always means the location of that item in memory? For example, if X is an integer, then (X.address == 0) would compare the address of X with the integer value 0, while (X.contents == 0) would conpare the integer value of X with the integer value 0, and Y is an object, then (Y.address == 0) would compare the address in memory where the contents of Y are stored to the integer value 0, while (Y.contents == 0) would by default compare the bit pattern of the contents of Y with the bit pattern of the numeric litteral 0. This concept can actually be generallized to the point where one can code things like "if (12.address >= "hello".address){printf("the string was stored at a lower memory address than the number.");}" and there it allows instant removal of ambiguity no matter what kinds of things you're working with, as well as the ability to copy the contents of any object with a simple assignment such as "Y.contents = Z.contents" without wondering if you're going to end up making Y and Z point to the same object. Of course, I still think that the ambiguity should be removed from operators like "is" and "==" as much as reasonably possible, but a set of universal attributes like this would also help to facilitate that goal. TechnoZeusThat has a lot of appeal, but certainly is a lot of typing. It would be nice to always have those properties so that in the cases you need to be sure you can be totally unambigious. I agree that "==" and "is" should be kept & as un-ambigious as possible. BTW - this is a problem that every language I can think of has - built in primitives are value, objects are generally reference/pointer. Maybe it would be interesting to make the builtins defaultly by reference? Brad
Apr 14 2005
I haven't worked with it since it was still in it's beta development, so I'm worked out years ago. Their solution was to allow all litterals to be treated as objects when the programmer chose to do so, and to add in a set of properties similar to what I have mentioned here, which were a part of every object. By allowing litterals to be boxed up as objects when an object based property access was attempted, they had made it unnecessary to distinguish between them other than for the sake of writing efficient code. This is my point. Make it consistant and easy to learn. Those who have gotten past the newbie phase can then concentrate on writing more efficient code while those who haven't can concentrate on graduating to the next level. This goes not only for the programming language as a whole, but also for any part of it that is still to any reasonable degree unfamilliar to a particular person, and by extension, to the tools used by programmers to facilitate programming in the language. TZ <brad domain.invalid> wrote in message news:d3ms27$1vb1$1 digitaldaemon.com...How about giving all items, including litterals, two properties as follows? .contents and .address such that .conents always means the internal value or contents of an item, and .address always means the location of that item in memory? For example, if X is an integer, then (X.address == 0) would compare the address of X with the integer value 0, while (X.contents == 0) would conpare the integer value of X with the integer value 0, and Y is an object, then (Y.address == 0) would compare the address in memory where the contents of Y are stored to the integer value 0, while (Y.contents == 0) would by default compare the bit pattern of the contents of Y with the bit pattern of the numeric litteral 0. This concept can actually be generallized to the point where one can code things like "if (12.address >= "hello".address){printf("the string was stored at a lower memory address than the number.");}" and there it allows instant removal of ambiguity no matter what kinds of things you're working with, as well as the ability to copy the contents of any object with a simple assignment such as "Y.contents = Z.contents" without wondering if you're going to end up making Y and Z point to the same object. Of course, I still think that the ambiguity should be removed from operators like "is" and "==" as much as reasonably possible, but a set of universal attributes like this would also help to facilitate that goal. TechnoZeusThat has a lot of appeal, but certainly is a lot of typing. It would be nice to always have those properties so that in the cases you need to be sure you can be totally unambigious. I agree that "==" and "is" should be kept & as un-ambigious as possible. BTW - this is a problem that every language I can think of has - built in primitives are value, objects are generally reference/pointer. Maybe it would be interesting to make the builtins defaultly by reference? Brad
Apr 14 2005
However for the objects that are designed to look at act like built in types (ie, BigNum implementation), then they will NEVER behave exactly like built ins.I didn't have many problems mimicing a primitive numeric type when implementing the "big num" gmp wrapper. It's a class so you have to 'new' them, so that's one difference. Another is that toString is a member function instead of a top-level function. It would be nice to make it easier to write template code that works for both primitive, structs and classes when it makes sense, but I see that as a post-1.0 feature. Since the operator overloading returns new objects there isn't a problem of reference vs value. In general big nums work just like ints or other primitives. Check out http://home.comcast.net/~benhinkle/gmp-d/
Apr 14 2005
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
Apr 15 2005
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
Apr 15 2005
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
Apr 15 2005
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: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.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.. xs0Argh! 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"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
Apr 15 2005
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)
Apr 15 2005
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
Apr 16 2005
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
Apr 16 2005
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
Apr 20 2005
TechnoZeus wrote: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.) TZI think we should campaign for ":=" right now. I don't think we need a special "identity assignment" operator just yet - but I am fully infavour of the ".value" and ".address" properties for all types. If people find they are typing "x.address = y.address" on a regular basis, then we would have a case for an address assignment operator. Walter - what do you think of this discussion? Cheers Brad
Apr 20 2005
Yes, I agree fully. Walter? Could we please have a ":=" value assignment opperator, that assigns values by default and never assigns an address unless that address is actually the value of the item (such as the value of a pointer, for example)? TZ "brad beveridge" <brad nowhere.com> wrote in message news:d458ge$2p8p$1 digitaldaemon.com...TechnoZeus wrote: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.) TZI think we should campaign for ":=" right now. I don't think we need a special "identity assignment" operator just yet - but I am fully infavour of the ".value" and ".address" properties for all types. If people find they are typing "x.address = y.address" on a regular basis, then we would have a case for an address assignment operator. Walter - what do you think of this discussion? Cheers Brad
Apr 20 2005
On Wed, 20 Apr 2005 03:20:01 -0500, TechnoZeus <TechnoZeus PeoplePC.com> wrote: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.Agreed.Therefore, it may be "possible" but undesireable to allow identity assignemnts to value types in general.Something like: int a,b; &a = &b; This would effectively ignore the memory 'a' occupied and make 'a' and alias of 'b'.In cases where it is desireable, pointers would suffice.Pointers are a piece of memory whose value is the address of a piece of memory. (I'm sure you know this.. I'm just leading in..) They don't really facilitate identity assignment of value types, rather, they themselves have a fixed identity (the addres in which they are stored) and their value is the identity of something else (or themselves). You can assign to them another identiy, but this doesn't effect their identity, the identity of the value to which they are assigned or were previously assigned.Not an argument for or against anything you said... just a detail that I thought should be mentioned.Splitting hairs is fun, often I find it asks you to look at something in a different light, usually increasing understanding of the subject overall.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."=" is currently a reference assignment operator (for reference types) and a value assignment operator (for value types). I wasn't suggesting that it change in any way. I can see, re-reading my post, how by labelling it a "reference assignment" I might have given an impression of change, but note the "exception" I spoke of and my conclusion: <quote> 2. "=" does identity assignment ... 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. </quote> In short, leave it the same as it is currently.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,Yes.but add ":=" for value assignments,Yes.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.I don't see a point in this. All you're really doing is creating another name for an existing type, just like passing it into a function with "inout" does. Currently you can achieve this by: - passing it into a function using 'inout'. - using "alias". Personally I have never had the need to alias an existing type in this way. However, thinking about it... If _anything_ I would suggest adding a referece type specifier, eg. int a; int& b; //reference type, like C++ reference parameters to functions. b = a; //reference assignment, as 'b' is a reference type; b = 5; //assigns 'a' to 5 assert(a == b); this would have the syntax of a value type, but be a reference to some other value type elsewhere. Note, the "=" operator does not change in any way and no explicit identity assignment operator is required. However, if these were added then "is" would need to change to handle "if (b is a)" i.e. is "b" a reference to "a", luckily the LHS is a reference type, so this might not be too hard to manage.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.Assuming: - there is little need to assign identity for value types. - we have methods to do so, inout, alias. or we add a reference type for value types. then I see no point in this.Most important though of all that's been mentioned in this thread, in my opinion, would be the addition of a ":=" value assigment operator.Agreed.(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.)I like how the current operators function. They already cover all the bases defaulting to the most sensible operation. Regan"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:comparison isMy 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 ofIfcompared using identity. If identity is equal, value will be equal.assumeidentity is not equal then given no way to compare value one mustlittleinequality 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 seepoint 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
Apr 20 2005
Regan Heath wrote:Assuming: - there is little need to assign identity for value types.Yes, but suppose someone (for example with python background) after reading that '=' is identity assignment operator decided to implement some features relying on it, for example symmetric matrixes: for(i=0; i<10; i++) for(j=0; j<i; j++) matrix[j][i] = matrix[i][j]; ... matrix[1][2] = 10; If matrix is array of objects then we have matrix[1][2] = matrix[2][1] = 10, but it differs for built-in types. May be just disallow of using '=' for built-in types and allow only ':=', but for classes allow both of them ?- we have methods to do so, inout, alias. or we add a reference type for value types.alias is compile-time construction, isn't it ? -- Vladimir
Apr 20 2005
On Wed, 20 Apr 2005 17:21:59 +0400, Vladimir <kv11111 mail.ru> wrote:Regan Heath wrote:True.Assuming: - there is little need to assign identity for value types.Yes, but suppose someone (for example with python background) after reading that '=' is identity assignment operator decided to implement some features relying on it, for example symmetric matrixes: for(i=0; i<10; i++) for(j=0; j<i; j++) matrix[j][i] = matrix[i][j]; ... matrix[1][2] = 10; If matrix is array of objects then we have matrix[1][2] = matrix[2][1] = 10, but it differs for built-in types.May be just disallow of using '=' for built-in types and allow only ':=', but for classes allow both of them ?If your intention is to assign "value" then you'd use ":=" not "=".True. "inout" is the only runtime one. I'm still not convinced of the need to alias value types. However, assuming there is a need I would use a "basic reference type" i.e. "int a; int& b;" (see my last post for more details). Regan Regan- we have methods to do so, inout, alias. or we add a reference type for value types.alias is compile-time construction, isn't it ?
Apr 20 2005
On Thu, 21 Apr 2005 09:36:30 +1200, Regan Heath <regan netwin.co.nz> wrote:On Wed, 20 Apr 2005 17:21:59 +0400, Vladimir <kv11111 mail.ru> wrote:If they read this, it was poorly written because it's untrue. (I did try to qualify my statement when I said that, didn't I?)Regan Heath wrote:Assuming: - there is little need to assign identity for value types.Yes, but suppose someone (for example with python background) after reading that '=' is identity assignment operatorOr, flipside, if your intention was to assign "identity".. If your matrix contained value types it would not work, so... 1. Currently you could use "int*" to achieve what you want. 2. Or, adding a "basic reference type" i.e. "int& a" would allow you to have a matrix of them, and get identity assignment. 3. Of course, adding an identity assignment operator and allowing identity assignment for value types would also work (provided you used that operator). where a reference type is required. Regandecided to implement some features relying on it, for example symmetric matrixes: for(i=0; i<10; i++) for(j=0; j<i; j++) matrix[j][i] = matrix[i][j]; ... matrix[1][2] = 10; If matrix is array of objects then we have matrix[1][2] = matrix[2][1] = 10, but it differs for built-in types.True.May be just disallow of using '=' for built-in types and allow only ':=', but for classes allow both of them ?If your intention is to assign "value" then you'd use ":=" not "=".
Apr 20 2005
Not sure whether this would be advantageous or not, but perhaps the "=" operator could be deprecated where it functions as a value assignment operator, so that it could be phased out in that capacity. Okay... separate thread on a thought about deprecation, comming up. :) TZ "Regan Heath" <regan netwin.co.nz> wrote in message news:opspjwazw323k2f5 nrage.netwin.co.nz...On Thu, 21 Apr 2005 09:36:30 +1200, Regan Heath <regan netwin.co.nz> wrote:On Wed, 20 Apr 2005 17:21:59 +0400, Vladimir <kv11111 mail.ru> wrote:If they read this, it was poorly written because it's untrue. (I did try to qualify my statement when I said that, didn't I?)Regan Heath wrote:Assuming: - there is little need to assign identity for value types.Yes, but suppose someone (for example with python background) after reading that '=' is identity assignment operatorOr, flipside, if your intention was to assign "identity".. If your matrix contained value types it would not work, so... 1. Currently you could use "int*" to achieve what you want. 2. Or, adding a "basic reference type" i.e. "int& a" would allow you to have a matrix of them, and get identity assignment. 3. Of course, adding an identity assignment operator and allowing identity assignment for value types would also work (provided you used that operator). where a reference type is required. Regandecided to implement some features relying on it, for example symmetric matrixes: for(i=0; i<10; i++) for(j=0; j<i; j++) matrix[j][i] = matrix[i][j]; ... matrix[1][2] = 10; If matrix is array of objects then we have matrix[1][2] = matrix[2][1] = 10, but it differs for built-in types.True.May be just disallow of using '=' for built-in types and allow only ':=', but for classes allow both of them ?If your intention is to assign "value" then you'd use ":=" not "=".
Apr 20 2005
Regan Heath wrote:On Thu, 21 Apr 2005 09:36:30 +1200, Regan Heath <regan netwin.co.nz> wrote:But not in general templates. For classes type C* means pointer to reference (and I do not understand why we need both references and pointers for classes).On Wed, 20 Apr 2005 17:21:59 +0400, Vladimir <kv11111 mail.ru> wrote:If they read this, it was poorly written because it's untrue. (I did try to qualify my statement when I said that, didn't I?)Regan Heath wrote:Assuming: - there is little need to assign identity for value types.Yes, but suppose someone (for example with python background) after reading that '=' is identity assignment operatorOr, flipside, if your intention was to assign "identity".. If your matrix contained value types it would not work, so... 1. Currently you could use "int*" to achieve what you want.decided to implement some features relying on it, for example symmetric matrixes: for(i=0; i<10; i++) for(j=0; j<i; j++) matrix[j][i] = matrix[i][j]; ... matrix[1][2] = 10; If matrix is array of objects then we have matrix[1][2] = matrix[2][1] = 10, but it differs for built-in types.True.May be just disallow of using '=' for built-in types and allow only ':=', but for classes allow both of them ?If your intention is to assign "value" then you'd use ":=" not "=".2. Or, adding a "basic reference type" i.e. "int& a" would allow you to have a matrix of them, and get identity assignment.I think this is reasonable. For value-types T& will be reference type, but for classes C& makes no sense so we can make C& be the same type as C.3. Of course, adding an identity assignment operator and allowing identity assignment for value types would also work (provided you used that operator).This seems to be really hard to implement. Compiled languages have no run-time symbol tables, they assigns address to variable at compile time, and it can't be changed at run-time.where a reference type is required. ReganIn C++ there were value-type and reference-type for any class or built-in type. In D we have only reference-type for classes and only value-type for anything else (pointers are something else). Adding := operator will smooth this asymmetry, but not remove it totally. I can see at least these remaining problems: 1. absent reference-type for non-classes (discussed above). 2. reference-type variable are always initialized to null, while value-type can't be null 3. different behavior of 'is' operator for value-type and reference-type. To illustrate some of this: /* Class for calculation some difficult function and caching result */ /* Suppose reverse function is easy to calculate */ class SomeFunction(T) { T _cached_val; T calculate(T input) { /* if T is class we have seg-v here at first invocation * because _cached_val is null */ if(input == calculate_reverse(_cached_val)) /* if T is class then by returning _cached_val we allow caller * to change it and hurt our presious cache */ return _cached_val; /* if we have := we can write * { R t := _chached_val; return t; } * but it's ugly and slow if R is big value-type struct */ /* if T is value-type it won't compile */ if( _cached_val is null ) {} /* here we obviously need := */ _cached_for = input; /* here we change caller's variable if T is class, * and := can't solve out problem */ input += 10; ... /* again we have problem here */ return _cached_val; } T calculate_reverse(T input) { ... } } -- Vladimir
Apr 21 2005
Vladimir wrote: <snip>To illustrate some of this:<snip> Vladimir - that is a fantastic example of the disconnect between reference types and value types, and how screwed up you could potentially get with templates. You've also illustrated that the := operator doesn't really cut it in terms of making life better. Can we come up with something that fixes this? Brad
Apr 21 2005
Define "better" in that context. True, it wouldn't solve "all" problems, but then again, nothing ever will. There are obviously advantages to adding a := operator for value assignments, and I have yet to hear a down side to it. TZ "brad beveridge" <brad nowhere.com> wrote in message news:d47ro7$2lem$1 digitaldaemon.com...Vladimir wrote: <snip>To illustrate some of this:<snip> Vladimir - that is a fantastic example of the disconnect between reference types and value types, and how screwed up you could potentially get with templates. You've also illustrated that the := operator doesn't really cut it in terms of making life better. Can we come up with something that fixes this? Brad
Apr 21 2005
"TechnoZeus" <TechnoZeus PeoplePC.com> wrote in message news:d48b73$2m6$1 digitaldaemon.com...Define "better" in that context. True, it wouldn't solve "all" problems, but then again, nothing ever will. There are obviously advantages to adding a := operator for value assignments, and I have yet to hear a down side to it. TZhttp://www.digitalmars.com/d/faq.html#assignmentoverloading
Apr 21 2005
"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d48chi$48n$1 digitaldaemon.com..."TechnoZeus" <TechnoZeus PeoplePC.com> wrote in message news:d48b73$2m6$1 digitaldaemon.com...Hi Ben. Why the link to information about assignment overloading? TZDefine "better" in that context. True, it wouldn't solve "all" problems, but then again, nothing ever will. There are obviously advantages to adding a := operator for value assignments, and I have yet to hear a down side to it. TZhttp://www.digitalmars.com/d/faq.html#assignmentoverloading
Apr 21 2005
That's what this discussion on := and opAssign are about. Walter has already thought about overloading assignment and it has come up before on the newsgroup (I actually found that link during a quick search of the archives).Why the link to information about assignment overloading?There are obviously advantages to adding a := operator for value assignments, and I have yet to hear a down side to it.http://www.digitalmars.com/d/faq.html#assignmentoverloading
Apr 21 2005
Ben Hinkle wrote:This discussion is not about opAssign overloading, but about problems when writing general templates that must work with classes as well as with fundamental types. Addition of := operator may require making it overloadable because of external resource allocation (not only memory allocation but also opened files, DB connections and so on). Allowing := overloading also will solve casting problem (for example ability to write BigInt class in such way that code { BigInt i; i:=100; } can be compiled), but this is just side-effect. But again, even adding this operator will not solve the whole problem with general templates. -- VladimirThat's what this discussion on := and opAssign are about. Walter has already thought about overloading assignment and it has come up before on the newsgroup (I actually found that link during a quick search of the archives).Why the link to information about assignment overloading?There are obviously advantages to adding a := operator for value assignments, and I have yet to hear a down side to it.http://www.digitalmars.com/d/faq.html#assignmentoverloading
Apr 21 2005
It's a big thread... that might have been in it somewhere. This branch of it deals with adding ":=" as a separate operator in addition to the "=" operator, and having ":=" act as a value assignment operator such that... a := b; anways results in (a == b) being true, but never makes (a is b) become true. Not related to overloading the "=" operator. TZ "Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d48dc2$54g$1 digitaldaemon.com...That's what this discussion on := and opAssign are about. Walter has already thought about overloading assignment and it has come up before on the newsgroup (I actually found that link during a quick search of the archives).Why the link to information about assignment overloading?There are obviously advantages to adding a := operator for value assignments, and I have yet to hear a down side to it.http://www.digitalmars.com/d/faq.html#assignmentoverloading
Apr 21 2005
"TechnoZeus" <TechnoZeus PeoplePC.com> wrote in message news:d48iic$9se$1 digitaldaemon.com...It's a big thread... that might have been in it somewhere. This branch of it deals with adding ":=" as a separate operator in addition to the "=" operator, and having ":=" act as a value assignment operator such that... a := b; anways results in (a == b) being true, but never makes (a is b) become true. Not related to overloading the "=" operator. TZhehe. Sorry but it sounds funny to say an operator called := with overload opAssign is not related to overloading assignment. I would bet no matter what the symbol is and the overload name Walter's objections would still apply. ps - I should have asked you to do my taxes :-)
Apr 21 2005
On Thu, 21 Apr 2005 12:44:35 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:"TechnoZeus" <TechnoZeus PeoplePC.com> wrote in message news:d48iic$9se$1 digitaldaemon.com...But they don't as far as I can see. Reading: http://www.digitalmars.com/d/faq.html#assignmentoverloading and remembering he mentioned something along the lines of "overloading = causes subtle behaviour which is a source of bugs for little gain". 1. := is a new operator, so no subtle behaviour for = is added. 2. You could argue := has the subtle behaviour, but I argue it isn't subtle because if you use := you're asking for that behaviour. 3. The copy constructor argument is on the surface valid, but consider intrinsics which have no constructors at all. 4. Lastly .dup does not solve the whole problem, the original intent was to make this possible: class A{} class B{} A a = new A(); B b; b = a; construct a A using an A. So while you can write a copy constructor: class A { this(B b) {} } intrinsics don't have constructors so in a template: template(T) { void foo(T t) { B b = new B(); T t; t = new T(b); }} it doesn't work when T is 'int' etc. .dup does not solve the above as: t = b.dup returns a B not a T. However := solves both problems neatly. t := b; calls opAssign for type T (for intrinsics it would do what it currently does on assignment). ReganIt's a big thread... that might have been in it somewhere. This branch of it deals with adding ":=" as a separate operator in addition to the "=" operator, and having ":=" act as a value assignment operator such that... a := b; anways results in (a == b) being true, but never makes (a is b) become true. Not related to overloading the "=" operator. TZhehe. Sorry but it sounds funny to say an operator called := with overload opAssign is not related to overloading assignment. I would bet no matter what the symbol is and the overload name Walter's objections would still apply.
Apr 21 2005
"Regan Heath" <regan netwin.co.nz> wrote in message news:opspln2nhw23k2f5 nrage.netwin.co.nz...On Thu, 21 Apr 2005 12:44:35 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:I agree it's a matter of opinion what counts as subtle and what doesn't. The fact that users would know := can be subtle still makes it subtle. The argument that := isn't like = is too subtle for me ;-)"TechnoZeus" <TechnoZeus PeoplePC.com> wrote in message news:d48iic$9se$1 digitaldaemon.com...But they don't as far as I can see. Reading: http://www.digitalmars.com/d/faq.html#assignmentoverloading and remembering he mentioned something along the lines of "overloading = causes subtle behaviour which is a source of bugs for little gain". 1. := is a new operator, so no subtle behaviour for = is added. 2. You could argue := has the subtle behaviour, but I argue it isn't subtle because if you use := you're asking for that behaviour.It's a big thread... that might have been in it somewhere. This branch of it deals with adding ":=" as a separate operator in addition to the "=" operator, and having ":=" act as a value assignment operator such that... a := b; anways results in (a == b) being true, but never makes (a is b) become true. Not related to overloading the "=" operator. TZhehe. Sorry but it sounds funny to say an operator called := with overload opAssign is not related to overloading assignment. I would bet no matter what the symbol is and the overload name Walter's objections would still apply.3. The copy constructor argument is on the surface valid, but consider intrinsics which have no constructors at all. 4. Lastly .dup does not solve the whole problem, the original intent was to make this possible: class A{} class B{} A a = new A(); B b; b = a; construct a A using an A. So while you can write a copy constructor: class A { this(B b) {} } intrinsics don't have constructors so in a template: template(T) { void foo(T t) { B b = new B(); T t; t = new T(b); }} it doesn't work when T is 'int' etc.I think I need more context - I am missed the point..dup does not solve the above as: t = b.dup returns a B not a T. However := solves both problems neatly. t := b; calls opAssign for type T (for intrinsics it would do what it currently does on assignment).I don't really get the point so correct me if I'm wrong but I think your example is getting at converting a B into a T while copying the value. I agree dup only concerns itself with duplicating a value and not with casting it or converting it to something else. For that one needs other mechanisms and I would agree it's hard to write generic code in D that does conversions. The opCast is clunky because you can't overload it. Personally I'm not convinced := is the right way to solve the casting problem, though. Consider if D got something that let you say "t = cast(T)b". That would be cleaner than introducing := IMO. If a copy of the value is needed it could be "t = cast(T)b.dup".
Apr 21 2005
On Thu, 21 Apr 2005 21:40:45 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:I don't really get the point so correct me if I'm wrong but I think your example is getting at converting a B into a T while copying the value.Yes. Derek originally wanted to overload opCast by return type or something along those lines. After some thought I figured casting is actually just "copying the 'value' using some predefined method", i.e. casting from int to float copies the 'value' be it 5, 9 etc but uses some method to arrange the value in 'float' form. I also remembered a while back someone wanting a way to deep copy things. It occured to me a deep copy is also "copying the 'value' using some predefined method" where the source type is the same as the destination type. So then I figured, why not combine all these ideas into one thing, an operator that copies the 'value' from the RHS into the LHS, thus ":=".I agree dup only concerns itself with duplicating a value and not with casting it or converting it to something else. For that one needs other mechanisms and I would agree it's hard to write generic code in D that does conversions. The opCast is clunky because you can't overload it.Correct.Personally I'm not convinced := is the right way to solve the casting problem, though.I am not adverse to other suggestions...Consider if D got something that let you say "t = cast(T)b". That would be cleaner than introducing := IMO.Maybe. This would call some variant of opCast or something similar. Then you'd write a dup method when LHS and RHS are the same type. So you have opCast and dup methods, instead of opAssign methods. The latter just seems .. cleaner to me.If a copy of the value is needed it could be "t = cast(T)b.dup".Wouldn't "t = cast(T)b" have to copy anyway? Regan
Apr 21 2005
Using := as a value assignment operator would have more uses than just those related to casting. Yes, it is true that there could be advantages in that area, but they would be "emergent advantages" and would surface as a function of the implementation. TZ
Apr 22 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:d48l9l$cb7$1 digitaldaemon.com..."TechnoZeus" <TechnoZeus PeoplePC.com> wrote in message news:d48iic$9se$1 digitaldaemon.com...Yes, you're right. If that had been what we were saying, it would have sounded funny. TZIt's a big thread... that might have been in it somewhere. This branch of it deals with adding ":=" as a separate operator in addition to the "=" operator, and having ":=" act as a value assignment operator such that... a := b; anways results in (a == b) being true, but never makes (a is b) become true. Not related to overloading the "=" operator. TZhehe. Sorry but it sounds funny to say an operator called := with overload opAssign is not related to overloading assignment. I would bet no matter what the symbol is and the overload name Walter's objections would still apply. ps - I should have asked you to do my taxes :-)
Apr 22 2005
brad beveridge wrote:Vladimir wrote: <snip> Vladimir - that is a fantastic example of the disconnect between reference types and value types, and how screwed up you could potentially get with templates. You've also illustrated that the := operator doesn't really cut it in terms of making life better. Can we come up with something that fixes this?This post essentially sums up what I've been talking about for some time. 1) It is obvious that the difference between reference and value assignment does cause head aches. (For the non-gurus anyway. :-) ) 2) All of the discussion about "=" vs "==" (etc.) has actually been about this single issue (whether all the participants have realised it, or not.) 3) There seems not to exist an obvious solution, at least as far as we've got so far. 4) For all I know, there might not even exist a problem here. (!) OTOH, this does seem to be a thing that gets peoples' attention, and does seem to disturb people -- even if they come from C++ or Java. (Those coming from other languages, I'd _expect_ to get stuck with this issue.) 5) Considering that D is a "metal near language" (in the spirit of C), and a high level language (in the spirit of C++ and Java -- but not ever aspiring to the level of Lisp), it is natural, that this distinction is prominent in the language -- after all, the distinction is very visible in assembler and C. (And in processor architecture.) 6) As a side effect of this, the discussion of .value and .reference, as well as (a part of) the discussion of comparability vs. equality, has arisen. On the surface, there would exist a number of "solutions". - Create two distinct assignment operators. - := and =. - Have each do its part, and only then default to the other. - Have each do its part, and fail when applied wrong. - Have a war about which does which. - Somehow else separate value and reference assignment. - Using & or some other syntactic means. - Rely on the lvalue accepting only either. I could go on with this list, as anybody else could, too. But what I see here is, a lack of a common understanding and thorough insight between the two. Therefore, I suggest that we refrain from "Calling Walter" for quite some time with this issue. We really need to get to the bottom of this. (We might find nothing of value -- whence the existing status quo would suffice. Or, we might find something else, but then we'd know exactly what we want! By that time it would be "a piece of cake" to ask Walter to pay attention.) So far, however, this discussion (excuse me, everybody) hasn't turned up anything "new". Hey, I'm not putting any single person down, or the entire discussion. I'm just (like a referee, this time) "lifting the cat on the table" as we say in Finland, or writing the obvious on the wall. ----- I do (whaddayaknow) humbly admit here, that I haven't got a clear picture of the issue, so far. Somehow I "feel" that the distinction between value and reference, is, eh, unsharp. (Not as a concept, but as it is implemented in the _syntax_ (or, more to the point, the _semantics_) of quite a few languages, including D.) On one hand, I'd love a situation where there were two separate assignment operators (for example := and =), where neither would accept the "wrong" kind of rvalue nor lvalue. On the other hand, I feel that this would make programming cumbersome, introduce gratuituous obstacles, steer folks' attention to undeserving detail, and appear low-level upon the whole. ----- The distinction between value and reference is (to my (this time) not so humble opinion), very much less clear to the newcomer in D, as it is in C. The same problem occurred to me when initially learning Pascal. (Where it was actually less opaque than in D.) While people hate pointers and references in C, at least they are consistent (in _this_ respect, not necessarily in general). So, this discussion does carry some merit, IMHO. But let's not assume this is for D 1.0!!! Let's all accept that this discussion is about something bigger, and more fundamental, and therefore we'd be stupid to ecxpect that we'd reach the required level of common (or even individual) understanding before D 1.0 has been out for a long time. While I'm not suggesting that we get rid of imports or the need to write the main function (for the illiterate, see other thread), I do think that this issue is worth some serious study.
Apr 21 2005
Georg Wrede wrote: <snip>The distinction between value and reference is (to my (this time) not so humble opinion), very much less clear to the newcomer in D, as it is in C. The same problem occurred to me when initially learning Pascal. (Where it was actually less opaque than in D.) While people hate pointers and references in C, at least they are consistent (in _this_ respect, not necessarily in general). So, this discussion does carry some merit, IMHO.<snip> Excellent post Georg - and precisely the reason that I suggested "Walter Weigh In"s should first be sanctioned by senior members. We obviously haven't covered enough ground with this topic yet. As you say, the distinction between reference and value in D are not very clear - I personally think that such a fundamental concept should be clarified/fixed before v1.0 - but that is just IMHO. I'm afraid that I can't offer much more to this thread, so hopefully smarter people than me will figure something out. I must also say that I haven't personally run into this problem yet. Can someone who has run into this problem in real code make a post - otherwise we are simply intellectualising (and D is a practical language, not an acedemic one). I know that Derek wanted to convert one object to another, and that is possibly where the := operator stemed from, but other than that I don't think anyone else has posted about running into this in real life. Brad
Apr 21 2005
On Fri, 22 Apr 2005 10:49:45 +1200, Brad Beveridge wrote: [snip]I know that Derek wanted to convert one object to another, and that is possibly where the := operator stemed from, but other than that I don't think anyone else has posted about running into this in real life.BTW, I've resigned myself to using a 'Value' property in the classes I'm working with, as I can't see Walter bothering to make coding any easier for us ... class Foo { void Value(Bar x) { ... } } class Bar { void Value(Foo x) { ... } } Foo f = new Foo; Bar b = new Bar; Foo.Value = b; Bar.Value = f; -- Derek Melbourne, Australia 22/04/2005 10:55:07 AM
Apr 21 2005
class Foo { void Value(Bar x) { ... } } class Bar { void Value(Foo x) { ... } } Foo f = new Foo; Bar b = new Bar; Foo.Value = b; Bar.Value = f;Without knowing anything about the context, would using toFoo and toBar work? I use toFoo to "cast" to other types much like toString takes the object and returns a string. class Foo { Bar toBar() { ... } } class Bar { Foo toFoo() { ... } } Foo f = new Foo; Bar b = new Bar; Foo f2 = b.toFoo(); Bar b2 = f.toBar(); Note the original example Foo.Value = b doesn't compile - I assume you meant something like f.Value = b.
Apr 21 2005
On Thu, 21 Apr 2005 21:25:36 -0400, Ben Hinkle wrote:Yes it would work, but I use templates a lot, and there are more classes than just two, so that might be a problem. The syntax "<id>.Value = <id>" is a bit more generic.class Foo { void Value(Bar x) { ... } } class Bar { void Value(Foo x) { ... } } Foo f = new Foo; Bar b = new Bar; Foo.Value = b; Bar.Value = f;Without knowing anything about the context, would using toFoo and toBar work? I use toFoo to "cast" to other types much like toString takes the object and returns a string.Note the original example Foo.Value = b doesn't compile - I assume you meant something like f.Value = b.Oops! Just coding from the hip ;-) -- Derek Melbourne, Australia 22/04/2005 11:27:39 AM
Apr 21 2005
The problem isn't a lack of understanding. The problem in comming to a uniform agreement is mostly in the idea that there is only one right way to do something. A few people who are comfortable with the way things are oppose the addition of an alternative way of doing things because they see it as "not needed" since they personally don't need it. It's unfortunately an all too common way of looking at the world, and if that way of thinking were to be applied across the board, then since some people never program at all, we could consider any programming language to be completely useless, and since some people never use computers, we could consider all computers to be useless as well. In fact, if the only thing it takes for something to be useless is that "someone" fails to see the use for it, then by that logic, there is nothing in this world that is of any use at all. Personally, I favor looking at the world from a less egocentric point of view. If it's useful to "someone" then it is of value. The := operator would "obviously" be of use to "many" people, even if there are a few people who just don't see it. TZ "Georg Wrede" <georg.wrede nospam.org> wrote in message news:42682A29.8090300 nospam.org...brad beveridge wrote:Vladimir wrote: <snip> Vladimir - that is a fantastic example of the disconnect between reference types and value types, and how screwed up you could potentially get with templates. You've also illustrated that the := operator doesn't really cut it in terms of making life better. Can we come up with something that fixes this?This post essentially sums up what I've been talking about for some time. 1) It is obvious that the difference between reference and value assignment does cause head aches. (For the non-gurus anyway. :-) ) 2) All of the discussion about "=" vs "==" (etc.) has actually been about this single issue (whether all the participants have realised it, or not.) 3) There seems not to exist an obvious solution, at least as far as we've got so far. 4) For all I know, there might not even exist a problem here. (!) OTOH, this does seem to be a thing that gets peoples' attention, and does seem to disturb people -- even if they come from C++ or Java. (Those coming from other languages, I'd _expect_ to get stuck with this issue.) 5) Considering that D is a "metal near language" (in the spirit of C), and a high level language (in the spirit of C++ and Java -- but not ever aspiring to the level of Lisp), it is natural, that this distinction is prominent in the language -- after all, the distinction is very visible in assembler and C. (And in processor architecture.) 6) As a side effect of this, the discussion of .value and .reference, as well as (a part of) the discussion of comparability vs. equality, has arisen. On the surface, there would exist a number of "solutions". - Create two distinct assignment operators. - := and =. - Have each do its part, and only then default to the other. - Have each do its part, and fail when applied wrong. - Have a war about which does which. - Somehow else separate value and reference assignment. - Using & or some other syntactic means. - Rely on the lvalue accepting only either. I could go on with this list, as anybody else could, too. But what I see here is, a lack of a common understanding and thorough insight between the two. Therefore, I suggest that we refrain from "Calling Walter" for quite some time with this issue. We really need to get to the bottom of this. (We might find nothing of value -- whence the existing status quo would suffice. Or, we might find something else, but then we'd know exactly what we want! By that time it would be "a piece of cake" to ask Walter to pay attention.) So far, however, this discussion (excuse me, everybody) hasn't turned up anything "new". Hey, I'm not putting any single person down, or the entire discussion. I'm just (like a referee, this time) "lifting the cat on the table" as we say in Finland, or writing the obvious on the wall. ----- I do (whaddayaknow) humbly admit here, that I haven't got a clear picture of the issue, so far. Somehow I "feel" that the distinction between value and reference, is, eh, unsharp. (Not as a concept, but as it is implemented in the _syntax_ (or, more to the point, the _semantics_) of quite a few languages, including D.) On one hand, I'd love a situation where there were two separate assignment operators (for example := and =), where neither would accept the "wrong" kind of rvalue nor lvalue. On the other hand, I feel that this would make programming cumbersome, introduce gratuituous obstacles, steer folks' attention to undeserving detail, and appear low-level upon the whole. ----- The distinction between value and reference is (to my (this time) not so humble opinion), very much less clear to the newcomer in D, as it is in C. The same problem occurred to me when initially learning Pascal. (Where it was actually less opaque than in D.) While people hate pointers and references in C, at least they are consistent (in _this_ respect, not necessarily in general). So, this discussion does carry some merit, IMHO. But let's not assume this is for D 1.0!!! Let's all accept that this discussion is about something bigger, and more fundamental, and therefore we'd be stupid to ecxpect that we'd reach the required level of common (or even individual) understanding before D 1.0 has been out for a long time. While I'm not suggesting that we get rid of imports or the need to write the main function (for the illiterate, see other thread), I do think that this issue is worth some serious study.
Apr 22 2005
Vladimir wrote:/* Class for calculation some difficult function and caching result */ /* Suppose reverse function is easy to calculate */ class SomeFunction(T) { T _cached_val; T calculate(T input) { /* if T is class we have seg-v here at first invocation * because _cached_val is null */ if(input == calculate_reverse(_cached_val)) 2. reference-type variable are always initialized to null, whilevalue-type can't be null One of possible solutions for this is to add static init property for classes: class A { /* example */ static A init = new A(0,0); /* evaluated only once */ /* default is: static A init = null; } */ } and then treat expression A a; as A a = A.init; (this is exactly the same as with fundamental types) so A a; A b; if((a is b) and (a is A.init)) writef(" true "); will print "true" -- Vladimir
Apr 21 2005
I should have been more clear in what I stated about pointers. What I meant was that the :=" operator should effect "their own" value (which is the address of what they are pointing to) rather than the value of the anything that they might be pointing to. In other words, that the value assignment operator should do direct value assignemts. No compromises. I think a separate identity assignment operator would be overkill, but I had included mention of it for completeness. The addition of ".value" and ".identity" support would allow a way for programmers to avoid any ambiguity, which would probably not get used a lot in the long run, but would definately be nice to have as an option... especially for beginners who are not sure of whether something is a value type or a reference type. These members would allow them to treat "anything" as a value type, or as a reference type (maybe it should be .reference rather than .identity?), regardless of what it is... and it would also be nice for searching the source code later. As for +:= and so on... Not important at this time, but worth thinking about... in my opinion. Hopefully when Walter has time to look in here, he'll give the ":=" value assignment operator strong consideration. I don't know how he feels about bringing in programmers from different backgrounds, but I think the addition of a ":=" assignment operator would be a good step in that direction, due to people experienced in certain other languages finding it familliar and comfortable. TZ
Apr 20 2005
On Wed, 20 Apr 2005 17:44:15 -0500, TechnoZeus <TechnoZeus PeoplePC.com> wrote:I should have been more clear in what I stated about pointers. What I meant was that the :=" operator should effect "their own" value (which is the address of what they are pointing to) rather than the value of the anything that they might be pointing to.Just like "=" does currently.In other words, that the value assignment operator should do direct value assignemts. No compromises. I think a separate identity assignment operator would be overkill, but I had included mention of it for completeness.Then we are in agreement, pretty much.The addition of ".value" and ".identity" support would allow a way for programmers to avoid any ambiguity, which would probably not get used a lot in the long run, but would definately be nice to have as an option...Maybe, I'm not sold on the idea yet.especially for beginners who are not sure of whether something is a value type or a reference type. These members would allow them to treat "anything" as a value type, or as a reference type (maybe it should be .reference rather than .identity?), regardless of what it is...But wouldn't this just train bad habits. Assuming using .value etc is only intended for beginners and you should really learn the difference between value and reference types.Hopefully when Walter has time to look in here, he'll give the ":=" value assignment operator strong consideration.Fingers crossed. Regan
Apr 20 2005
Yes, for the most part, we are in agreement... is one of the things I was trying to clarify. (stating it outright does tend to help.) As for letting beginners use ".value" and ".identity" to avoid ambiguity, I wouldn't consider than enforcing bad habits, but rather discouraging them. After all, their code would be practically self-documented in that sense. Those of us who have already gotten used to the way things are would be the ones with the bad habit of writing code that is harder for a person to be sure they understood correctly. Given time, most new programmers would also adapt the simpler way over the less ambiguous way, but at least they would know that it's there in the event they're ever in doubt... or just want to write more readable code. :) TZ "Regan Heath" <regan netwin.co.nz> wrote in message news:opspjzn4ky23k2f5 nrage.netwin.co.nz...On Wed, 20 Apr 2005 17:44:15 -0500, TechnoZeus <TechnoZeus PeoplePC.com> wrote:I should have been more clear in what I stated about pointers. What I meant was that the :=" operator should effect "their own" value (which is the address of what they are pointing to) rather than the value of the anything that they might be pointing to.Just like "=" does currently.In other words, that the value assignment operator should do direct value assignemts. No compromises. I think a separate identity assignment operator would be overkill, but I had included mention of it for completeness.Then we are in agreement, pretty much.The addition of ".value" and ".identity" support would allow a way for programmers to avoid any ambiguity, which would probably not get used a lot in the long run, but would definately be nice to have as an option...Maybe, I'm not sold on the idea yet.especially for beginners who are not sure of whether something is a value type or a reference type. These members would allow them to treat "anything" as a value type, or as a reference type (maybe it should be .reference rather than .identity?), regardless of what it is...But wouldn't this just train bad habits. Assuming using .value etc is only intended for beginners and you should really learn the difference between value and reference types.Hopefully when Walter has time to look in here, he'll give the ":=" value assignment operator strong consideration.Fingers crossed. Regan
Apr 20 2005
I am soliticting help from the senior members of the NG. As I mention in another thread, I would like to call a weigh in on this issue. If I get 3 senior members (I mention specific names in the Walter Weigh In thread, but if I have missed anyone please speak up) saying that introducing ":=" as a deepcopy operator is a good idea, then I will summerize this thread and rename it to "Walter Weigh In: How to bridge the gap between user defined types and built in types" Can I please have sanction from at least three of the more senior people here. Thanks Brad
Apr 20 2005
I'll do one better than that. TZ "Brad Beveridge" <brad somewhere.net> wrote in message news:d46qs6$1jpt$1 digitaldaemon.com...I am soliticting help from the senior members of the NG. As I mention in another thread, I would like to call a weigh in on this issue. If I get 3 senior members (I mention specific names in the Walter Weigh In thread, but if I have missed anyone please speak up) saying that introducing ":=" as a deepcopy operator is a good idea, then I will summerize this thread and rename it to "Walter Weigh In: How to bridge the gap between user defined types and built in types" Can I please have sanction from at least three of the more senior people here. Thanks Brad
Apr 20 2005
With respect to the established mathematical notation, := should by the identity assignment In article <opspa0gry023k2f5 nrage.netwin.co.nz>, Regan Heath says...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)
Apr 20 2005
Why? TZJust as I was expecting that a google search on "mathematical identity" would turn up loads of examples, it fails on me... The proper symbol for identity is really U+2261, "identity", a = with 3 dashes. Besides that, I recall := being used in mathematical context for expressing identity as opposed to equal values, which is what = stands for. In article <d46pk7$1ii7$1 digitaldaemon.com>, TechnoZeus says...Why? TZYep... I totally agree. Better to let "=" act as it does now, and let ":=" assign by copying the contents of the source item into the destination item. As for the established mathematical identity operator, I would recommend that for identity comparisons, except that I've never seen a keyboard with that symbol on it. TZ "Brad Beveridge" <brad somewhere.net> wrote in message news:d46t6k$1lja$1 digitaldaemon.com...In article <d46t6k$1lja$1 digitaldaemon.com>, Brad Beveridge says...What can you do with deep copy that you can't do with: a = b.dup; Or, do you mean "deeper" than that, as in, keep descending levels? Or is efficiency the primary reason to do a deep copy instead of that syntax? KevinYes, I think that you should be able to override a function so that a deep copy descends levels. But the primary problem with b.dup is that it doesn't work for built-in types. Also in this discussion is the problem that you there is no way to fill out an object of type Foo from an object of type Bar, with C++ you could just override operator= so that a = b; would actually convert/copy b into a. Cheers BradApr 22 2005As I pointed out in another thread, the following code doesn't work... //_______________________________// char[] source = "This is just for testing purposes."; char[4] dest; void main() { dest = source[8..12].dup; assert(dest=="just"); } //_______________________________// So using .dup doesn't actually emulate a value assignment operator. For clarification, in the following code... //_______________________________// char[] source = "This is just for testing purposes."; char[4] dest; void main() { dest := source[8..12]; assert(dest=="just"); } //_______________________________// the line... dest := source[8..12]; ...would mean set the contents of "dest" to the contents of "source[8..12]" The value assignment operator would assign values. Not identities. If there are cases which Walter thinks are ambiguous, I would rather he simply leave no definition for the ":=" operator in those cases than to leave us without a value assignment operator over it... even if we're not given a way to be able to define the operator for those cases. TZ "Brad Beveridge" <brad somewhere.net> wrote in message news:d4cp3i$v7c$1 digitaldaemon.com...What can you do with deep copy that you can't do with: a = b.dup; Or, do you mean "deeper" than that, as in, keep descending levels? Or is efficiency the primary reason to do a deep copy instead of that syntax? KevinYes, I think that you should be able to override a function so that a deep copy descends levels. But the primary problem with b.dup is that it doesn't work for built-in types. Also in this discussion is the problem that you there is no way to fill out an object of type Foo from an object of type Bar, with C++ you could just override operator= so that a = b; would actually convert/copy b into a. Cheers BradApr 23 2005TechnoZeus wrote:As I pointed out in another thread, the following code doesn't work... //_______________________________// char[] source = "This is just for testing purposes."; char[4] dest; void main() { dest = source[8..12].dup; assert(dest=="just"); } //_______________________________// So using .dup doesn't actually emulate a value assignment operator.It was already answered: this is almost as trying to change a const.For clarification, in the following code... //_______________________________// char[] source = "This is just for testing purposes."; char[4] dest; void main() { dest := source[8..12]; assert(dest=="just"); } //_______________________________// the line... dest := source[8..12]; ....would mean set the contents of "dest" to the contents of "source[8..12]"Also already answered: dest[] = source[8..12] -- Carlos Santander BernalApr 23 2005"Carlos Santander B." <csantander619 gmail.com> wrote in message news:d4evp8$2qpv$1 digitaldaemon.com...TechnoZeus wrote:That's not an answer. It's a work-around. dest is an array, in that example, not a pointer. It should be possible to assign the contents of an array to an array. I like the way it is handled with the "=" operator, overall, but my point is that .dup doesn't change what you're working with into something that acts like a value type, so the "=" operator thinks you want to change the destination to point to the contents of the duplicate. A value assignment operator wouldn't have to "figure out" whether you wanted to change the value or the identity of the destination operand. TZAs I pointed out in another thread, the following code doesn't work... //_______________________________// char[] source = "This is just for testing purposes."; char[4] dest; void main() { dest = source[8..12].dup; assert(dest=="just"); } //_______________________________// So using .dup doesn't actually emulate a value assignment operator.It was already answered: this is almost as trying to change a const.For clarification, in the following code... //_______________________________// char[] source = "This is just for testing purposes."; char[4] dest; void main() { dest := source[8..12]; assert(dest=="just"); } //_______________________________// the line... dest := source[8..12]; ....would mean set the contents of "dest" to the contents of "source[8..12]"Also already answered: dest[] = source[8..12] -- Carlos Santander BernalApr 23 2005On Sat, 23 Apr 2005 23:41:30 -0500, TechnoZeus wrote:"Carlos Santander B." <csantander619 gmail.com> wrote in message news:d4evp8$2qpv$1 digitaldaemon.com...Are doing this deliberately? That is not a work around. It is the way to do it.TechnoZeus wrote:That's not an answer. It's a work-around.As I pointed out in another thread, the following code doesn't work... //_______________________________// char[] source = "This is just for testing purposes."; char[4] dest; void main() { dest = source[8..12].dup; assert(dest=="just"); } //_______________________________// So using .dup doesn't actually emulate a value assignment operator.It was already answered: this is almost as trying to change a const.For clarification, in the following code... //_______________________________// char[] source = "This is just for testing purposes."; char[4] dest; void main() { dest := source[8..12]; assert(dest=="just"); } //_______________________________// the line... dest := source[8..12]; ....would mean set the contents of "dest" to the contents of "source[8..12]"Also already answered: dest[] = source[8..12] -- Carlos Santander Bernaldest is an array, in that example, not a pointer.Yes, and 'source' is not an array, it is a dynamic array reference.It should be possible to assign the contents of an array to an array.It is. And the way one does it is to specify which elements of the target array you are updating. The syntax 'target[]' is shorthand for 'target[0..$]'. Even in the case where the target is a dynamic array, target = source; does not update the target array elements, it makes target point to the same array as source. To update the elements you still need to do target[] = source;I like the way it is handled with the "=" operator, overall, but my point is that .dup doesn't change what you're working with into something that acts like a value type,Of course not. The .dup just takes a copy.so the "=" operator thinks you want to change the destination to point to the contents of the duplicate.Yes, because that's what you told it to do via the 'target = source;' statement. If you wanted to update all the elements in target, you need to use the correct syntax... 'target[] = source'A value assignment operator wouldn't have to "figure out" whether you wanted to change the value or the identity of the destination operand.You seem to be saying, that you wish ':=' to be an alternative syntax to update all the elements in an array, based on the elements in the source. -- Derek Parnell Melbourne, Australia http://www.dsource.org/projects/build 24/04/2005 8:50:16 PMApr 24 2005"Derek Parnell" <derek psych.ward> wrote in message news:nvs7ocyuwj7$.5srfzovygnpv$.dlg 40tude.net...On Sat, 23 Apr 2005 23:41:30 -0500, TechnoZeus wrote:*snip*You seem to be saying, that you wish ':=' to be an alternative syntax to update all the elements in an array, based on the elements in the source. -- Derek Parnell Melbourne, Australia http://www.dsource.org/projects/build 24/04/2005 8:50:16 PMAmong othger things, yes... that is what I am saying I would like it to do. More generally, I would like := to update the contents of the destination operand with the contents of the source operand. That's what value assignment is. As for source being a dynamic array reference rather than an array, I think that is a matter of perspective. The "=" operator does treat it as a dynamic array reference, we all know there's more to "what it is" than simply how it's treated. I'm not tring to tell anyone that their point of view is wrong. I'm trying to point out that alternative points of view may be equally valid, and potentially productive. Having a value assignment operator available would support an alternative way of thinking, and by extension, increase potential productivity. People who don't like it wouldn't have to use it. People who do like it wouldn't have to use it "exclusively". TZApr 24 2005Thanks Ben. Okay, now... Ben...I think you mean Vladimir. My post was the one with no ideas in it :-)Apr 15 2005Hahaha. 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 :-)Apr 15 2005Anders mentioned the addition of a ":=" operator on April 12th, and then there is this one, to which I am posting a reply, and the discussion has resulted in what looks suspiciously like nearly unanimous agreement... so as has been pointed out more than once, it's time to ask Walter to have a look at it. Walter: Please consider the addition of ":=" as a vlaue assignment operator. What's meant by that, is while "=" would continue to function "as is" there would be the option of using ":=" to represent assignment of value regardless of whether dealing with value types or reverence types. In cases where assigning value can't be done, ":=" would produce an error rather than assign by identity. This would allow unambiguous source code, and would also point out any places where there may be a need to add a value assignment specifically. Please give us some indication of what you think on this matter. Many of us would very much like to see this implemented, and feel that it would be very beneficial. Donald A. Kronos, PhD. - 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. -- VladimirApr 20 2005I'm inviting anyone who wants to summarize their thoughts or comments on the proposed ":=" assignment opperator to do so as a reply to this post... to save Walter the time necessary to otherwise search for such comments. TechnoZeusApr 20 2005TechnoZeus wrote:I'm inviting anyone who wants to summarize their thoughts or comments on the proposed ":=" assignment opperator to do so as a reply to this post... to save Walter the time necessary to otherwise search for such comments. TechnoZeusMy only comment is thus: The flexibility of the ":=" operator is twofold if it calls an "opAssign" function when used with LHS being a class. Calling opAssign (or some other name) because then you not only have the deep copy ability, but you can cast/convert from one class type to another. ie Foo a = new Foo(); Foo b = new Foo(); Bar c = new Bar(); a := b; // calls Foo.opAssign(Foo rhs); a := c; // calls Foo.opAssign(Bar rhs); Also, array.dup can now go away. BradApr 20 2005Cool. Hadn't thought of that. :) Now I'm wondering how many other "unexpected" potential benefits there might be. Other comments? TZ "Brad Beveridge" <brad somewhere.net> wrote in message news:d46u5v$1mi8$1 digitaldaemon.com...TechnoZeus wrote:I'm inviting anyone who wants to summarize their thoughts or comments on the proposed ":=" assignment opperator to do so as a reply to this post... to save Walter the time necessary to otherwise search for such comments. TechnoZeusMy only comment is thus: The flexibility of the ":=" operator is twofold if it calls an "opAssign" function when used with LHS being a class. Calling opAssign (or some other name) because then you not only have the deep copy ability, but you can cast/convert from one class type to another. ie Foo a = new Foo(); Foo b = new Foo(); Bar c = new Bar(); a := b; // calls Foo.opAssign(Foo rhs); a := c; // calls Foo.opAssign(Bar rhs); Also, array.dup can now go away. BradApr 20 2005Foo a = new Foo(); Foo b = new Foo(); Bar c = new Bar(); a := b; // calls Foo.opAssign(Foo rhs); a := c; // calls Foo.opAssign(Bar rhs); Also, array.dup can now go away.array.dup would still be needed (like any dup property) in expressions that don't have any assignment. For example "return array.dup;"Apr 21 2005"TechnoZeus" <TechnoZeus PeoplePC.com> wrote in message news:d46tp4$1m37$1 digitaldaemon.com...I'm inviting anyone who wants to summarize their thoughts or comments on the proposed ":=" assignment opperator to do so as a reply to this post... to save Walter the time necessary to otherwise search for such comments.What exactly is the proposed behavior? For instance what would it do for builtin types, pointers, arrays, structs, and classes? The post with [suggestion][Walter] in the subject mentions "assign by value" but that's too vague for me. For example how deep does the deep assignment go? I haven't looked at all the other posts in the thread but I'd be surprised if this is really the right way to address the problem. Actually now that I think of it - what is the problem? I assume it's that inside templates "=" assigns by value for value types and by reference for reference types, correct? Plus I skimmed a post or two about a problem that there is an asymmetry between "==" and "is" and assignment (which only has "="). About the template problem: I'd prefer to look into something like extending ".dup" to all types rather than invent a new operator. But I haven't thought about it really. About the asymmetry problem: D is designed to be practical so while it would be nice to have symmetry I wouldn't consider that a goal.Apr 20 2005What exactly is the proposed behavior? For instance what would it do for builtin types, pointers, arrays, structs, and classes? The post with [suggestion][Walter] in the subject mentions "assign by value" but that's too vague for me. For example how deep does the deep assignment go?Built-in types will behave exactly as they do with ":=" as they currently do with "=" Arrays will have a new array created, with each new element created from the old array using the ":=" operator. Structs will have ":=" called on each member they contain - or if this is too hard, they will need to define opAssign(). Reference types (ie classes) will need to define the operator function opAssign, and they can do what they like. Classes may also define overloaded opAssign functions, which could potentially act as object conversion operators. BradApr 20 2005"Brad Beveridge" <brad somewhere.net> wrote in message news:d46vid$1nec$1 digitaldaemon.com...Thanks. You explained that much better than I did. :) TZWhat exactly is the proposed behavior? For instance what would it do for builtin types, pointers, arrays, structs, and classes? The post with [suggestion][Walter] in the subject mentions "assign by value" but that's too vague for me. For example how deep does the deep assignment go?Built-in types will behave exactly as they do with ":=" as they currently do with "=" Arrays will have a new array created, with each new element created from the old array using the ":=" operator. Structs will have ":=" called on each member they contain - or if this is too hard, they will need to define opAssign(). Reference types (ie classes) will need to define the operator function opAssign, and they can do what they like. Classes may also define overloaded opAssign functions, which could potentially act as object conversion operators. BradApr 20 2005"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:d46v3g$1n7o$1 digitaldaemon.com..."TechnoZeus" <TechnoZeus PeoplePC.com> wrote in message news:d46tp4$1m37$1 digitaldaemon.com...My understanding of the overal concensus is that := would be used to copy the contents of the source to the destination, but not copy the address of the source and not alter the address of the destination. Not everyone is in "full agreement" but this much does appear to be pretty consistantly agreed on. I didn't want to say too much in the post with [Walter] in the subject, because I thought it better if everyone had an equal opportunity to present their take on it, since the agreement was obviously not total and across the board. To answer your questions, here is my take on the aspects which you asked about... For basic data types, := would set the vaue of the item's data. For pointer types, := would set the location pointed to by the pointer's value. For array types, := would set the contents of the destination array or of the specified subset of the array in the case of a slice as the destination. In general, when you name an object, you specify the identity of that object by name. That identity is represented internally by a memory address. The := operator would not assign anything to that address, but would rather assign something to the contents pointed to by that address. I hope this helps to clarify what was meant. TechnoZeusI'm inviting anyone who wants to summarize their thoughts or comments on the proposed ":=" assignment opperator to do so as a reply to this post... to save Walter the time necessary to otherwise search for such comments.What exactly is the proposed behavior? For instance what would it do for builtin types, pointers, arrays, structs, and classes? The post with [suggestion][Walter] in the subject mentions "assign by value" but that's too vague for me. For example how deep does the deep assignment go? I haven't looked at all the other posts in the thread but I'd be surprised if this is really the right way to address the problem. Actually now that I think of it - what is the problem? I assume it's that inside templates "=" assigns by value for value types and by reference for reference types, correct? Plus I skimmed a post or two about a problem that there is an asymmetry between "==" and "is" and assignment (which only has "="). About the template problem: I'd prefer to look into something like extending ".dup" to all types rather than invent a new operator. But I haven't thought about it really. About the asymmetry problem: D is designed to be practical so while it would be nice to have symmetry I wouldn't consider that a goal.Apr 20 2005In article <d46v3g$1n7o$1 digitaldaemon.com>, Ben Hinkle says...About the template problem: I'd prefer to look into something like extending ".dup" to all types rather than invent a new operator.Ben, thank you. You took the words right out of my mouth. :) For classes, there's no need to make this a formal 'operator'. It could merely be added to Object as a shallow copy (return this;) and then overridden in any class where it's needed. So really, all that's needed is a 'dup' property for scalars. The rest is up to the developer. class Foobar{ public Foobar dup(){ return this; // or a copy } } void main(){ Foobar a,b; a = new Foobar(); b = a.dup; // custom ('deep') copy int c,d; c = d.dup; // value-copy: allowed for consistency int[] e,f e = f.dup; // old hat } The above folds into templates, extremely well: template valueOf(T){ T valueOf(T x){ return x.dup; } } .. where 'T' can be, well, anything. I'll add that the above is also *impossible* with ':=' and would require a temporary varible to work. Thus, it would be less flexible (and probably useful IMO). There's absolutely no need for an additional operator like ':='. - EricAnderton at yahooApr 21 2005pragma wrote:In article <d46v3g$1n7o$1 digitaldaemon.com>, Ben Hinkle says...Formally you are right, but always typing a=b.dup is not convenient and can be forgotten, especially when one tries to convert non-template function to template. May be we can add ':' unary operator which in expression :a works exactly like a.dup ? So a=b.dup will look as a = :b or even a =: b. When returning from function this will look like { return :a; }. -- VladimirAbout the template problem: I'd prefer to look into something like extending ".dup" to all types rather than invent a new operator.Ben, thank you. You took the words right out of my mouth. :) For classes, there's no need to make this a formal 'operator'. It could merely be added to Object as a shallow copy (return this;) and then overridden in any class where it's needed. So really, all that's needed is a 'dup' property for scalars. The rest is up to the developer. class Foobar{ public Foobar dup(){ return this; // or a copy } } void main(){ Foobar a,b; a = new Foobar(); b = a.dup; // custom ('deep') copy int c,d; c = d.dup; // value-copy: allowed for consistency int[] e,f e = f.dup; // old hat } The above folds into templates, extremely well: template valueOf(T){ T valueOf(T x){ return x.dup; } } .. where 'T' can be, well, anything. I'll add that the above is also *impossible* with ':=' and would require a temporary varible to work. Thus, it would be less flexible (and probably useful IMO). There's absolutely no need for an additional operator like ':='.Apr 21 2005In article <d48gt8$8ao$1 digitaldaemon.com>, Vladimir says...May be we can add ':' unary operator which in expression :a works exactly like a.dup ? So a=b.dup will look as a = :b or even a =: b. When returning from function this will look like { return :a; }.The only wart here is that you'll run into small problems with ':' when evaluating the ternary '?' operator: foo() ? bar() : a; // what was meant here? (value-of or ternary else) .. but that's strictly a matter of operator precedence. I for one, don't find it as readable. Not that I think it's a good idea, but you could use something like ' ' to mean 'value-of' (which would be akin to '&' meaning 'address-of'). { return a; } This isn't too bad, but it still lands us in "create a new operator territory". I still think .dup() is the way to go. -EricAnderton at yahooApr 21 2005pragma wrote:In article <d48gt8$8ao$1 digitaldaemon.com>, Vladimir says...But what is so fundamental difference between "create a new property for fundamental data type" and "create a new operator" ?May be we can add ':' unary operator which in expression :a works exactly like a.dup ? So a=b.dup will look as a = :b or even a =: b. When returning from function this will look like { return :a; }.The only wart here is that you'll run into small problems with ':' when evaluating the ternary '?' operator: foo() ? bar() : a; // what was meant here? (value-of or ternary else) .. but that's strictly a matter of operator precedence. I for one, don't find it as readable. Not that I think it's a good idea, but you could use something like ' ' to mean 'value-of' (which would be akin to '&' meaning 'address-of'). { return a; } This isn't too bad, but it still lands us in "create a new operator territory".I still think .dup() is the way to go.For me it's just harder to type that . The only thing is that having operator it's too big tempting to allow T for creating class-value-type, which Walter will never accept, wont he ? :-) Anyway, if implemented, .dup() or := or would be very useful feature. -- VladimirApr 21 2005In article <d48pet$g4d$1 digitaldaemon.com>, Vladimir says...Largely, the compiler impact is the biggest difference; a universal dup() property won't require anything new in the lexer and will likely be easily attached to the property evaluation bits already present. Adding a ':=' operator requires changes to the lexer, and a expression handling branch, with quirks and rules all its own. IMO, adding ':=' would be much more work to do, and not worth it since D has already (partially) sovled the problem. There is a smaller impact to D's grammar is a close second as ':=' is somewhat ambiguous when applied to certain cases; I'm welcome to be wrong about that. Regardless, .dup() is wholly unambiguous and meshes well with the present design.Not that I think it's a good idea, but you could use something like ' ' to mean 'value-of' (which would be akin to '&' meaning 'address-of'). { return a; } This isn't too bad, but it still lands us in "create a new operator territory".But what is so fundamental difference between "create a new property for fundamental data type" and "create a new operator" ?Probably not. Again, I'd be willing to bet that extending .dup to everything would be cake to implement by comparison. - EricAnderton at yahooI still think .dup() is the way to go.For me it's just harder to type that . The only thing is that having operator it's too big tempting to allow T for creating class-value-type, which Walter will never accept, wont he ? :-)Apr 21 2005As it turns out, the .dup member function returns a reference, rather than a value (at least in arrays, as I have tested it), and so does not qualify as a substitute for directly working the a value rather than a reference. The := reference operator is still needed. TZ "pragma" <pragma_member pathlink.com> wrote in message news:d48rjc$ibp$1 digitaldaemon.com...In article <d48pet$g4d$1 digitaldaemon.com>, Vladimir says...Largely, the compiler impact is the biggest difference; a universal dup() property won't require anything new in the lexer and will likely be easily attached to the property evaluation bits already present. Adding a ':=' operator requires changes to the lexer, and a expression handling branch, with quirks and rules all its own. IMO, adding ':=' would be much more work to do, and not worth it since D has already (partially) sovled the problem. There is a smaller impact to D's grammar is a close second as ':=' is somewhat ambiguous when applied to certain cases; I'm welcome to be wrong about that. Regardless, .dup() is wholly unambiguous and meshes well with the present design.Not that I think it's a good idea, but you could use something like ' ' to mean 'value-of' (which would be akin to '&' meaning 'address-of'). { return a; } This isn't too bad, but it still lands us in "create a new operator territory".But what is so fundamental difference between "create a new property for fundamental data type" and "create a new operator" ?Probably not. Again, I'd be willing to bet that extending .dup to everything would be cake to implement by comparison. - EricAnderton at yahooI still think .dup() is the way to go.For me it's just harder to type that . The only thing is that having operator it's too big tempting to allow T for creating class-value-type, which Walter will never accept, wont he ? :-)Apr 22 2005oops... brain thought one thing, and hands typed another. that last line should have read... The := value assignment operator is still needed. TZ "TechnoZeus" <TechnoZeus PeoplePC.com> wrote in message news:d4adkr$21p6$1 digitaldaemon.com...As it turns out, the .dup member function returns a reference, rather than a value (at least in arrays, as I have tested it), and so does not qualify as a substitute for directly working the a value rather than a reference. The := reference operator is still needed. TZ "pragma" <pragma_member pathlink.com> wrote in message news:d48rjc$ibp$1 digitaldaemon.com...In article <d48pet$g4d$1 digitaldaemon.com>, Vladimir says...Largely, the compiler impact is the biggest difference; a universal dup() property won't require anything new in the lexer and will likely be easily attached to the property evaluation bits already present. Adding a ':=' operator requires changes to the lexer, and a expression handling branch, with quirks and rules all its own. IMO, adding ':=' would be much more work to do, and not worth it since D has already (partially) sovled the problem. There is a smaller impact to D's grammar is a close second as ':=' is somewhat ambiguous when applied to certain cases; I'm welcome to be wrong about that. Regardless, .dup() is wholly unambiguous and meshes well with the present design.Not that I think it's a good idea, but you could use something like ' ' to mean 'value-of' (which would be akin to '&' meaning 'address-of'). { return a; } This isn't too bad, but it still lands us in "create a new operator territory".But what is so fundamental difference between "create a new property for fundamental data type" and "create a new operator" ?Probably not. Again, I'd be willing to bet that extending .dup to everything would be cake to implement by comparison. - EricAnderton at yahooI still think .dup() is the way to go.For me it's just harder to type that . The only thing is that having operator it's too big tempting to allow T for creating class-value-type, which Walter will never accept, wont he ? :-)Apr 22 2005pragma wrote:In article <d48pet$g4d$1 digitaldaemon.com>, Vladimir says...All these changes are trivial. I've done a patch for gdc-0.10 to allow discussed above ' ' operator, and it takes me about one hour. I've never seen gdc sources before, so I belive for Walter it takes not more than five minutes. Adding ':=' will be more difficult, but I like challenges.Largely, the compiler impact is the biggest difference; a universal dup() property won't require anything new in the lexer and will likely be easily attached to the property evaluation bits already present. Adding a ':=' operator requires changes to the lexer, and a expression handling branch, with quirks and rules all its own.Not that I think it's a good idea, but you could use something like ' ' to mean 'value-of' (which would be akin to '&' meaning 'address-of'). { return a; } This isn't too bad, but it still lands us in "create a new operator territory".But what is so fundamental difference between "create a new property for fundamental data type" and "create a new operator" ?IMO, adding ':=' would be much more work to do, and not worth it since D has already (partially) sovled the problem.There is a smaller impact to D's grammar is a close second as ':=' is somewhat ambiguous when applied to certain cases; I'm welcome to be wrong about that. Regardless, .dup() is wholly unambiguous and meshes well with the present design.-- VladimirProbably not. Again, I'd be willing to bet that extending .dup to everything would be cake to implement by comparison. - EricAnderton at yahooI still think .dup() is the way to go.For me it's just harder to type that . The only thing is that having operator it's too big tempting to allow T for creating class-value-type, which Walter will never accept, wont he ? :-)Apr 22 2005Vladimir - can you please explain the new behaviour of your patch? From looking at the patch, it appears that when you type object it gets translated into object.opValue() - is this correct? Does the operator handle built-in types? I think this is great work, now if we could just figure out a way to convert from one type to another, such as Foo a = new Foo(); Bar b = new Bar(); b := a; then most issues raised in this discussion would be solved (I think) BradApr 22 2005Brad Beveridge wrote:Vladimir - can you please explain the new behaviour of your patch? From looking at the patch, it appears that when you type object it gets translated into object.opValue() - is this correct?Correct. But may be we need some default behavior here, such as recursively apply for all members stopping at built-in types.Does the operator handle built-in types?Yes, but not arrays yet.I think this is great work, now if we could just figure out a way to convert from one type to another, such as Foo a = new Foo(); Bar b = new Bar(); b := a;I have an idea about it, I'll try when I'll find a new piece of free time.then most issues raised in this discussion would be solved (I think)Does not take is so serious :-) I just like to play with code :-) It is not in D trunk and may be never get there. It's just my test how can it be done.Brad-- VladimirApr 22 2005That's important too. :) Much appriated, of course. TZ "Vladimir" <kv11111 mail.ru> wrote in message news:d4bsfo$9j3$1 digitaldaemon.com...Brad Beveridge wrote:Vladimir - can you please explain the new behaviour of your patch? From looking at the patch, it appears that when you type object it gets translated into object.opValue() - is this correct?Correct. But may be we need some default behavior here, such as recursively apply for all members stopping at built-in types.Does the operator handle built-in types?Yes, but not arrays yet.I think this is great work, now if we could just figure out a way to convert from one type to another, such as Foo a = new Foo(); Bar b = new Bar(); b := a;I have an idea about it, I'll try when I'll find a new piece of free time.then most issues raised in this discussion would be solved (I think)Does not take is so serious :-) I just like to play with code :-) It is not in D trunk and may be never get there. It's just my test how can it be done.Brad-- VladimirApr 23 2005"Vladimir" <kv11111 mail.ru> wrote in message news:d4bsfo$9j3$1 digitaldaemon.com...Brad Beveridge wrote:*snip*It's just my test how can it be done. -- VladimirSorry. I should snipped the quote. What I meant to say was... testing how it can be done is important. Thanks for doing that. It's very much appreciated. TZApr 23 2005On Sat, 23 Apr 2005 08:35:18 +1200, Brad Beveridge wrote:Vladimir - can you please explain the new behaviour of your patch? From looking at the patch, it appears that when you type object it gets translated into object.opValue() - is this correct? Does the operator handle built-in types? I think this is great work, now if we could just figure out a way to convert from one type to another, such as Foo a = new Foo(); Bar b = new Bar(); b := a; then most issues raised in this discussion would be solved (I think)This ' ' proposal is the one that I'm liking the most so far. In other words use '&' to get something's RAM address, and use ' ' to get something's value. For things that support methods, the ' ' could translate to a call to the things opValue() method. For things that do not support methods, it would invoke opValue_r() if defined otherwise, its identical to the current D behaviour for casting. Of course, if the undocumented syntax relating to arrays is propagated to all types (see last example below), we could really have a useful programming construct. Foo a = new Foo(); Bar b = new Bar(); int c; real d; char[] e; b = a; // b.opValue(a); a = b; // a.opValue(b); c = b; // b.opValue_r(inout c); c = d; // c = cast(int)d; a = d; // a.opValue(d); e = a; // a.opValue_r(inout e); d = e; // d = opValue(in d, e); This idea would work for all things making it suitable for template usage too. -- Derek Parnell Melbourne, Australia 23/04/2005 10:27:19 AMApr 22 2005Derek Parnell wrote:On Sat, 23 Apr 2005 08:35:18 +1200, Brad Beveridge wrote:The operator is currently unary, so there really is no notion of opValue_r() - at least as I understand it. Ie, this suffers the same problem that the cast operator does - because it is unary there is no notion of the LHS. Is it possible to have an operator that is both unary and binary - depending on context? I can't think how. BradVladimir - can you please explain the new behaviour of your patch? From looking at the patch, it appears that when you type object it gets translated into object.opValue() - is this correct? Does the operator handle built-in types? I think this is great work, now if we could just figure out a way to convert from one type to another, such as Foo a = new Foo(); Bar b = new Bar(); b := a; then most issues raised in this discussion would be solved (I think)This ' ' proposal is the one that I'm liking the most so far. In other words use '&' to get something's RAM address, and use ' ' to get something's value. For things that support methods, the ' ' could translate to a call to the things opValue() method. For things that do not support methods, it would invoke opValue_r() if defined otherwise, its identical to the current D behaviour for casting. Of course, if the undocumented syntax relating to arrays is propagated to all types (see last example below), we could really have a useful programming construct. Foo a = new Foo(); Bar b = new Bar(); int c; real d; char[] e; b = a; // b.opValue(a); a = b; // a.opValue(b); c = b; // b.opValue_r(inout c); c = d; // c = cast(int)d; a = d; // a.opValue(d); e = a; // a.opValue_r(inout e); d = e; // d = opValue(in d, e); This idea would work for all things making it suitable for template usage too.Apr 22 2005The operator is currently unary, so there really is no notion of opValue_r() - at least as I understand it. Ie, this suffers the same problem that the cast operator does - because it is unary there is no notion of the LHS. Is it possible to have an operator that is both unary and binary - depending on context? I can't think how. BradPoor form answering my own question, perhaps we should add = as an operator, which will call opValue with a parameter a -- calls a.opValue() a = b -- calls a.opValue(b), or b.opValue_r(a) Since if you think about it, a conversion must create a new object. BradApr 22 2005Any binary operator could be made to act unary, as long as the operator isn't restricted to being commutative. As a crude example, int a; int b; a + -b; // add negative b to a. a - b; // subtract b from a. a + (0-b); Much like "a + -b;" the subtraction doesn't need to know about "a" in this case. TZ "Brad Beveridge" <brad somewhere.net> wrote in message news:d4c64h$goe$1 digitaldaemon.com...Derek Parnell wrote:On Sat, 23 Apr 2005 08:35:18 +1200, Brad Beveridge wrote:The operator is currently unary, so there really is no notion of opValue_r() - at least as I understand it. Ie, this suffers the same problem that the cast operator does - because it is unary there is no notion of the LHS. Is it possible to have an operator that is both unary and binary - depending on context? I can't think how. BradVladimir - can you please explain the new behaviour of your patch? From looking at the patch, it appears that when you type object it gets translated into object.opValue() - is this correct? Does the operator handle built-in types? I think this is great work, now if we could just figure out a way to convert from one type to another, such as Foo a = new Foo(); Bar b = new Bar(); b := a; then most issues raised in this discussion would be solved (I think)This ' ' proposal is the one that I'm liking the most so far. In other words use '&' to get something's RAM address, and use ' ' to get something's value. For things that support methods, the ' ' could translate to a call to the things opValue() method. For things that do not support methods, it would invoke opValue_r() if defined otherwise, its identical to the current D behaviour for casting. Of course, if the undocumented syntax relating to arrays is propagated to all types (see last example below), we could really have a useful programming construct. Foo a = new Foo(); Bar b = new Bar(); int c; real d; char[] e; b = a; // b.opValue(a); a = b; // a.opValue(b); c = b; // b.opValue_r(inout c); c = d; // c = cast(int)d; a = d; // a.opValue(d); e = a; // a.opValue_r(inout e); d = e; // d = opValue(in d, e); This idea would work for all things making it suitable for template usage too.Apr 23 2005Ironically, since the " " symbol is usually pronounced "at" (in English at least) it would have been a nice choice for an address operator, to tell where something is at. Hehe. Oh well... too late to change history. We can get used to it. :) TZ "Derek Parnell" <derek psych.ward> wrote in message news:pqibzzcik9ez$.1nw19ysr1xxya$.dlg 40tude.net...On Sat, 23 Apr 2005 08:35:18 +1200, Brad Beveridge wrote:Vladimir - can you please explain the new behaviour of your patch? From looking at the patch, it appears that when you type object it gets translated into object.opValue() - is this correct? Does the operator handle built-in types? I think this is great work, now if we could just figure out a way to convert from one type to another, such as Foo a = new Foo(); Bar b = new Bar(); b := a; then most issues raised in this discussion would be solved (I think)This ' ' proposal is the one that I'm liking the most so far. In other words use '&' to get something's RAM address, and use ' ' to get something's value. For things that support methods, the ' ' could translate to a call to the things opValue() method. For things that do not support methods, it would invoke opValue_r() if defined otherwise, its identical to the current D behaviour for casting. Of course, if the undocumented syntax relating to arrays is propagated to all types (see last example below), we could really have a useful programming construct. Foo a = new Foo(); Bar b = new Bar(); int c; real d; char[] e; b = a; // b.opValue(a); a = b; // a.opValue(b); c = b; // b.opValue_r(inout c); c = d; // c = cast(int)d; a = d; // a.opValue(d); e = a; // a.opValue_r(inout e); d = e; // d = opValue(in d, e); This idea would work for all things making it suitable for template usage too. -- Derek Parnell Melbourne, Australia 23/04/2005 10:27:19 AMApr 23 2005"Vladimir" <kv11111 mail.ru> wrote in message news:d48gt8$8ao$1 digitaldaemon.com...pragma wrote:Correct me if I'm mistaken, but I think what you are saying only takes reference types into account. The idea here is to get away from the risk of code failing to work when value types and reference types inevitably get confused. There is, for example, not much sense to the following code... int a = 5.dup; int b; int c; b = a.dup + 7.dup; c = b.dup; Of course, this is an extreme case, but it is meant to illustrate a point. If the programmer wants to be sure that they are assigning values, and not changing the address of somehting, then the ":=" operator would be used... int a := 5; int b; int c; b := a+7; c := b; No ambiguity there. Notice that with this convention, one would know what "a := b" is supposed to do, even without knowing what "a" and "b" represent. The same can not be said of "a = b" in D. TZIn article <d46v3g$1n7o$1 digitaldaemon.com>, Ben Hinkle says...Formally you are right, but always typing a=b.dup is not convenient and can be forgotten, especially when one tries to convert non-template function to template. May be we can add ':' unary operator which in expression :a works exactly like a.dup ? So a=b.dup will look as a = :b or even a =: b. When returning from function this will look like { return :a; }. -- VladimirAbout the template problem: I'd prefer to look into something like extending ".dup" to all types rather than invent a new operator.Ben, thank you. You took the words right out of my mouth. :) For classes, there's no need to make this a formal 'operator'. It could merely be added to Object as a shallow copy (return this;) and then overridden in any class where it's needed. So really, all that's needed is a 'dup' property for scalars. The rest is up to the developer. class Foobar{ public Foobar dup(){ return this; // or a copy } } void main(){ Foobar a,b; a = new Foobar(); b = a.dup; // custom ('deep') copy int c,d; c = d.dup; // value-copy: allowed for consistency int[] e,f e = f.dup; // old hat } The above folds into templates, extremely well: template valueOf(T){ T valueOf(T x){ return x.dup; } } .. where 'T' can be, well, anything. I'll add that the above is also *impossible* with ':=' and would require a temporary varible to work. Thus, it would be less flexible (and probably useful IMO). There's absolutely no need for an additional operator like ':='.Apr 21 2005In article <d48je6$arv$1 digitaldaemon.com>, TechnoZeus says...If the programmer wants to be sure that they are assigning values, and not changing the address of somehting, then the ":=" operator would be used... int a := 5; int b; int c; b := a+7; c := b; No ambiguity there. Notice that with this convention, one would know what "a := b" is supposed to do, even without knowing what "a" and "b" represent. The same can not be said of "a = b" in D.The problem with your example in this argument is that it's ambiguous. b := a+7 Does it mean "take the actual value of the lvalue"? b = (a+7).opValue; .. or "take the actual value of all the distinct portions of the lvalue"? b = a.opValue + 7.opValue; Which is correct? Also, keep in mind, that with either interpretation, will limit its percieved utility: T a,b,c,d; a := b + c + d; To obtain the opvalue of just one of b,c or d, i need to use more than one expression; regardless of the actual interpretation of ':='. To side-step the limitations of the operator. This is in sharp contrast to operators like good ol' '=' or even '&', which are much more explicit. With an explicit syntax like '.dup' there's no question as to what's going on. - EricAnderton at yahooApr 21 2005I should've double-checked before posting. by 'lvalue', I actually mean 'rvalue'. Sorry for the confusion. -EricAnderton at yahoo In article <d48nr3$ejr$1 digitaldaemon.com>, pragma says...In article <d48je6$arv$1 digitaldaemon.com>, TechnoZeus says...If the programmer wants to be sure that they are assigning values, and not changing the address of somehting, then the ":=" operator would be used... int a := 5; int b; int c; b := a+7; c := b; No ambiguity there. Notice that with this convention, one would know what "a := b" is supposed to do, even without knowing what "a" and "b" represent. The same can not be said of "a = b" in D.The problem with your example in this argument is that it's ambiguous. b := a+7 Does it mean "take the actual value of the lvalue"? b = (a+7).opValue; .. or "take the actual value of all the distinct portions of the lvalue"? b = a.opValue + 7.opValue; Which is correct? Also, keep in mind, that with either interpretation, will limit its percieved utility: T a,b,c,d; a := b + c + d; To obtain the opvalue of just one of b,c or d, i need to use more than one expression; regardless of the actual interpretation of ':='. To side-step the limitations of the operator. This is in sharp contrast to operators like good ol' '=' or even '&', which are much more explicit. With an explicit syntax like '.dup' there's no question as to what's going on. - EricAnderton at yahooApr 21 2005Actually, it's not ambiguous at all. At least, not to me... and I'm guessing not to other people who see the advantages of a := value assignment operator. There is a clear distinction between working with values and working with identities. If you interpret "a+7" as an identity operation, then that interpretation obviously can't be assigned using a value assignment operator. If you interpret it as a value operation, then the results would be a value. You don't need to look for the value stored at the location pointed to by the identity referenced to specify the value. That's recursive, and serves only to cause an invinite loop. b := a+7; would mean that the value "7" is added to the value stored in "a" and then the value of b is set to the resulting value. No ambiguity. That's the idea. TZ "pragma" <pragma_member pathlink.com> wrote in message news:d48osb$fgg$1 digitaldaemon.com...I should've double-checked before posting. by 'lvalue', I actually mean 'rvalue'. Sorry for the confusion. -EricAnderton at yahoo In article <d48nr3$ejr$1 digitaldaemon.com>, pragma says...In article <d48je6$arv$1 digitaldaemon.com>, TechnoZeus says...If the programmer wants to be sure that they are assigning values, and not changing the address of somehting, then the ":=" operator would be used... int a := 5; int b; int c; b := a+7; c := b; No ambiguity there. Notice that with this convention, one would know what "a := b" is supposed to do, even without knowing what "a" and "b" represent. The same can not be said of "a = b" in D.The problem with your example in this argument is that it's ambiguous. b := a+7 Does it mean "take the actual value of the lvalue"? b = (a+7).opValue; .. or "take the actual value of all the distinct portions of the lvalue"? b = a.opValue + 7.opValue; Which is correct? Also, keep in mind, that with either interpretation, will limit its percieved utility: T a,b,c,d; a := b + c + d; To obtain the opvalue of just one of b,c or d, i need to use more than one expression; regardless of the actual interpretation of ':='. To side-step the limitations of the operator. This is in sharp contrast to operators like good ol' '=' or even '&', which are much more explicit. With an explicit syntax like '.dup' there's no question as to what's going on. - EricAnderton at yahooApr 22 2005On Thu, 21 Apr 2005 17:28:03 +0000 (UTC), pragma <pragma_member pathlink.com> wrote:In article <d48je6$arv$1 digitaldaemon.com>, TechnoZeus says...It means call: b.opAssign(a+7); ReganIf the programmer wants to be sure that they are assigning values, and not changing the address of somehting, then the ":=" operator would be used... int a := 5; int b; int c; b := a+7; c := b; No ambiguity there. Notice that with this convention, one would know what "a := b" is supposed to do, even without knowing what "a" and "b" represent. The same can not be said of "a = b" in D.The problem with your example in this argument is that it's ambiguous. b := a+7 Does it mean "take the actual value of the lvalue"?Apr 21 2005Which, is exactly the same as regular "=" precidence, ie the assignment operation always happens last. BradThe problem with your example in this argument is that it's ambiguous. b := a+7 Does it mean "take the actual value of the lvalue"?It means call: b.opAssign(a+7); ReganApr 21 2005Yep. TZ "Brad Beveridge" <brad somewhere.net> wrote in message news:d494bj$qho$1 digitaldaemon.com...Which, is exactly the same as regular "=" precidence, ie the assignment operation always happens last. BradThe problem with your example in this argument is that it's ambiguous. b := a+7 Does it mean "take the actual value of the lvalue"?It means call: b.opAssign(a+7); ReganApr 22 2005Correct me if I'm mistaken, but I think what you are saying only takes reference types into account. The idea here is to get away from the risk of code failing to work when value types and reference types inevitably get confused. There is, for example, not much sense to the following code... int a = 5.dup; int b; int c; b = a.dup + 7.dup; c = b.dup; Of course, this is an extreme case, but it is meant to illustrate a point. If the programmer wants to be sure that they are assigning values, and not changing the address of somehting, then the ":=" operator would be used... int a := 5; int b; int c; b := a+7; c := b; No ambiguity there. Notice that with this convention, one would know what "a := b" is supposed to do, even without knowing what "a" and "b" represent. The same can not be said of "a = b" in D.Hmm, isn't there a problem that if you do func(T a) { T b:=a; } b is null if T is reference-type, so it can't even have the value assigned? You can't explicitly new it, because that wouldn't work with primitive types again. It could get automatically allocated, but that'd require the class to have a zero-parameter constructor, which may again break, and in fact, calling it may cause unforeseen effects. Just allocating memory without calling the constructor is not an option at all, because the opValue (or whatever) may depend on the objects state being initialized... Furthermore, if you do a:=b+c, you needlessly create a new object (the result of b+c), so it would be very inefficient. Finally, if (a is b), modifying either with := would also modify the other, so you just move the problem to other cases. In other words, a:=c+d modifies b as well, and it's a=c+d that doesn't. IMO, all of these mean that := will not actually help with the value_types/reference_types divide, but will instead only shift the problems to other cases. I think the best option is to either - write two versions of templates, one specialized on Object, or - use the a=b+0 idiom and implement opAdd on all relevant classes xs0Apr 21 2005xs0 wrote:Please, look at my post in different branch of this thread: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/22165Correct me if I'm mistaken, but I think what you are saying only takes reference types into account. The idea here is to get away from the risk of code failing to work when value types and reference types inevitably get confused. There is, for example, not much sense to the following code... int a = 5.dup; int b; int c; b = a.dup + 7.dup; c = b.dup; Of course, this is an extreme case, but it is meant to illustrate a point. If the programmer wants to be sure that they are assigning values, and not changing the address of somehting, then the ":=" operator would be used... int a := 5; int b; int c; b := a+7; c := b; No ambiguity there. Notice that with this convention, one would know what "a := b" is supposed to do, even without knowing what "a" and "b" represent. The same can not be said of "a = b" in D.Hmm, isn't there a problem that if you do func(T a) { T b:=a; } b is null if T is reference-type, so it can't even have the value assigned? You can't explicitly new it, because that wouldn't work with primitive types again. It could get automatically allocated, but that'd require the class to have a zero-parameter constructor, which may again break, and in fact, calling it may cause unforeseen effects.Just allocating memory without calling the constructor is not an option at all, because the opValue (or whatever) may depend on the objects state being initialized... Furthermore, if you do a:=b+c, you needlessly create a new object (the result of b+c), so it would be very inefficient. Finally, if (a is b), modifying either with := would also modify the other, so you just move the problem to other cases. In other words, a:=c+d modifies b as well, and it's a=c+d that doesn't. IMO, all of these mean that := will not actually help with the value_types/reference_types divide, but will instead only shift the problems to other cases. I think the best option is to either - write two versions of templates, one specialized on Object, or - use the a=b+0 idiom and implement opAdd on all relevant classes xs0-- VladimirApr 21 2005With .init on classes: - all uninitialized vars of a class will point to the same object - using := with any of them will change all the others - so, even trivial code like func(T a, T b) { T c:=a+b; T d:=a*b; return c/d; } will totally not work, because after the second line, c will have the same value as d, so the result will always be the same (1, assuming some normal numeric class). In a multithreaded app, things will get even uglier, because c and d may get modified from outside, which is not the case with =. xs0Hmm, isn't there a problem that if you do func(T a) { T b:=a; } b is null if T is reference-type, so it can't even have the value assigned? You can't explicitly new it, because that wouldn't work with primitive types again. It could get automatically allocated, but that'd require the class to have a zero-parameter constructor, which may again break, and in fact, calling it may cause unforeseen effects.Please, look at my post in different branch of this thread: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/22165Apr 21 2005xs0 wrote:Yes, you are right and I was wrong. Possible solution is to allow .init property to return new instance of class: class A { static A init() { // return new A object with reasonable state return new A(0,0); // default is return null; } } so for now A a,b; a == b - true a is b - falseWith .init on classes: - all uninitialized vars of a class will point to the same object - using := with any of them will change all the others - so, even trivial code likeHmm, isn't there a problem that if you do func(T a) { T b:=a; } b is null if T is reference-type, so it can't even have the value assigned? You can't explicitly new it, because that wouldn't work with primitive types again. It could get automatically allocated, but that'd require the class to have a zero-parameter constructor, which may again break, and in fact, calling it may cause unforeseen effects.Please, look at my post in different branch of this thread: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/22165func(T a, T b) { T c:=a+b; T d:=a*b; return c/d; } will totally not work, because after the second line, c will have the same value as d, so the result will always be the same (1, assuming some normal numeric class). In a multithreaded app, things will get even uglier, because c and d may get modified from outside, which is not the case with =.-- VladimirApr 22 2005No, if the variable is uninitialized and a value is assigned, then assigning that value "is" the initialization. You don't just throw a copy of the value where-ever the unitinitialized reference type happens to be pointing to. an implicit "new" would alocate the space for it. The idea is to make a value assignment operator that works with both value and reference types, not to make one that works with value types and fails to accomodate reference types. That wouldn't be any improvement over what we have now. TZ "xs0" <xs0 xs0.com> wrote in message news:d49aeq$1047$1 digitaldaemon.com...With .init on classes: - all uninitialized vars of a class will point to the same object - using := with any of them will change all the others - so, even trivial code like func(T a, T b) { T c:=a+b; T d:=a*b; return c/d; } will totally not work, because after the second line, c will have the same value as d, so the result will always be the same (1, assuming some normal numeric class). In a multithreaded app, things will get even uglier, because c and d may get modified from outside, which is not the case with =. xs0Hmm, isn't there a problem that if you do func(T a) { T b:=a; } b is null if T is reference-type, so it can't even have the value assigned? You can't explicitly new it, because that wouldn't work with primitive types again. It could get automatically allocated, but that'd require the class to have a zero-parameter constructor, which may again break, and in fact, calling it may cause unforeseen effects.Please, look at my post in different branch of this thread: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/22165Apr 22 2005TechnoZeus wrote:No, if the variable is uninitialized and a value is assigned, then assigning that value "is" the initialization.How exactly do you expect the compiler to know what is and what isn't the value of an object? For example, if the object is just a wrapper for another object, the other object is the value, so it won't help to shallow-copy the original. OTOH, doing a deep-copy by default sucks, because in many cases it's not needed (w/ unmodifiable objects), and/or not desired (you don't want to have 25000 connections to a database open). So, the only sensible option is to make the object provide its own duplicate. You can already do that. OK, so you have two versions of the template. If you don't want two versions of the main template, write an assign template, specialize it for Objects and arrays, and use wherever you'd use a=b. Again, note that this issue only applies to simple assignments "a=b". In the case of expression "a=b+c", a new object will be constructed as-is, so there is no need for another operator.You don't just throw a copy of the value where-ever the unitinitialized reference type happens to be pointing to. an implicit "new" would alocate the space for it.You'd always allocate a new object, even if it was already allocated?The idea is to make a value assignment operator that works with both value and reference types, not to make one that works with value types and fails to accomodate reference types. That wouldn't be any improvement over what we have now.Duh! xs0"xs0" <xs0 xs0.com> wrote in message news:d49aeq$1047$1 digitaldaemon.com...With .init on classes: - all uninitialized vars of a class will point to the same object - using := with any of them will change all the others - so, even trivial code like func(T a, T b) { T c:=a+b; T d:=a*b; return c/d; } will totally not work, because after the second line, c will have the same value as d, so the result will always be the same (1, assuming some normal numeric class). In a multithreaded app, things will get even uglier, because c and d may get modified from outside, which is not the case with =. xs0Hmm, isn't there a problem that if you do func(T a) { T b:=a; } b is null if T is reference-type, so it can't even have the value assigned? You can't explicitly new it, because that wouldn't work with primitive types again. It could get automatically allocated, but that'd require the class to have a zero-parameter constructor, which may again break, and in fact, calling it may cause unforeseen effects.Please, look at my post in different branch of this thread: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/22165Apr 25 2005"xs0" <xs0 xs0.com> wrote in message news:d4ilv1$1m84$1 digitaldaemon.com...TechnoZeus wrote: How exactly do you expect the compiler to know what is and what isn't the value of an object?*snip*xs0I don't expect the compiler to know the difference at that level. Right now, it doesn't know the difference at "any" level. It simply copies identities or values depending on what it is dealing with. All I'm asking for is a way to remove the "depending on what it is dealing with" and replace it with "depending on what it was asked to do" so that it will if the value of an item is an address, or a wrapper, or whatever, we can compare or assign that "value" without having to first establish what syntax we have to use based on what the value is contained in. In other words, a:=b should "always" mean... copy the contents of "b" into "a" no matter whther "a" and "b" are classes, integers, arrays, or what ever, as long as it is possible to change the value of "a" and as long as the data contained in "b" is capable of being stored in "a" ... period. TZApr 27 2005TechnoZeus wrote:"xs0" <xs0 xs0.com> wrote in message news:d4ilv1$1m84$1 digitaldaemon.com...No, it always copies the value. You just seem to think that the value of a reference is the object it's pointing to, not the reference itself.TechnoZeus wrote: How exactly do you expect the compiler to know what is and what isn't the value of an object?*snip*xs0I don't expect the compiler to know the difference at that level. Right now, it doesn't know the difference at "any" level. It simply copies identities or values depending on what it is dealing with.All I'm asking for is a way to remove the "depending on what it is dealing with" and replace it with "depending on what it was asked to do"OK then, how do you expect the compiler to know what it was asked to do? Again, you assume it is possible for the compiler to automatically know what _you_ consider a value.so that it will if the value of an item is an address, or a wrapper, or whatever, we can compare or assign that "value" without having to first establish what syntax we have to use based on what the value is contained in.Again, the only reasonable way to do this is to let the object itself determine what its value is (in other words, to let you determine it). If you do that, you will still have to use different syntax, it will just be shifted elsewhere. int a:=b; // OK Object c:=d; // not OK, because c is nullIn other words, a:=b should "always" mean... copy the contents of "b" into "a" no matter whther "a" and "b" are classes, integers, arrays, or what ever, as long as it is possible to change the value of "a" and as long as the data contained in "b" is capable of being stored in "a" ... period.See the above example for why you need to handle things differently in any case. Using dummy init values is a somewhat naive solution, and just copying bit-by-bit is only an option if both sides are of the exact same type, even if you disregard what a source of bugs it can be. I feel you don't realize that it's not possible to somehow magically treat globals, stack variables (locals) and heap variables (objects) all the same. Each have their specifics which you have to be aware of in order to use them correctly. Even a local int and a global int differ in important ways, and they're both ints. You're just so used to their differences (like their lifetime), you don't see it as an issue. xs0Apr 28 2005"xs0" <xs0 xs0.com> wrote in message news:d4qt4a$unl$1 digitaldaemon.com...TechnoZeus wrote:I realize more than you are aparently capable of comprehending. What you are stating as imutable fact is actually implementation dependant. Unfortunatley, I don't know how it was implemented in D, but I know there is more than one way of looking at it, and more than one way of implementing it. In case you hadn't noticed, the compiler does know the difference between a reference type and a value type. Well... Obviously, either those who want the same thing I want are either the minority, or mostly quiet people... so I'm giving up. I've stated my case, and I'm getting insults for it rather than discussion. I have better things to do. Donald A. Kronos, PhD. - TechnoZeus"xs0" <xs0 xs0.com> wrote in message news:d4ilv1$1m84$1 digitaldaemon.com...No, it always copies the value. You just seem to think that the value of a reference is the object it's pointing to, not the reference itself.TechnoZeus wrote: How exactly do you expect the compiler to know what is and what isn't the value of an object?*snip*xs0I don't expect the compiler to know the difference at that level. Right now, it doesn't know the difference at "any" level. It simply copies identities or values depending on what it is dealing with.All I'm asking for is a way to remove the "depending on what it is dealing with" and replace it with "depending on what it was asked to do"OK then, how do you expect the compiler to know what it was asked to do? Again, you assume it is possible for the compiler to automatically know what _you_ consider a value.so that it will if the value of an item is an address, or a wrapper, or whatever, we can compare or assign that "value" without having to first establish what syntax we have to use based on what the value is contained in.Again, the only reasonable way to do this is to let the object itself determine what its value is (in other words, to let you determine it). If you do that, you will still have to use different syntax, it will just be shifted elsewhere. int a:=b; // OK Object c:=d; // not OK, because c is nullIn other words, a:=b should "always" mean... copy the contents of "b" into "a" no matter whther "a" and "b" are classes, integers, arrays, or what ever, as long as it is possible to change the value of "a" and as long as the data contained in "b" is capable of being stored in "a" ... period.See the above example for why you need to handle things differently in any case. Using dummy init values is a somewhat naive solution, and just copying bit-by-bit is only an option if both sides are of the exact same type, even if you disregard what a source of bugs it can be. I feel you don't realize that it's not possible to somehow magically treat globals, stack variables (locals) and heap variables (objects) all the same. Each have their specifics which you have to be aware of in order to use them correctly. Even a local int and a global int differ in important ways, and they're both ints. You're just so used to their differences (like their lifetime), you don't see it as an issue. xs0Apr 29 2005"xs0" <xs0 xs0.com> wrote in message news:d48tfo$k26$1 digitaldaemon.com...Hmm, isn't there a problem that if you do func(T a) { T b:=a; } b is null if T is reference-type, so it can't even have the value assigned? You can't explicitly new it, because that wouldn't work with primitive types again. It could get automatically allocated, but that'd require the class to have a zero-parameter constructor, which may again break, and in fact, calling it may cause unforeseen effects.No, there's no problem with it at all. You're thinking in C. TZApr 22 2005"pragma" <pragma_member pathlink.com> wrote in message news:d48dib$57l$1 digitaldaemon.com...In article <d46v3g$1n7o$1 digitaldaemon.com>, Ben Hinkle says...[snip] One issue with .dup is that the expression x.dup calls the same thing if x is a struct or a ptr to a struct. Not that I'm complaining since I don't think the := does any better wrt pointers. In general I'm not optimistic about either := or .dup helping template programming by themselves. I'd like to see more motivating examples of what the problems are and what the workarounds look like. Sometimes the cure is worse than the disease.About the template problem: I'd prefer to look into something like extending ".dup" to all types rather than invent a new operator.Ben, thank you. You took the words right out of my mouth. :) For classes, there's no need to make this a formal 'operator'. It could merely be added to Object as a shallow copy (return this;) and then overridden in any class where it's needed. So really, all that's needed is a 'dup' property for scalars. The rest is up to the developer.Apr 21 2005Ben Hinkle wrote:I'd like to see more motivating examples of what the problems are and what the workarounds look like. Sometimes the cure is worse than the disease.One of examples you can find at the end of my post in different branch of this thread: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/22137 Of course there are workarounds, but they are ugly and error-prone. The biggest problems occurs when one tries to make template from non-template function. Or when one had written and tested template and then realized that it won't work with his new class-based type and should be rewritten. And this can't be solved with .dup() property. BTW in C++ this example can be _easily_ implemented. -- VladimirApr 21 2005"Vladimir" <kv11111 mail.ru> wrote in message news:d492pb$p4h$1 digitaldaemon.com...Ben Hinkle wrote:A complete example from an actual project was what I had in mind. The posted example wasn't complete and the purpose didn't make sense to me. There were many issues hidden under the dots (...) that would be nice to see.I'd like to see more motivating examples of what the problems are and what the workarounds look like. Sometimes the cure is worse than the disease.One of examples you can find at the end of my post in different branch of this thread: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/22137Of course there are workarounds, but they are ugly and error-prone.Two versions (one for Object and one for everything else) seems reasonable to me. It depends on the template. If there is alot of code shared between the templates mixins can help factor it out.The biggest problems occurs when one tries to make template from non-template function. Or when one had written and tested template and then realized that it won't work with his new class-based type and should be rewritten. And this can't be solved with .dup() property.Can you give a more complete example? I'm assume this happened to you for real. <flame-alert>BTW in C++ this example can be _easily_ implemented.I assume you mean because classes have value semantics in C++. I'd say C++ templates are more error-prone than D templates due to all the magic in C++ templates. </flame-alert>Apr 21 2005Can you give a more complete example? I'm assume this happened to you for real.I haven't written this yet, but I am pretty sure it is impossible: A template that implements a linked list (or any other container), such that when you add an object to the list it copies the object. You may want to do this so you can roll back the state of your program, ie an undo button. There are 2 problems with this 1) Doesn't work with both references and builtings/structs 2) No language specified way to work around it, so you have to cook your own .dup property, or whatever - but it won't work with classes that don't provide that custom function. You could standardize on using copy constructor - but builtins and structs don't have them. So there we go - a templated linked list that copies the objects added to it is impossible in D. If I am wrong - please enlighten me :) BradApr 21 2005"Brad Beveridge" <brad somewhere.net> wrote in message news:d495k4$rrl$1 digitaldaemon.com...My first reaction is that the simplest solution is to use a regular linked list and have either the calling code dup whatever they needs to be dup'ed. The user knows their objects the best and how to handle the references so keeping the linked list as simple as possible makes them more usable. Why have something as simple as a linked list try to worry about duplicating the objects in the list? That shouldn't be its job. If it really is needed to make the list copy the objects I'd try writing a template with different specializations that share code for common actions. Since Object doesn't have any dup property the templates would only work for objects that define some form of duplication.Can you give a more complete example? I'm assume this happened to you for real.I haven't written this yet, but I am pretty sure it is impossible: A template that implements a linked list (or any other container), such that when you add an object to the list it copies the object. You may want to do this so you can roll back the state of your program, ie an undo button. There are 2 problems with this 1) Doesn't work with both references and builtings/structs 2) No language specified way to work around it, so you have to cook your own .dup property, or whatever - but it won't work with classes that don't provide that custom function. You could standardize on using copy constructor - but builtins and structs don't have them.So there we go - a templated linked list that copies the objects added to it is impossible in D. If I am wrong - please enlighten me :)If you mean in a single template then I agree. I wasn't asking for examples because I didn't think it was impossible. I was asking for examples to see what the problem is, what the workarounds look like and how := would be any better than various other solutions. The general topic of writing templates that works with reference and value types has come up before (probably many times) and dup or := or whatever is one piece of the bigger picture. In any case IMO this whole thread should wait until after 1.0.Apr 21 2005:= wouldn't assign the value of a struct pointed to by it's right operand. It would assign the value of it's right operand. Even if that operand is a pointer, in which case it's value is the address of the location that it points to. Not the data stored at that location. In other words, no it wouldn't have the same problem. TZ "Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d48sn8$jbq$1 digitaldaemon.com..."pragma" <pragma_member pathlink.com> wrote in message news:d48dib$57l$1 digitaldaemon.com...In article <d46v3g$1n7o$1 digitaldaemon.com>, Ben Hinkle says...[snip] One issue with .dup is that the expression x.dup calls the same thing if x is a struct or a ptr to a struct. Not that I'm complaining since I don't think the := does any better wrt pointers. In general I'm not optimistic about either := or .dup helping template programming by themselves. I'd like to see more motivating examples of what the problems are and what the workarounds look like. Sometimes the cure is worse than the disease.About the template problem: I'd prefer to look into something like extending ".dup" to all types rather than invent a new operator.Ben, thank you. You took the words right out of my mouth. :) For classes, there's no need to make this a formal 'operator'. It could merely be added to Object as a shallow copy (return this;) and then overridden in any class where it's needed. So really, all that's needed is a 'dup' property for scalars. The rest is up to the developer.Apr 22 2005On Thu, 21 Apr 2005 14:32:43 +0000 (UTC), pragma <pragma_member pathlink.com> wrote:In article <d46v3g$1n7o$1 digitaldaemon.com>, Ben Hinkle says...Assuming .dup is added for intrinsics. However... Dereks original goal was to achieve this: class A {} class B {} A a = new A(); B b; b = a; i.e. construct b using a. The current proposed method is a copy constructor. But, as intrinsics have no constructors how do you write it generically? := solves that problem as well as the other which .dup can solve. ReganAbout the template problem: I'd prefer to look into something like extending ".dup" to all types rather than invent a new operator.Ben, thank you. You took the words right out of my mouth. :) For classes, there's no need to make this a formal 'operator'. It could merely be added to Object as a shallow copy (return this;) and then overridden in any class where it's needed. So really, all that's needed is a 'dup' property for scalars. The rest is up to the developer. class Foobar{ public Foobar dup(){ return this; // or a copy } } void main(){ Foobar a,b; a = new Foobar(); b = a.dup; // custom ('deep') copy int c,d; c = d.dup; // value-copy: allowed for consistency int[] e,f e = f.dup; // old hat } The above folds into templates, extremely well: template valueOf(T){ T valueOf(T x){ return x.dup; } } .. where 'T' can be, well, anything. I'll add that the above is also *impossible* with ':=' and would require a temporary varible to work. Thus, it would be less flexible (and probably useful IMO). There's absolutely no need for an additional operator like ':='.Apr 21 2005Hello All ! Here is patch for gdc-0.10 implementing and = operators. This patch is not intended for direct use, this is just my test how can it be done. is unary operator which currently: tries to overwrite expression as rvalue.opValue() returns rvalue for structs without opValue returns rvalue for arithmetic types fails to compile otherwise. = is binary operator which currently: tries to overwrite expression as lvalue.opValueAssign(rvalue) overwrites expression as lvalue = rvalue for structs without opValueAssign overwrites expression as lvalue = rvalue for arithmetic types fails otherwise ' ' symbol means 'at' which emphasizes it's meaning in language: a means "get value *at* given location" and a = means "store value *at* given location" ':=' is bad because D already has too many meanings for symbol ':'. TODO: overwrite array as array.dup (recursion here ?) overwrite a =array as a=array.dup (recursion here ?) decide what to do with pointers (possibilities: return rvalue return *rvalue return **...*rvalue (recursively)) Other ideas related to general template programming: Allow static .init property for classes which will return new instance of class for default variable initializing (by default return null). For any type T allow T& and T for reference (pointer?) and value types. Multiple-applying should behave as: T&& equals T& and T equals T . For classes T& equals T, for structs and built-in types T equals T. May be this is too global change to be accepted, but it has a lot of benefits. -- VladimirApr 25 2005In article <d4ipf2$1poj$1 digitaldaemon.com>, Vladimir says...--nextPart1356870.LVNHTvSSDs Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 8Bit Hello All ! Here is patch for gdc-0.10 implementing and = operators. This patch is not intended for direct use, this is just my test how can it be done. [snip]Vlad, Thank you for taking the bazaar concept (or 'microfork' if you will) seriously and writing a reference implementation for this feature concept. I only hope that this stands as an example for how to more effectively communicate new language concepts from here on out (as has been discussed to death in this forum before). One question remains: what is the most effective way to apply such a patch for us *nix neophytes? - EricAnderton at yahooApr 25 2005pragma wrote:One question remains: what is the most effective way to apply such a patch for us *nix neophytes?Change to the "d" directory (where you unpacked GDC 0.10) and: patch -p1 -i d-opValue.patch Sometimes linefeeds will give you trouble... (ie. UNIX vs. DOS) Then you need to translate the Windows files to drop the '\r'. --anders PS. See also http://www.gnu.org/software/diffutils/manual/Apr 25 2005pragma wrote:Vlad, Thank you for taking the bazaar concept (or 'microfork' if you will) seriously and writing a reference implementation for this feature concept. I only hope that this stands as an example for how to more effectively communicate new language concepts from here on out (as has been discussed to death in this forum before).Thanks for your support ! Actually while implementing this patch I've found some places where I was wrong in discussion and got some new ideas about how to do it better.One question remains: what is the most effective way to apply such a patch for us *nix neophytes? - EricAnderton at yahoo-- VladimirApr 25 2005Vladimir wrote:TODO: overwrite array as array.dup (recursion here ?) overwrite a =array as a=array.dup (recursion here ?) decide what to do with pointers (possibilities: return rvalue return *rvalue return **...*rvalue (recursively))After thinking again: TODO: 1. By default (if not overloaded) recursively apply = to all members if lvalue and rvalue are of the same aggregate type (class, struct or array). Overloading are still need for (a) type conversion and (b) external resources handling. 2. By default (if not overloaded) try to rewrite a as { typeof(a) __t; __t = a; return __t; } This needs either a. Somehow redefine = for correct handling null lvalue (for example change overloading signature to: static T opAssignValue(inout T to, T from); so that inside function one can check if to is null react appropriate) b. Implement .init property for classes. Without this the following examples will cause seg-v: /* Can be solved by overloading opAssignValue for struct S */ class C { ... } struct S { C c; } S a, b; a = b; /* Can't be solved */ C[] array1 = new C[1]; C[] array2 = new C[1]; array2[0] = new C; array1 = array2; -- VladimirApr 25 2005