www.digitalmars.com         C & C++   DMDScript  

D - String comparison ==

reply Barry Pederson <barryp yahoo.com> writes:
The D HTML page on arrays mentions:

-----------
  Strings can be copied, compared, concatenated, and appended:

    if (str1 < str3) ...
-----------

When I see "compared", I would take that to mean you could compare for content 
equality using the "==" operator - but that doesn't seem to be the case, and D 
seems to just do C-style pointer comparisons.

Is string-content comparison using == just something that hasn't been 
implemented yet?  or are the docs a bit misleading and string.cmp() is how 
it's going to have to be done?

	Barry
Mar 07 2002
next sibling parent "Pavel Minayev" <evilone omen.ru> writes:
"Barry Pederson" <barryp yahoo.com> wrote in message
news:3C883E19.3030407 yahoo.com...

 When I see "compared", I would take that to mean you could compare for

 equality using the "==" operator - but that doesn't seem to be the case,

 seems to just do C-style pointer comparisons.

This is the topic raised several times, and I remember we've got to the idea that some separate operator to compare arrays is needed (because strings are just char arrays). Walter keeps silent on the topic, though, so the question is still open.
Mar 07 2002
prev sibling next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Barry Pederson" <barryp yahoo.com> wrote in message
news:3C883E19.3030407 yahoo.com...
 The D HTML page on arrays mentions:

 -----------
   Strings can be copied, compared, concatenated, and appended:

     if (str1 < str3) ...
 -----------

 When I see "compared", I would take that to mean you could compare for

 equality using the "==" operator - but that doesn't seem to be the case,

 seems to just do C-style pointer comparisons.

 Is string-content comparison using == just something that hasn't been
 implemented yet?  or are the docs a bit misleading and string.cmp() is how
 it's going to have to be done?

The issue is confusing, and it's a bit up in the air at the moment.
Mar 07 2002
next sibling parent reply "Immanuel Scholz" <digitals-mars kutzsche.net> writes:
"Walter" <walter digitalmars.com> schrieb im Newsbeitrag
news:a69s6c$m38$1 digitaldaemon.com...
 "Barry Pederson" <barryp yahoo.com> wrote in message
 news:3C883E19.3030407 yahoo.com...
 The D HTML page on arrays mentions:

 -----------
   Strings can be copied, compared, concatenated, and appended:

     if (str1 < str3) ...
 -----------

 When I see "compared", I would take that to mean you could compare for

 equality using the "==" operator - but that doesn't seem to be the case,

 seems to just do C-style pointer comparisons.

 Is string-content comparison using == just something that hasn't been
 implemented yet?  or are the docs a bit misleading and string.cmp() is


 it's going to have to be done?

The issue is confusing, and it's a bit up in the air at the moment.

If I remember right, in Perl the operator "eq" is used.. what about that? Imi
Mar 08 2002
parent "Pavel Minayev" <evilone omen.ru> writes:
"Immanuel Scholz" <digitals-mars kutzsche.net> wrote in message
news:a6antm$10nh$1 digitaldaemon.com...

 If I remember right, in Perl the operator "eq" is used.. what about that?

I always hated it. Too hard to distinguish from name of local variable in a typical D program, anyhow. I believe it should be some sequence of special symbols rather than keyword. I suggested ~~ and !~ a while ago, but these aren't ideal because they are missing on some national keyboards. Maybe === and !== then? Lengthy, but I personally could leave with it...
Mar 08 2002
prev sibling parent reply "Richard Krehbiel" <rich kastle.com> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a69s6c$m38$1 digitaldaemon.com...
 "Barry Pederson" <barryp yahoo.com> wrote in message
 news:3C883E19.3030407 yahoo.com...
 The D HTML page on arrays mentions:

 -----------
   Strings can be copied, compared, concatenated, and appended:

     if (str1 < str3) ...
 -----------

 When I see "compared", I would take that to mean you could compare for

 equality using the "==" operator - but that doesn't seem to be the case,

 seems to just do C-style pointer comparisons.

 Is string-content comparison using == just something that hasn't been
 implemented yet?  or are the docs a bit misleading and string.cmp() is


 it's going to have to be done?

The issue is confusing, and it's a bit up in the air at the moment.

I might suggest that this is a good reason for having "string" be a separate data type from "char[]". -- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 comcast.net (personal)
Mar 08 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Richard Krehbiel" <rich kastle.com> wrote in message
news:a6aos4$118b$1 digitaldaemon.com...

 I might suggest that this is a good reason for having "string" be a

 data type from "char[]".

This has been discussed, and apart from the ability to define operator+ for concatenation, and operators == != < > <= >= for string comparison, it doesn't give any other opportunities.
Mar 08 2002
next sibling parent reply "Richard Krehbiel" <rich kastle.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a6apl9$11fn$1 digitaldaemon.com...
 "Richard Krehbiel" <rich kastle.com> wrote in message
 news:a6aos4$118b$1 digitaldaemon.com...

 I might suggest that this is a good reason for having "string" be a

 data type from "char[]".

This has been discussed, and apart from the ability to define operator+ for concatenation, and operators == != < > <= >= for string comparison, it doesn't give any other opportunities.

You say that as if those things are inconsequential. I think they're not. Well, operator + might be. -- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 comcast.net (personal)
Mar 08 2002
parent "Pavel Minayev" <evilone omen.ru> writes:
"Richard Krehbiel" <rich kastle.com> wrote in message
news:a6av8p$140b$1 digitaldaemon.com...

 You say that as if those things are inconsequential.  I think they're not.
 Well, operator + might be.

I'm pretty happy with operator~ now. If Walter also gives us array equality/non-equality operator, I'll be completely satisfied.
Mar 08 2002
prev sibling parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Pavel Minayev wrote:

 "Richard Krehbiel" <rich kastle.com> wrote in message
 news:a6aos4$118b$1 digitaldaemon.com...

 I might suggest that this is a good reason for having "string" be a

 data type from "char[]".

This has been discussed, and apart from the ability to define operator+ for concatenation, and operators == != < > <= >= for string comparison, it doesn't give any other opportunities.

Indeed, and I think that NOT having a separate type GIVES us new opportunities. Eventually, we will agree on some sort of syntax that makes sense. But since char[] is not a unique type with unique rules, this syntax will be able to be used on ALL arrays...perhaps even multidimensional arrays, if we are careful with how we choose the syntax. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Mar 08 2002
prev sibling next sibling parent reply "Derjo Phar" <not available.com> writes:
"Barry Pederson" <barryp yahoo.com> wrote in message
news:3C883E19.3030407 yahoo.com...
 The D HTML page on arrays mentions:

 -----------
   Strings can be copied, compared, concatenated, and appended:

     if (str1 < str3) ...
 -----------

 When I see "compared", I would take that to mean you could compare for

 equality using the "==" operator - but that doesn't seem to be the case,

 seems to just do C-style pointer comparisons.

 Is string-content comparison using == just something that hasn't been
 implemented yet?  or are the docs a bit misleading and string.cmp() is how
 it's going to have to be done?

 Barry

Mar 08 2002
parent "Derjo Phar" <not available.com> writes:
Sorry about the multiple posts. Bloody Outlook Express just took over!
Mar 08 2002
prev sibling parent reply "Derjo Phar" <not available.com> writes:
"Barry Pederson" <barryp yahoo.com> wrote in message
news:3C883E19.3030407 yahoo.com...
 The D HTML page on arrays mentions:

 -----------
   Strings can be copied, compared, concatenated, and appended:

     if (str1 < str3) ...
 -----------

 When I see "compared", I would take that to mean you could compare for

 equality using the "==" operator - but that doesn't seem to be the case,

 seems to just do C-style pointer comparisons.

 Is string-content comparison using == just something that hasn't been
 implemented yet?  or are the docs a bit misleading and string.cmp() is how
 it's going to have to be done?

 Barry

What is that coders are trying find out when they code : if (a == b) My guess is that, of all the properties of 'a' and 'b', they are trying to find out if the value (aka content) of 'a' is identical to the value of 'b'. Now you and I know that 'a' and 'b' are really a type of shorthand for referencing a RAM location, and depending on the data type, how much RAM they take up. But programming languages exist to hide all that yucky detail. So therefore, when we see 'a' and 'b' in source code, we tend to think of them as having content or value. If D wants to be self consistent, plus being helpful to coders, this comparision should mean the same regardless of the datatypes that 'a' and 'b' happen to be. For example, if 'a' and 'b' were both integers, we would expect to be comparing the contents of 'a' and 'b', not their RAM addresses. Also, if 'a' and 'b' were both floating point numbers, we would expect to be comparing the contents of 'a' and 'b', not their RAM addresses. Now if 'a' and 'b' are arrays, shouldn't we also expect D to compare their contents rather than the RAM addresses of their first byte? N.B.: Disregard this idea if D is trying to be (C++)++
Mar 08 2002
next sibling parent reply Barry Pederson <barryp yahoo.com> writes:
Derjo Phar wrote:

 What is that coders are trying find out when they code :
 
      if (a == b)
 
 My guess is that, of all the properties of 'a' and 'b', they are trying to
 find out if the value (aka content) of 'a' is identical to the value  of
 'b'.
 
 Now you and I know that 'a' and 'b' are really a type of shorthand for
 referencing a RAM location, and depending on the data type, how much RAM
 they take up. But programming languages exist to hide all that yucky detail.
 So therefore, when we see 'a' and 'b' in source code, we tend to think of
 them as having content or value.
 
 If D wants to be self consistent, plus being helpful to coders, this
 comparision should mean the same regardless of the datatypes that 'a' and
 'b' happen to be.
 
 For example, if 'a' and 'b' were both integers, we would expect to be
 comparing the contents of 'a' and 'b', not their RAM addresses.
 
 Also, if 'a' and 'b' were both floating point numbers, we would expect to be
 comparing the contents of 'a' and 'b', not their RAM addresses.
 
 Now if 'a' and 'b' are arrays, shouldn't we also expect D to compare their
 contents rather than the RAM addresses of their first byte?

Well said. Let me throw this out: arrays have a length and a pointer. We can access the length with the .length property, how about adding a .pointer (or .ptr, or .addr) property to access the pointer to the array's data (that would the appropriate type for the array). So for example, given "ubyte[] b", b.pointer would have the type: (ubyte *) Then if you wanted to do a comparison of the RAM addresses of two arrays, you could say: if (a.pointer == b.pointer) ... Instead of the more verbose: if ((ubyte *) a == (ubyte *) b) ... There's also the advantage that if you ever changed the array types for a or b, you wouldn't have to go through and change the casts in any pointer comparisons. Then you'd be free to use "==" for array content comparison. Right now there is string.cmp() for char[] comparison, but what about comparing other array types? Ideally, you should even be able to compare arrays of different types, assuming the elements within the arrays can be compared. So [1, 2, 3] == [1.0, 2.0, 3.0]. Barry
Mar 08 2002
parent reply "Walter" <walter digitalmars.com> writes:
"Barry Pederson" <barryp yahoo.com> wrote in message
news:3C89924D.2020507 yahoo.com...
 Let me throw this out:  arrays have a length and a pointer.  We can access

 length with the .length property, how about adding a .pointer (or .ptr, or
 .addr) property to access the pointer to the array's data (that would the
 appropriate type for the array).   So for example, given "ubyte[] b",
 b.pointer would have the type: (ubyte *)

 Then if you wanted to do a comparison of the RAM addresses of two arrays,

 could say:

      if (a.pointer == b.pointer)
          ...

 Instead of the more verbose:

      if ((ubyte *) a == (ubyte *) b)
          ...

 There's also the advantage that if you ever changed the array types for a

 b, you wouldn't have to go through and change the casts in any pointer
 comparisons.

Comparing the pointers isn't sufficient, as two arrays aren't "equal" unless both the lengths and the pointers match. For conversions to a pointer, a cast to (void*) will have the properties you suggest, although I agree it is a little less appealing in appearance <g>.
Mar 26 2002
parent reply Barry Pederson <barryp yahoo.com> writes:
Walter wrote:
 "Barry Pederson" <barryp yahoo.com> wrote in message
 news:3C89924D.2020507 yahoo.com...
 
Let me throw this out:  arrays have a length and a pointer.  We can access

the
length with the .length property, how about adding a .pointer (or .ptr, or
.addr) property to access the pointer to the array's data (that would the
appropriate type for the array).   So for example, given "ubyte[] b",
b.pointer would have the type: (ubyte *)

Then if you wanted to do a comparison of the RAM addresses of two arrays,

you
could say:

     if (a.pointer == b.pointer)
         ...

Instead of the more verbose:

     if ((ubyte *) a == (ubyte *) b)
         ...

There's also the advantage that if you ever changed the array types for a

or
b, you wouldn't have to go through and change the casts in any pointer
comparisons.

Comparing the pointers isn't sufficient, as two arrays aren't "equal" unless both the lengths and the pointers match. For conversions to a pointer, a cast to (void*) will have the properties you suggest, although I agree it is a little less appealing in appearance <g>.

Agreed, but I wasn't claiming that pointer comparison would be a way to check if arrays were equal - it was just a suggestion for a way to implement the old C-style compare-by-address of two things: a and b, if it had been decided that "a == b" was going to be compare-by-content. The ".pointer" thing seemed nicely orthogonal to having the ".length" property. But I think the later suggestion to use "a[] == b" to compare content is even better, since that seemed a good counterpoint to using "a[] = b" to copy content (and made the .pointer thing not quite so necessary) I'm lukewarm to the proposal to use "===", I think it'd be awfully easy to slip-up and type "==", which would be perfectly valid to the compiler too. On some screens or printouts or books, depending on the font, it might be hard to tell how many "="s are in there. But given a choice between "===" and "string.cmp()", I'd take "===" I guess. Barry
Mar 26 2002
next sibling parent "Pavel Minayev" <evilone omen.ru> writes:
"Barry Pederson" <barryp yahoo.com> wrote in message
news:3CA1433D.5050900 yahoo.com...

 But I think the later suggestion to use "a[] == b" to compare content is

 better, since that seemed a good counterpoint to using "a[] = b" to copy
 content (and made the .pointer thing not quite so necessary)

Since == is a binary operator, it is defined on arrays like this: c = (a[] == b); // is implemented as: for (int i = 0; i < a.length; i++) c[i] = (a[i] == b[i]); That is, all elements are compared, and you get a bit array of results. I guess this is how it was supposed to work.
Mar 26 2002
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
"Barry Pederson" <barryp yahoo.com> wrote in message
news:3CA1433D.5050900 yahoo.com...
 Agreed, but I wasn't claiming that pointer comparison would be a way to

 if arrays were equal - it was just a suggestion for a way to implement the

 C-style compare-by-address of two things: a and b, if it had been decided

   "a == b" was going to be compare-by-content.  The ".pointer" thing

 nicely orthogonal to having the ".length" property.

Yes, it is nicely orthogonal.
 But I think the later suggestion to use "a[] == b" to compare content is

 better, since that seemed a good counterpoint to using "a[] = b" to copy
 content (and made the .pointer thing not quite so necessary)

That was my original plan, but it died a horrible death from ambiguities with the array slicing semantics.
 I'm lukewarm to the proposal to use "===", I think it'd be awfully easy to
 slip-up and type "==", which would be perfectly valid to the compiler too.

Yes, that is a weakness of that approach. I've seen === and !== used before (javascript), so it isn't a total invention of mine.
 On some screens or printouts or books, depending on the font, it might be

 to tell how many "="s are in there.   But given a choice between "===" and
 "string.cmp()", I'd take "===" I guess.

I agree === is suboptimal, but I can't think of anything better.
Mar 26 2002
parent Barry Pederson <barryp yahoo.com> writes:
Walter wrote:
 "Barry Pederson" <barryp yahoo.com> wrote in message
 
But I think the later suggestion to use "a[] == b" to compare content is
 even
better, since that seemed a good counterpoint to using "a[] = b" to copy
content (and made the .pointer thing not quite so necessary)

That was my original plan, but it died a horrible death from ambiguities with the array slicing semantics.

I'm curious now ... what about array slicing threw a wrench in the works? if (a[] == b) if (a[w..x] == b) if (a[] == b[y..z]) if (a[w..x] == b[y..z]) seem ok to me at first glance (of somebody not actually implementing the dang thing), unless you really wanted to compare-by-reference and not by-contents, in the 2nd and 4th cases. Barry
Mar 27 2002
prev sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Derjo Phar" <not available.com> wrote in message
news:a6budn$1h6n$1 digitaldaemon.com...

 Now if 'a' and 'b' are arrays, shouldn't we also expect D to compare their
 contents rather than the RAM addresses of their first byte?

I believe this is wrong approach. Dynamic arrays are just pointers which know size of the data they point to.
Mar 08 2002
next sibling parent Russell Borogove <kaleja estarcion.com> writes:
Pavel Minayev wrote:
 "Derjo Phar" <not available.com> wrote in message
 news:a6budn$1h6n$1 digitaldaemon.com...
 
 
Now if 'a' and 'b' are arrays, shouldn't we also expect D to compare their
contents rather than the RAM addresses of their first byte?

I believe this is wrong approach. Dynamic arrays are just pointers which know size of the data they point to.

The argument still applies. I rarely care what the addresses of arrays are; I frequently care what the contents are. The only exception I can see is when you're trying to see if a and b are in fact the exact same array. I'm not sure how often this will come up in D. If I remember rightly that two array slices can share storage, then the (e.g.) [0..3] and the [0..6] slice of a given array could return equality in comparison because they have the same base address. Is that useful to anyone? -RB
Mar 09 2002
prev sibling parent reply "Derjo Phar" <not available.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a6cch7$1mph$1 digitaldaemon.com...
 "Derjo Phar" <not available.com> wrote in message
 news:a6budn$1h6n$1 digitaldaemon.com...

 Now if 'a' and 'b' are arrays, shouldn't we also expect D to compare


 contents rather than the RAM addresses of their first byte?

I believe this is wrong approach.

Why?
 Dynamic arrays are just pointers which know size of the data
 they point to.

Doesn't that depend entirely on the implementation? Or are you saying that it is axiomatic that dynamic array's are a type of pointer? I thought that a dynamic array is a data structure that can contain zero or more items of data, in which each item can be uniquely referenced by an index value. And that doesn't sound like a pointer to me. But in any case, I would hope we are not talking about generated machine code (implementation details), which is used by computers, but about program source code, which is used by people. So when we come back to people coding, what is the more common requirement we have? To see if two variables are referencing the same array, or to see if two variables contain the same data? From my experience so far (I started programming in 1972), I believe that it content comparision is intended far more frequently that pointer comparision. If D were to adopt something like the ".pointer" property syntax (thank you Barry) for all variables, it would have a few side-effects that would be beneficial. The first being that the intentions of coders would be more explicitly expressed in the source code. Another would be that changing the datatype of a variable would not be the large exercise in code changing it is today with C.
Mar 09 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Derjo Phar" <not available.com> wrote in message
news:a6du8i$2g5t$1 digitaldaemon.com...

 Doesn't that depend entirely on the implementation? Or are you saying that
 it is axiomatic that dynamic array's are a type of pointer?

I'm not sure. Walter might tell. =)
 I thought that a dynamic array is a data structure that can contain zero

 more items of data, in which each item can be uniquely referenced by an
 index value.  And that doesn't sound like a pointer to me.

Well actually it's a _pointer_ to the "data structure that ...". This comes from the fact that you can have two overlapping D arrays: int[] foo, bar; foo = bar; // now they share the same memory block
 So when we come back to people coding, what is the more common requirement
 we have? To see if two variables are referencing the same array, or to see
 if two variables contain the same data?

 From my experience so far (I started programming in 1972), I believe that

 content comparision is intended far more frequently that pointer
 comparision.

In general, I agree. D arrays are somewhat low-level, and making them more high-level seems like a logical step for me. It would be really nice to have "=" copy the arrays, and "==" to compare them for equality. This would also solve most (if not all) of string problems. That .pointer idea is also great.
Mar 09 2002
parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a6e005$2gpd$1 digitaldaemon.com...
 "Derjo Phar" <not available.com> wrote in message
 news:a6du8i$2g5t$1 digitaldaemon.com...

 So when we come back to people coding, what is the more common


 we have? To see if two variables are referencing the same array, or to


 if two variables contain the same data?

 From my experience so far (I started programming in 1972), I believe


 it
 content comparision is intended far more frequently that pointer
 comparision.

In general, I agree. D arrays are somewhat low-level, and making them more high-level seems like a logical step for me. It would be really nice to have "=" copy the arrays, and "==" to compare them for equality. This would also solve most (if not all) of string problems. That .pointer idea is also great.

I was talking about this in the discussion "Operator overloading: A way to make everybody happy?": <a68s84$872$1 digitaldaemon.com> Basically, normally reference semantics is what you need in most cases. Java and Delphi recognized this and made all class variables references. C++ uses value semantics as the standard case, and you have to use pointers to avoid it. A lot of programmers hate it, but it offers some significant advantages when using operator overloading. My reasoning is that you use operator overloading because you are using a class to simulate some 'basic' type that does not exist, such as a string, an int256 or a date. Now when you see the following declarations: date dtA = new date (19, 12, 1976); date dtB = new date (19, 12, 1976); string sA = new String ('Hello World!'); string sB = new String ('Hello World!'); int256 iA = new int256 (12); int256 iB = new int256 (12); What would you expect the following expressions to eveluate to? if (dtA == dtB) if (sA == sB) if (iA == iB) You might be surprised to learn that with reference semantics these expressions would in fact all evaluate to false, simply because references A and B do not reference the same objects! With value semantics you would get the "correct" result of true, because the value of the variables is the same in all the cases. Basic variables such as int use value semantics, so that is what we need to make operator overloading work in a logical manner on classes. So how about a way to say "use value semantics" or "use reference semantics"? Maybe this: if (&dtA == &dtB) // Compare references if (*dtA == *dtB) // Compare values Comments, suggestions, negatives? -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Mar 11 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:a6j4im$1kgt$1 digitaldaemon.com...

 So how about a way to say "use value semantics" or "use
 reference semantics"?

 Maybe this:

 if (&dtA == &dtB)  // Compare references
 if (*dtA == *dtB)    // Compare values

 Comments, suggestions, negatives?

First of all, where's (dtA == dtB)? Then, &foo is a pointer to foo. So: char[] foo; char[]* bar = &foo; I guess that, for objects, you'd prefer reference semantics (you can always use .cmp() to check for equality). For arrays, however, value semantics seems to be preferrable.
Mar 11 2002
parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a6j5cq$1kvr$1 digitaldaemon.com...
 "OddesE" <OddesE_XYZ hotmail.com> wrote in message
 news:a6j4im$1kgt$1 digitaldaemon.com...

 So how about a way to say "use value semantics" or "use
 reference semantics"?

 Maybe this:

 if (&dtA == &dtB)  // Compare references
 if (*dtA == *dtB)    // Compare values

 Comments, suggestions, negatives?

First of all, where's (dtA == dtB)?

I guess it would be the same as &==.
 Then, &foo is a pointer to foo. So:

     char[] foo;
     char[]* bar = &foo;

 I guess that, for objects, you'd prefer reference semantics
 (you can always use .cmp() to check for equality). For arrays,
 however, value semantics seems to be preferrable.

What about dates? And int256? Operator overloading implies value semantics, at least in my mind. And, I am afraid to say that I don't like cmp(), because a lot of classes support operators != and ==, but not operators >, < and <= and >=.... Do you see the problem? If cmp() returns 1, does that mean that object b is larger than object a, or just that it is not equal to it. This is an ambiguity that I do not like. Apart from that, this basically is the same problem as plagued C for many years, where an int was used to simulate a bool. If one programmer returns -1 when two objects are unequal, while another programmer returns 1, you have the old C problem of false != false, or unequal != unequal in this case. If operator overloading is out, then please define Equal(), Larger() and Smaller() functions that return bool's.... -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Mar 11 2002
next sibling parent reply Russell Borogove <kaleja estarcion.com> writes:
OddesE wrote:
 And, I am afraid to say that I don't like cmp(), because
 a lot of classes support operators != and ==, but not
 operators >, < and <= and >=....
 Do you see the problem? If cmp() returns 1, does that
 mean that object b is larger than object a, or just that
 it is not equal to it. 

In my little world, it means that object b is to be presented after object a in an ascending sort, and nothing else. Even if it's hard to say what's "greater" or "lesser", it's often valuable to have a consistent sorting order[1]. -Russell B [1] Consider something like nethack, a game where your character has several kinds of things in inventory: food, rings, weapons, armor, potions -- it's nice to have all the food sort together, but silly to say that "food is value-larger than potions".
Mar 11 2002
parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Russell Borogove" <kaleja estarcion.com> wrote in message
news:3C8D1F5C.7010108 estarcion.com...
 OddesE wrote:
 And, I am afraid to say that I don't like cmp(), because
 a lot of classes support operators != and ==, but not
 operators >, < and <= and >=....
 Do you see the problem? If cmp() returns 1, does that
 mean that object b is larger than object a, or just that
 it is not equal to it.

In my little world, it means that object b is to be presented after object a in an ascending sort, and nothing else. Even if it's hard to say what's "greater" or "lesser", it's often valuable to have a consistent sorting order[1]. -Russell B [1] Consider something like nethack, a game where your character has several kinds of things in inventory: food, rings, weapons, armor, potions -- it's nice to have all the food sort together, but silly to say that "food is value-larger than potions".

It still doesn't adress the unequal != unequal problem. -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Mar 11 2002
parent reply Russell Borogove <kaleja estarcion.com> writes:
OddesE wrote:
 "Russell Borogove" <kaleja estarcion.com> wrote in message
 news:3C8D1F5C.7010108 estarcion.com...
 
OddesE wrote:

And, I am afraid to say that I don't like cmp(), because
a lot of classes support operators != and ==, but not
operators >, < and <= and >=....
Do you see the problem? If cmp() returns 1, does that
mean that object b is larger than object a, or just that
it is not equal to it.

presented after object a in an ascending sort, and nothing else. Even if it's hard to say what's "greater" or "lesser", it's often valuable to have a consistent sorting order[1].

It still doesn't adress the unequal != unequal problem.

Well, again, since cmp() doesn't return a bool (in fact, it needn't be restricted to -1, 0, or 1 - you can simply return (b-a) for valued types), it's hazardous to use its return value as if it were boolean. In my little world, of course, I have operator overloading, so I can make boolean != and == operators that do the right thing. -RB
Mar 12 2002
parent "OddesE" <OddesE_XYZ hotmail.com> writes:
"Russell Borogove" <kaleja estarcion.com> wrote in message
news:3C8E3F00.4070800 estarcion.com...
 OddesE wrote:
 "Russell Borogove" <kaleja estarcion.com> wrote in message
 news:3C8D1F5C.7010108 estarcion.com...

OddesE wrote:

And, I am afraid to say that I don't like cmp(), because
a lot of classes support operators != and ==, but not
operators >, < and <= and >=....
Do you see the problem? If cmp() returns 1, does that
mean that object b is larger than object a, or just that
it is not equal to it.

presented after object a in an ascending sort, and nothing else. Even if it's hard to say what's "greater" or "lesser", it's often valuable to have a consistent sorting order[1].

It still doesn't adress the unequal != unequal problem.

Well, again, since cmp() doesn't return a bool (in fact, it needn't be restricted to -1, 0, or 1 - you can simply return (b-a) for valued types), it's hazardous to use its return value as if it were boolean. In my little world, of course, I have operator overloading, so I can make boolean != and == operators that do the right thing. -RB

Indeed you are right :) But since we do not have operator overloading in D, I was trying to point out it's need by showing why cmp() is not a viable alternative for comparing two values, especially if you want to compare for unequality. (Ofcourse, you could always write: if ((cmp (a,b) != 0) && (cmp (c,d) != 0)) to compare for unequality, but it just, well..., sucks basically :) ) -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Mar 12 2002
prev sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:a6j66b$1l7n$1 digitaldaemon.com...

 What about dates? And int256?

If these are classes, == should check for equality of references. If they are structs, then it's overloadable.
 And, I am afraid to say that I don't like cmp(), because
 a lot of classes support operators != and ==, but not
 operators >, < and <= and >=....
 Do you see the problem? If cmp() returns 1, does that
 mean that object b is larger than object a, or just that
 it is not equal to it. This is an ambiguity that I do not
 like. Apart from that, this basically is the same problem
 as plagued C for many years, where an int was used to
 simulate a bool. If one programmer returns -1 when two
 objects are unequal, while another programmer returns
 1, you have the old C problem of false != false,
 or unequal != unequal in this case. If operator overloading
 is out, then please define Equal(), Larger() and Smaller()
 functions that return bool's....

Then, an equal() function could be added: class Object { bit equal(Object other) { return false; } }
Mar 12 2002
parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Pavel Minayev wrote:

 "OddesE" <OddesE_XYZ hotmail.com> wrote in message
 news:a6j66b$1l7n$1 digitaldaemon.com...

 What about dates? And int256?

If these are classes, == should check for equality of references. If they are structs, then it's overloadable.

 Then, an equal() function could be added:

     class Object
     {
         bit equal(Object other) { return false; }
     }

ICK! This is one of the worst artifacts of Java! I think that == should compare value, and you can have a function (like compareReference() or something) to compare address. Generally, it's not the reference that's important (particularly in a garbage collected language) - it's the internal value! -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Mar 12 2002
parent reply "Immanuel Scholz" <digitals-mars kutzsche.net> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> schrieb im Newsbeitrag
news:3C8E10BA.8CFEAD52 deming-os.org...
 Pavel Minayev wrote:

 "OddesE" <OddesE_XYZ hotmail.com> wrote in message
 news:a6j66b$1l7n$1 digitaldaemon.com...

 What about dates? And int256?

If these are classes, == should check for equality of references. If they are structs, then it's overloadable.

 Then, an equal() function could be added:

     class Object
     {
         bit equal(Object other) { return false; }
     }

ICK! This is one of the worst artifacts of Java! I think that == should compare value, and you can have a function (like compareReference() or something) to compare address. Generally, it's not the reference that's important (particularly in a garbage collected language) - it's the internal value!

ACK! And even more acks, since I believe that Java only compare by reference by default, because in Java you cannot write: if (&a == &b) But in D you can, so comparing by reference is just simple! Providing comparing by value the default statement is much better, IMHO. Arrays should not be simple pointers to their first element, and so char[] == char[] sould not compare pointers to the f.el. Imi
Mar 12 2002
parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Immanuel Scholz" <digitals-mars kutzsche.net> wrote in message
news:a6l6sv$ncm$1 digitaldaemon.com...
 "Russ Lewis" <spamhole-2001-07-16 deming-os.org> schrieb im Newsbeitrag
 news:3C8E10BA.8CFEAD52 deming-os.org...
 Pavel Minayev wrote:

 "OddesE" <OddesE_XYZ hotmail.com> wrote in message
 news:a6j66b$1l7n$1 digitaldaemon.com...

 What about dates? And int256?

If these are classes, == should check for equality of references. If they are structs, then it's overloadable.

 Then, an equal() function could be added:

     class Object
     {
         bit equal(Object other) { return false; }
     }

ICK! This is one of the worst artifacts of Java! I think that == should compare value, and you can have a function (like compareReference() or something) to compare address. Generally, it's not the reference that's important (particularly in a garbage collected language) - it's the internal value!

ACK! And even more acks, since I believe that Java only compare by reference by default, because in Java you cannot write: if (&a == &b) But in D you can, so comparing by reference is just simple! Providing comparing by value the default statement is much better, IMHO. Arrays should not be simple pointers to their first element, and so char[] == char[] sould not compare pointers to the f.el. Imi

I definitely agree with you that you normally compare by value by default, however, what about assign? Now assigning one reference to another *is* quitte common. More common in fact than assigning by value (I think?). So now what? Making compares act on values by default and assigns on references is just sooo inconsistent, the thought alone makes me shiver. Now here is my reasoning: 1) You always have to assign references to one and another in a typical program. 2) You often have to copy objects by value, but it is used less frequently (notice how you don't need Java's Clone() all that much compared to normal assignment with = ) 3) You often have to compare objects by value, but this is also used less frequently as assign by reference. 4) You sometimes need to compare by reference, but this is quitte rare. Comparison can be done by value as well as by reference just as with assignment but comparison by value makes more sense than comparison by reference as the default case. Now it seems to me that, even though comparison by value is the more typical situation, you can't make it the default because assignment by reference is more typical than assignment by value and you need assignment far more than you need comparison. Notice though, how this applies to all math operators. Addition, subtraction or multiplication by reference anyone? So we have a problem. The problem is that assignment is used very frequently and should be by reference. However, the other operators, though used much less frequently, should all be by value. I see two solutions for this problem: A) Introduce syntax to make the distinction between reference and value semantics. B) Introduce a new assign-by-value operator. Solution A is more flexible, but will lead to problems, because reference semantics *have* to be the default because reference assignment is used so much. Solution B might, in fact be quitte clean. Consider this: // Assume class Foo has operators := and == overloaded. Foo a, b, c; // Define a, b and c a = new Foo (12); // Set a to 12 b = a; // Copy a by ref. into b c := a; // Copy a by value into c if (a == b) // true if (a == c) // true b := 15; // assign 15 to b by value if (a == b) // a and b refer to same object, so true if (a == c) // c is another object holding 12, so false Best would be, in my opinion to combine both approaches, making a syntax to say "by reference" (probably the reference operator, &) but introducing a new assign by value operator := and making all operators work by value as the default except for the assign-by-reference operator =. This way you can implement operator overloading in a consistant and intuitive way, without creating ambiguities about wheter assignment is by value or by reference and without breaking existing code. Now I already hear you say that having two assignment operators is bad, but why? It is a very special operator anyhow, since it does not exist is math (to my knowledge) and there is a real consistency gain if it were to be used. Well, this post is already getting way too long, so I'll shut up and wait for your suggestions, comments and negatives :) -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Mar 12 2002
next sibling parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
OddesE wrote:

 I definitely agree with you that you normally compare by value
 by default, however, what about assign? Now assigning one
 reference to another *is* quitte common. More common in
 fact than assigning by value (I think?). So now what?
 Making compares act on values by default and assigns on
 references is just sooo inconsistent, the thought alone makes
 me shiver. Now here is my reasoning:

Ouch. Good point. I think, however, that we have already solved it (of sorts) with arrays: a = b; // assign by reference a[] = b; // assign by value Maybe we could use the dereferencing operator ( * ) analagously: Object a,b; a = b; // assign by reference *a = b; // assign by value Earlier, somebody (myself or somebody else, I forget who) suggested using the array syntax for comparisons; the same could work for references: int[] a,b; Object c,d; if(a == b) // compare by reference if(a[] == b) // compare by value if(c == d) // compare by reference if(*c == d) // compare by value -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Mar 12 2002
parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3C8E3ABB.52289F45 deming-os.org...
 OddesE wrote:

 I definitely agree with you that you normally compare by value
 by default, however, what about assign? Now assigning one
 reference to another *is* quitte common. More common in
 fact than assigning by value (I think?). So now what?
 Making compares act on values by default and assigns on
 references is just sooo inconsistent, the thought alone makes
 me shiver. Now here is my reasoning:

Ouch. Good point. I think, however, that we have already solved it (of sorts) with arrays: a = b; // assign by reference a[] = b; // assign by value Maybe we could use the dereferencing operator ( * ) analagously: Object a,b; a = b; // assign by reference *a = b; // assign by value Earlier, somebody (myself or somebody else, I forget who) suggested using

 array syntax for comparisons; the same could work for references:

     int[] a,b;
     Object c,d;
     if(a == b)    // compare by reference
     if(a[] == b)    // compare by value
     if(c == d)    // compare by reference
     if(*c == d)    // compare by value

 --
 The Villagers are Online! villagersonline.com

 .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
 .[ (a version.of(English).(precise.more)) is(possible) ]
 ?[ you want.to(help(develop(it))) ]

Ok, but at least make it symmetric! if(*c == *d) // compare by value, notice the second * Otherwise it makes no sense, I want the value of both arguments. But now we have a situation where we need to dereference almost allways using any operator but assignment... Introducing a second assignment operator is dubious to say the least but it offers some huge advantages with operator overloading, because now you can safely treat all operators (except the special assign-by-reference operator =) as having value semantics, which matches the way they are normally used in math and on basic types in D. Now two assignment ops is a lot, but assignment is a very special case, in math but also in D, because in math it doesn't exist :) and in D it assigns references, which is probably unexpected behaviour for non programmers, and even for some C/C++ programmers. Java and Delphi programmers will feel right at home though... :) -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Mar 12 2002
parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
OddesE wrote:

 Ok, but at least make it symmetric!

 if(*c == *d)    // compare by value, notice the second *

 Otherwise it makes no sense, I want the value of both arguments.

Agreed, although Walter currently uses the "mark only one" idea for array setting. IMHO, array setting should require both sides to include the [], but I suppose I could live without it.
 But now we have a situation where we need to dereference
 almost allways using any operator but assignment...
 Introducing a second assignment operator is dubious to
 say the least but it offers some huge advantages with operator
 overloading, because now you can safely treat all operators
 (except the special assign-by-reference operator =) as having
 value semantics, which matches the way they are normally used
 in math and on basic types in D.

I might go with this if you reverse the operators. If we are going to say that the default paradigm is by value, then the existing operator = should be the same. The new operator := should have the unusual syntax (assign by reference).
 Now two assignment ops is a lot, but assignment is a very
 special case, in math but also in D, because in math it
 doesn't exist  :)  and in D it assigns references, which is
 probably unexpected behaviour for non programmers,
 and even for some C/C++ programmers. Java and Delphi
 programmers will feel right at home though... :)

-- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Mar 12 2002
parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3C8E609D.E569A7E6 deming-os.org...
 OddesE wrote:

 Ok, but at least make it symmetric!

 if(*c == *d)    // compare by value, notice the second *

 Otherwise it makes no sense, I want the value of both arguments.

Agreed, although Walter currently uses the "mark only one" idea for array setting. IMHO, array setting should require both sides to include the [],

 I suppose I could live without it.

I agree that both sides should require []. However, an object matches an array less closely than a reference matches a pointer, so whatever the syntax for array slicing is, to me doesn't really matter. I think we should go for pointer semantics here, which means I want to dereference both of them.
 But now we have a situation where we need to dereference
 almost allways using any operator but assignment...
 Introducing a second assignment operator is dubious to
 say the least but it offers some huge advantages with operator
 overloading, because now you can safely treat all operators
 (except the special assign-by-reference operator =) as having
 value semantics, which matches the way they are normally used
 in math and on basic types in D.

I might go with this if you reverse the operators. If we are going to say

 the default paradigm is by value, then the existing operator = should be

 same.  The new operator := should have the unusual syntax (assign by
 reference).

To me it doesn't really matter. Object Pascal uses := to assign references, Java uses =. Neither of the two is really unusual, they are just different. From a practical standpoint it would probably be better to choose = as assign-by-reference for two reasons: 1) It is wat D uses now, so no existing code will be broken 2) Since D is a successor to C++ it's syntax should match C++'s (and Java's) closely whenever possible. Just my two eurocents :)
 Now two assignment ops is a lot, but assignment is a very
 special case, in math but also in D, because in math it
 doesn't exist  :)  and in D it assigns references, which is
 probably unexpected behaviour for non programmers,
 and even for some C/C++ programmers. Java and Delphi
 programmers will feel right at home though... :)

-- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]

-- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net ________________________________________________________ Please remove _XYZ from my address when replying by mail
Mar 12 2002
parent Barry Pederson <barryp yahoo.com> writes:
OddesE wrote:
 "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
 news:3C8E609D.E569A7E6 deming-os.org...
 
OddesE wrote:
Agreed, although Walter currently uses the "mark only one" idea for array
setting.  IMHO, array setting should require both sides to include the [],

but
I suppose I could live without it.


The problem with including [] on both sides of a comparison is: what if one side is a string constant? would you say: if (a[] == "hello"[]) ... ? doubtful that would fly. You're gonna want to say: if (a[] == "hello") ... , where the right side is just a plain array (and I'd guess that reason is also why Walter has the "mark only one" idea for array setting?) Barry
Mar 13 2002
prev sibling parent reply "Roberto Mariottini" <rmariottini lycosmail.com> writes:
"OddesE" <OddesE_XYZ hotmail.com> ha scritto nel messaggio
news:a6lcrf$q0q$1 digitaldaemon.com...
 "Immanuel Scholz" <digitals-mars kutzsche.net> wrote in message
 news:a6l6sv$ncm$1 digitaldaemon.com...

I see two solutions for this problem: A) Introduce syntax to make the distinction between reference and value semantics. B) Introduce a new assign-by-value operator. Solution A is more flexible, but will lead to problems, because reference semantics *have* to be the default because reference assignment is used so much.

We can use : as an operator prefix meaning "by value". For example: a = b // by reference a := b // by value if (a == b) // by reference if (a :== b) // by value c := a :+ b; // add by value ... Ciao
Mar 13 2002
parent Brock <alvin_x hotmail.com> writes:
Hmm, I think reference assignment is used so much NOW because of
things like the inability to return more than one variable from
a function, etc. Things which D fixes with "inout" and "out" in
function declarations. I agree that two different symbols are
needed to differentiate between assign by value vs. assign by
reference, and compare by value vs. compare by reference.
Primitive values use the = operator to represent assign by value,
it just seems "natural" to do things that way. Maybe we could just
throw in a & in current operations to indicate that the operator
is meant for dealing with the addresses of the objects.

i.e:

   a = b // by value (as it is for primitive types)
   a &= b // by reference (kinda like a = &b if a is a pointer, b isn't)
   if(a == b) // by value
   if(a &== b) // by reference

The statement "c := a :+ b" scares the hell out of me! I am by no means
an experienced programmer, and perhaps that shows by my avoidance of
having to deal with all those pointers, but nonetheless, I think
the ability to pass objects by reference to functions with no need for
an intermediate pointer will make the need for assigning by reference
obsolete. I realize this is a bold statement, but its just my humble
opinion. Its also a big departure from C/C++/Java style, but if the
purpose of D is to help fix the problems with C/C++/Java in the first
place, maybe a solution like this is needed.

My two cents...


Solution A is more flexible, but will lead to problems, because
reference semantics *have* to be the default because reference
assignment is used so much.

We can use : as an operator prefix meaning "by value". For example: a = b // by reference a := b // by value if (a == b) // by reference if (a :== b) // by value c := a :+ b; // add by value ... Ciao

Mar 22 2002