www.digitalmars.com         C & C++   DMDScript  

D - On "if (x)" and initialization...

reply "Luna Kid" <lunakid neuropolis.org> writes:
 Wouldn't you normally write ?:
 if (obj) {}
 if (!obj) {}
better than C and C++ (and, I think, D). The expressions in conditionals should be explicitly boolean. Hence int i = 1; X x = new X(); if(i) { if(!x) { Neither of those are sensible syntax. They are pandering to the ludicrous proposition that the extra typing to get to ...
Well, apart from it *being* sensible syntax (e.g. when x is boolean), I'd like to stress another point. Terseness is a very valid and important goal - it is one of the most important properties of an all-around language. Some of it should, naturally, be traded off for other valid goals, like readability (see PERL for a bad-balance example, or Eiffel, on the "too verbose" end to some). Since if (x is initialized) do something with x else do error handling is among the most common coding idioms, one cannot ignore the relief the short if (x) form gives to one's fingers. It's not at all just an unfortunate accident that the syntax allows it in so many practical languages - instead, the opposite is true: the support is well worse the risks. However, it is also true, that there could be much better ways to support that idiom, than tweaked "if" statements... Using e.g. exception handling (in languages where it's convenient to use) the above can be rewritten to something like: try something with x else if (x is not initialized) // "catch" do error handling Exceptions, however, are practical only for heavier cases, where e.g. errors can arise at multiple points etc. Exceptions are *not* optimal (both in terms of readability and efficiency) for the simplest and (therefore?) most frequent cases, where a single "if" would also do perfectly. So - for the very frequent simple cases exceptions give you nothing but unnecessary overhead - legacy code will be never rewritten from "if (x is initialized)" to "catch (x is not initialized)" in order to use exception handling just because it's available and is considered "modern style" DbC invariant would also be much better, but they are just impossible, or non-trivial, or too much work to add for simple, built-in types. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ About initializations.... In short: practice sadly blurs the two completely different concepts, but "being zero" is NOT THE SAME THING as "being uninitialized". (But I guess most of you are well aware of this classic problem of automatic zero-init.) Even, "being uninitialized because of a bug" or "not got a valid value by run-time input" are two subtly different things. Now, unfortunately, as the "ideal language" is still yet to be defined, there is no standard, clear and explicit notation for if (initialized x) do something with x else do error handling programmers, when handling the above-mentioned different cases, fall back "randomly" to various techniques available in the language they usewith whatever available (some form of an "if" caluse, exception handling, assertions or other invariant checking (DbC stuff) etc.). Some languages - implicitly - support this fallback (e.g. with imlicit conversion to bool and supporting the short if(x) form), some others pretend as if the need to express briefly that "if x is OK" never existed in the real world, forcing the fallback more painful than necessary (e.g. by saying "use exceptions" or "compare x to some value" or "define an is_initialized() boolean function"). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ So, to sum it up... The "Right Thing" for coding the simple and very frequent case of "checking the usability of an object before use" would be *explicitly* supported by a good language, in some dedicated way. The "ideal language" would acknowledge that objects tend to be in "usable" and "unusable" states. It would go further than silently encouraging programmers writing "if (x)"... Thanks, Luna Kid
Mar 29 2003
next sibling parent "Luna Kid" <lunakid neuropolis.org> writes:
 int    i = 1;
 X    x = new X();

 if(i)
 {

 if(!x)
 {

 Neither of those are sensible syntax. They are pandering to the
ludicrous
 proposition that the extra typing to get to ...
Well, apart from it *being* sensible syntax (e.g. when x is boolean), I'd like to stress another point.
I mean: ...x is boolean, or if there is a sensible default conversion to boolean. (I would not dare to deny the usefulness of default type coercion in a practical imperative programming language...) Luna Kid
Mar 29 2003
prev sibling next sibling parent reply "Matthew Wilson" <dmd synesis.com.au> writes:
Since the vast bulk of my experience is C & C++, I am coming from that
perspective (where implicit conversions are both easy and nasty). My
experience (and I have a lot of it in terms of clearing up other people's
messes) informs me that both these languages should follow Java's lead in
the boolean-ness of conditional expressions. I do this myself as a matter of
habit, and it does not impede the speed of my development; I still write
code _very_ quickly, but more safely and, as I emphasised before, much more
*maintainably*. That's the important part of it.

To the degree we are discussing it, terseness is an irrelevance. What
matters is correctness, clarity  and maintainability. People with a lot more
weight and "name" in the industry than little old me have documented war
stories up to their armpit. I mean no discourtesy to you (or anyone else who
espouses your point of view), but I find that programmers who do, or have
done, a lot of maintenance and/or trouble-shooting & remediation are
unaninmous in their willingness to sacrifice terseness (not to mention the
odd right arm) for correctness, clarity and maintainability.

I am a little surprised that a language that seeks to make it hard to do the
hard mistakes of other languages, and makes it impossible to do the simple
mistakes, passes the book on this point. I'm not advocating a nannying
language, such as Java - printf() is well worth the risk - but boolean
conditionals seems to be such a good reward for such a little sacrifice.

However, we are debating needlessly. I know full well that I've got more
chance of persuading Microsoft to write a standards-compliant Java compiler
than I have in persuading the vast bulk of developers to accept extra typing
when they deem it's not needed.

To satisfy everyone, perhaps all we need is an optional compiler warning -
in the
vein of DMC++s -wc - that tells us about it. (And the ability to promote it
to an error, of course). Walter, I imagine this would be pretty easy to do?

"Luna Kid" <lunakid neuropolis.org> wrote in message
news:b64rc4$4m3$1 digitaldaemon.com...
 Wouldn't you normally write ?:
 if (obj) {}
 if (!obj) {}
far
 better than C and C++ (and, I think, D). The expressions in conditionals
 should be explicitly boolean. Hence

 int    i = 1;
 X    x = new X();

 if(i)
 {

 if(!x)
 {

 Neither of those are sensible syntax. They are pandering to the
ludicrous
 proposition that the extra typing to get to ...
Well, apart from it *being* sensible syntax (e.g. when x is boolean), I'd like to stress another point. Terseness is a very valid and important goal - it is one of the most important properties of an all-around language. Some of it should, naturally, be traded off for other valid goals, like readability (see PERL for a bad-balance example, or Eiffel, on the "too verbose" end to some). Since if (x is initialized) do something with x else do error handling is among the most common coding idioms, one cannot ignore the relief the short if (x) form gives to one's fingers. It's not at all just an unfortunate accident that the syntax allows it in so many practical languages - instead, the opposite is true: the support is well worse the risks. However, it is also true, that there could be much better ways to support that idiom, than tweaked "if" statements... Using e.g. exception handling (in languages where it's convenient to use) the above can be rewritten to something like: try something with x else if (x is not initialized) // "catch" do error handling Exceptions, however, are practical only for heavier cases, where e.g. errors can arise at multiple points etc. Exceptions are *not* optimal (both in terms of readability and efficiency) for the simplest and (therefore?) most frequent cases, where a single "if" would also do perfectly. So - for the very frequent simple cases exceptions give you nothing but unnecessary overhead - legacy code will be never rewritten from "if (x is initialized)" to "catch (x is not initialized)" in order to use exception handling just because it's available and is considered "modern style" DbC invariant would also be much better, but they are just impossible, or non-trivial, or too much work to add for simple, built-in types. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ About initializations.... In short: practice sadly blurs the two completely different concepts, but "being zero" is NOT THE SAME THING as "being uninitialized". (But I guess most of you are well aware of this classic problem of automatic zero-init.) Even, "being uninitialized because of a bug" or "not got a valid value by run-time input" are two subtly different things. Now, unfortunately, as the "ideal language" is still yet to be defined, there is no standard, clear and explicit notation for if (initialized x) do something with x else do error handling programmers, when handling the above-mentioned different cases, fall back "randomly" to various techniques available in the language they usewith whatever available (some form of an "if" caluse, exception handling, assertions or other invariant checking (DbC stuff) etc.). Some languages - implicitly - support this fallback (e.g. with imlicit conversion to bool and supporting the short if(x) form), some others pretend as if the need to express briefly that "if x is OK" never existed in the real world, forcing the fallback more painful than necessary (e.g. by saying "use exceptions" or "compare x to some value" or "define an is_initialized() boolean function"). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ So, to sum it up... The "Right Thing" for coding the simple and very frequent case of "checking the usability of an object before use" would be *explicitly* supported by a good language, in some dedicated way. The "ideal language" would acknowledge that objects tend to be in "usable" and "unusable" states. It would go further than silently encouraging programmers writing "if (x)"... Thanks, Luna Kid
Mar 29 2003
next sibling parent reply "Luna Kid" <lunakid neuropolis.org> writes:
Well, to avoid guessing whether I'm yet another daily
coder who fetishizes expressions shorter by a few chars,
just because they are shorter by a few chars -- I just
assure you: I'm not from that camp. :)

 To the degree we are discussing it, terseness is an irrelevance. What
 matters is correctness, clarity  and maintainability. People with a
Let's not diverge from our specific subject to generailties we all agree on. :) (One comment, still: I've learned (you bet: from maintenance work), that terseness is not necessarily evil. Actually, verbosity tends to also very often introduce or increase diversity, which definitely *is* bad. Terse code -- not in the cryptic PERL way --, can actually help understanding it. (You can see e.g. windowsx.h vs. MFC (I mention those because you are familiar with them), both doing good and bad in this matter.) So, it is never black and white. The problem is, that good balance between verbosity and readability (and maintainability) is utterly subjective. (And, as you also also know, "the perfect language" is just another Holy Grail.) Back to the point... What I intended to state in my messy post, was that if people write things like if (f) or even f && write(... or even (truly horrible) things like if (f = fopen... they do it not because they are stupid and never heared about maintenance etc. They don't probably enjoy shooting themselves in the foot, either. (Some surely do, but let's not focus our discussion on how dumb people do things). What they do, is simply using idioms. Quite common and practical idioms, I have to add (for the first two). But, what I also implied -- and that's actually the whole point of my message -- that it is a poor, suboptimal, risky and hacky way of doing that! So, welcome to your own club, Matt! :) What I would like to see in a "dream language", is using if (...) for checking normal boolean stuff (as defined e.g. in C++), *and* some facilities to express the idioms you see all around, but in some *clean* manner. In a cleaner way, than they are expressed now, being those crippled if(x) statements. But that is difficult. It leads over to the muddy land of initializations and leads directly into the middle of religious battles over default values, zero values, empty states, invariants and their checking etc. etc. Libraries can be filled with papers written on this topic, too. All I say is, that because this is a subtle and complex matter, ignoring the whole phenomenon, or regarding it as just stubborn and incomprehensibly stupid reluctance for typing those extra chars, is, well, probably not the most correct and/or constructive approach, in my opinion.
 To satisfy everyone, all we need is an optional compiler warning - in the
 vein of DMC++s -wc - that tells us about it. (And the ability to promote
it No. That's symptomatic treatment, leaving you sick but not complain as much (the compiler doing it for you...). What *really* is needed is proper built-in semantics and syntax for letting you express what you mean by if (f) ... so people won't write this difficult-to-digest construct, but write something cleaner. Now, don't ask me what that should be... Something that is convenient, and maps directly to the semantics of the above idiom: if (f is OK) What this "OK" is -- man, this war between the USA and Iraq is just a friendly chat compared to what a debate on this matter could be... Cheers, Luna Kid ----- Original Message ----- From: "Matthew Wilson" <matthew synesis.com.au> To: "Luna Kid" <lunakid neuropolis.org> Sent: 2003. március 29. 23:48 Subject: Re: On "if (x)" and initialization...
 Since the vast bulk of my experience is C & C++, I am coming from that
 perspective (where implicit conversions are both easy and nasty). My
 experience (and I have a lot of it in terms of clearing up other people's
 messes) informs me that both these languages should follow Java's lead in
 the boolean-ness of conditional expressions. I do this myself as a matter
of
 habit, and it does not impede the speed of my development; I still write
 code _very_ quickly, but more safely and, as I emphasised before, much
more
 *maintainably*. That's the important part of it.

 To the degree we are discussing it, terseness is an irrelevance. What
 matters is correctness, clarity  and maintainability. People with a lot
more
 weight and "name" in the industry than little old me have documented war
 stories up to their armpit. I mean no discourtesy to you (or anyone else
who
 espouses your point of view), but I find that programmers who do, or have
 done, a lot of maintenance and/or trouble-shooting & remediation are
 unaninmous in their willingness to sacrifice terseness (not to mention the
 odd right arm) for correctness, clarity and maintainability.

 I am a little surprised that a language that seeks to make it hard to do
the
 hard mistakes of other languages, and makes it impossible to do the simple
 mistakes, passes the book on this point. I'm not advocating a nannying
 language, such as Java - printf() is well worth the risk - but boolean
 conditionals seems to be such a good reward for such a little sacrifice.

 However, we are debating needlessly. I know full well that I've got more
 chance of persuading Microsoft to write a standards-compliant Java
compiler
 than I have in persuading the vast bulk of developers to accept extra
typing
 when they deem it's not needed.

 To satisfy everyone, all we need is an optional compiler warning - in the
 vein of DMC++s -wc - that tells us about it. (And the ability to promote
it
 to an error, of course). Walter, I imagine this would be pretty easy to
do?
 ----- Original Message -----
 From: "Luna Kid" <lunakid neuropolis.org>
 Newsgroups: D
 Sent: Sunday, March 30, 2003 5:18 AM
 Subject: On "if (x)" and initialization...


 Wouldn't you normally write ?:
 if (obj) {}
 if (!obj) {}
far
 better than C and C++ (and, I think, D). The expressions in
conditionals
 should be explicitly boolean. Hence

 int    i = 1;
 X    x = new X();

 if(i)
 {

 if(!x)
 {

 Neither of those are sensible syntax. They are pandering to the
ludicrous
 proposition that the extra typing to get to ...
Well, apart from it *being* sensible syntax (e.g. when x is boolean), I'd like to stress another point. Terseness is a very valid and important goal - it is one of the most important properties of an all-around language. Some of it should, naturally, be traded off for other valid goals, like readability (see PERL for a bad-balance example, or Eiffel, on the "too verbose" end to some). Since if (x is initialized) do something with x else do error handling is among the most common coding idioms, one cannot ignore the relief the short if (x) form gives to one's fingers. It's not at all just an unfortunate accident that the syntax allows it in so many practical languages - instead, the opposite is true: the support is well worse the risks. However, it is also true, that there could be much better ways to support that idiom, than tweaked "if" statements... Using e.g. exception handling (in languages where it's convenient to use) the above can be rewritten to something like: try something with x else if (x is not initialized) // "catch" do error handling Exceptions, however, are practical only for heavier cases, where e.g. errors can arise at multiple points etc. Exceptions are *not* optimal (both in terms of readability and efficiency) for the simplest and (therefore?) most frequent cases, where a single "if" would also do perfectly. So - for the very frequent simple cases exceptions give you nothing but unnecessary overhead - legacy code will be never rewritten from "if (x is initialized)" to "catch (x is not initialized)" in order to use exception handling just because it's available and is considered "modern style" DbC invariant would also be much better, but they are just impossible, or non-trivial, or too much work to add for simple, built-in types. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ About initializations.... In short: practice sadly blurs the two completely different concepts, but "being zero" is NOT THE SAME THING as "being uninitialized". (But I guess most of you are well aware of this classic problem of automatic zero-init.) Even, "being uninitialized because of a bug" or "not got a valid value by run-time input" are two subtly different things. Now, unfortunately, as the "ideal language" is still yet to be defined, there is no standard, clear and explicit notation for if (initialized x) do something with x else do error handling programmers, when handling the above-mentioned different cases, fall back "randomly" to various techniques available in the language they usewith whatever available (some form of an "if" caluse, exception handling, assertions or other invariant checking (DbC stuff) etc.). Some languages - implicitly - support this fallback (e.g. with imlicit conversion to bool and supporting the short if(x) form), some others pretend as if the need to express briefly that "if x is OK" never existed in the real world, forcing the fallback more painful than necessary (e.g. by saying "use exceptions" or "compare x to some value" or "define an is_initialized() boolean function"). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ So, to sum it up... The "Right Thing" for coding the simple and very frequent case of "checking the usability of an object before use" would be *explicitly* supported by a good language, in some dedicated way. The "ideal language" would acknowledge that objects tend to be in "usable" and "unusable" states. It would go further than silently encouraging programmers writing "if (x)"... Thanks, Luna Kid
Mar 29 2003
next sibling parent reply "Matthew Wilson" <dmd synesis.com.au> writes:
Clarifications:

1. I absolutely agree that too much verbosity is also bad, and concede that
not acknowledging that is a failing in my posts so far. Indeed, I find
review & remediation of Java more of a challenge than C++ in this regard,
although it's perhaps offset by the fact that the number of stuff-ups
available in Java is (at least a bit) smaller.

2. I would like to stipulate that I wasn't calling any person stupid, or
seeking to imply that anyone is. I often comment that certain things are
stupid, but _never_ personalise things, especially on a Digital Mars group.
;) That's just plain bad manners.

3. The idioms are only such because the language allows bad practise. I
cannot believe that any experienced practitioner (of C++, at least) has not
come across a conditional expression that they have not readily comprehend
due to terseness of form, and further assert that I cannot accept that the
same experienced practitioners have not been bitten by the meaning of
implicit conversion operators.

What does

 string  line;

 while(s >> line)

mean, when s is an iostream input stream instance? I don't know! Every time
I see such thing I have to run to see whether operator void *() means
good(), or not bad(), or not eof(), or not eof() AND not bad(), or blah blah
blah all the way back to the drawing board. Heaven's above, if having
operator void *() used to denote a boolean state doesn't get people's alarm
bells ringing, I'm going to take up ornate pastry making, and leave this
game to those who clearly grok a picture my feeble brain can never hope to
comprehend!

Anyway, I'm going to shut up, as I've been doing far too much pontificating
over the last couple of days, and nowhere near enough work. ("Hear, hear"
you all cry. ;)

I'm primarily a coper, rather than an idealist, so if Walter'll give me the
compiler switch to warn of non-boolean conditional expressions, I'll promise
never to darken the door of this subject again. Over to you, big W ...


"Luna Kid" <lunakid neuropolis.org> wrote in message
news:b65rpn$qh9$1 digitaldaemon.com...
 Well, to avoid guessing whether I'm yet another daily
 coder who fetishizes expressions shorter by a few chars,
 just because they are shorter by a few chars -- I just
 assure you: I'm not from that camp. :)

 To the degree we are discussing it, terseness is an irrelevance. What
 matters is correctness, clarity  and maintainability. People with a
Let's not diverge from our specific subject to generailties we all agree on. :) (One comment, still: I've learned (you bet: from maintenance work), that terseness is not necessarily evil. Actually, verbosity tends to also very often introduce or increase diversity, which definitely *is* bad. Terse code -- not in the cryptic PERL way --, can actually help understanding it. (You can see e.g. windowsx.h vs. MFC (I mention those because you are familiar with them), both doing good and bad in this matter.) So, it is never black and white. The problem is, that good balance between verbosity and readability (and maintainability) is utterly subjective. (And, as you also also know, "the perfect language" is just another Holy Grail.) Back to the point... What I intended to state in my messy post, was that if people write things like if (f) or even f && write(... or even (truly horrible) things like if (f = fopen... they do it not because they are stupid and never heared about maintenance etc. They don't probably enjoy shooting themselves in the foot, either. (Some surely do, but let's not focus our discussion on how dumb people do things). What they do, is simply using idioms. Quite common and practical idioms, I have to add (for the first two). But, what I also implied -- and that's actually the whole point of my message -- that it is a poor, suboptimal, risky and hacky way of doing that! So, welcome to your own club, Matt! :) What I would like to see in a "dream language", is using if (...) for checking normal boolean stuff (as defined e.g. in C++), *and* some facilities to express the idioms you see all around, but in some *clean* manner. In a cleaner way, than they are expressed now, being those crippled if(x) statements. But that is difficult. It leads over to the muddy land of initializations and leads directly into the middle of religious battles over default values, zero values, empty states, invariants and their checking etc. etc. Libraries can be filled with papers written on this topic, too. All I say is, that because this is a subtle and complex matter, ignoring the whole phenomenon, or regarding it as just stubborn and incomprehensibly stupid reluctance for typing those extra chars, is, well, probably not the most correct and/or constructive approach, in my opinion.
 To satisfy everyone, all we need is an optional compiler warning - in
the
 vein of DMC++s -wc - that tells us about it. (And the ability to promote
it No. That's symptomatic treatment, leaving you sick but not complain as much (the compiler doing it for you...). What *really* is needed is proper built-in semantics and syntax for letting you express what you mean by if (f) ... so people won't write this difficult-to-digest construct, but write something cleaner. Now, don't ask me what that should be... Something that is convenient, and maps directly to the semantics of the above idiom: if (f is OK) What this "OK" is -- man, this war between the USA and Iraq is just a friendly chat compared to what a debate on this matter could be... Cheers, Luna Kid ----- Original Message ----- From: "Matthew Wilson" <matthew synesis.com.au> To: "Luna Kid" <lunakid neuropolis.org> Sent: 2003. március 29. 23:48 Subject: Re: On "if (x)" and initialization...
 Since the vast bulk of my experience is C & C++, I am coming from that
 perspective (where implicit conversions are both easy and nasty). My
 experience (and I have a lot of it in terms of clearing up other
people's
 messes) informs me that both these languages should follow Java's lead
in
 the boolean-ness of conditional expressions. I do this myself as a
matter
 of
 habit, and it does not impede the speed of my development; I still write
 code _very_ quickly, but more safely and, as I emphasised before, much
more
 *maintainably*. That's the important part of it.

 To the degree we are discussing it, terseness is an irrelevance. What
 matters is correctness, clarity  and maintainability. People with a lot
more
 weight and "name" in the industry than little old me have documented war
 stories up to their armpit. I mean no discourtesy to you (or anyone else
who
 espouses your point of view), but I find that programmers who do, or
have
 done, a lot of maintenance and/or trouble-shooting & remediation are
 unaninmous in their willingness to sacrifice terseness (not to mention
the
 odd right arm) for correctness, clarity and maintainability.

 I am a little surprised that a language that seeks to make it hard to do
the
 hard mistakes of other languages, and makes it impossible to do the
simple
 mistakes, passes the book on this point. I'm not advocating a nannying
 language, such as Java - printf() is well worth the risk - but boolean
 conditionals seems to be such a good reward for such a little sacrifice.

 However, we are debating needlessly. I know full well that I've got more
 chance of persuading Microsoft to write a standards-compliant Java
compiler
 than I have in persuading the vast bulk of developers to accept extra
typing
 when they deem it's not needed.

 To satisfy everyone, all we need is an optional compiler warning - in
the
 vein of DMC++s -wc - that tells us about it. (And the ability to promote
it
 to an error, of course). Walter, I imagine this would be pretty easy to
do?
 ----- Original Message -----
 From: "Luna Kid" <lunakid neuropolis.org>
 Newsgroups: D
 Sent: Sunday, March 30, 2003 5:18 AM
 Subject: On "if (x)" and initialization...


 Wouldn't you normally write ?:
 if (obj) {}
 if (!obj) {}
is
 far
 better than C and C++ (and, I think, D). The expressions in
conditionals
 should be explicitly boolean. Hence

 int    i = 1;
 X    x = new X();

 if(i)
 {

 if(!x)
 {

 Neither of those are sensible syntax. They are pandering to the
ludicrous
 proposition that the extra typing to get to ...
Well, apart from it *being* sensible syntax (e.g. when x is boolean), I'd like to stress another point. Terseness is a very valid and important goal - it is one of the most important properties of an all-around language. Some of it should, naturally, be traded off for other valid goals, like readability (see PERL for a bad-balance example, or Eiffel, on the "too verbose" end to some). Since if (x is initialized) do something with x else do error handling is among the most common coding idioms, one cannot ignore the relief the short if (x) form gives to one's fingers. It's not at all just an unfortunate accident that the syntax allows it in so many practical languages - instead, the opposite is true: the support is well worse the risks. However, it is also true, that there could be much better ways to support that idiom, than tweaked "if" statements... Using e.g. exception handling (in languages where it's convenient to use) the above can be rewritten to something like: try something with x else if (x is not initialized) // "catch" do error handling Exceptions, however, are practical only for heavier cases, where e.g. errors can arise at multiple points etc. Exceptions are *not* optimal (both in terms of readability and efficiency) for the simplest and (therefore?) most frequent cases, where a single "if" would also do perfectly. So - for the very frequent simple cases exceptions give you nothing but unnecessary overhead - legacy code will be never rewritten from "if (x is initialized)" to "catch (x is not initialized)" in order to use exception handling just because it's available and is considered "modern style" DbC invariant would also be much better, but they are just impossible, or non-trivial, or too much work to add for simple, built-in types. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ About initializations.... In short: practice sadly blurs the two completely different concepts, but "being zero" is NOT THE SAME THING as "being uninitialized". (But I guess most of you are well aware of this classic problem of automatic zero-init.) Even, "being uninitialized because of a bug" or "not got a valid value by run-time input" are two subtly different things. Now, unfortunately, as the "ideal language" is still yet to be defined, there is no standard, clear and explicit notation for if (initialized x) do something with x else do error handling programmers, when handling the above-mentioned different cases, fall back "randomly" to various techniques available in the language they usewith whatever available (some form of an "if" caluse, exception handling, assertions or other invariant checking (DbC stuff) etc.). Some languages - implicitly - support this fallback (e.g. with imlicit conversion to bool and supporting the short if(x) form), some others pretend as if the need to express briefly that "if x is OK" never existed in the real world, forcing the fallback more painful than necessary (e.g. by saying "use exceptions" or "compare x to some value" or "define an is_initialized() boolean function"). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ So, to sum it up... The "Right Thing" for coding the simple and very frequent case of "checking the usability of an object before use" would be *explicitly* supported by a good language, in some dedicated way. The "ideal language" would acknowledge that objects tend to be in "usable" and "unusable" states. It would go further than silently encouraging programmers writing "if (x)"... Thanks, Luna Kid
Mar 29 2003
next sibling parent reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
"Matthew Wilson" <dmd synesis.com.au> wrote in message
news:b65slq$r40$1 digitaldaemon.com...

 2. I would like to stipulate that I wasn't calling any person stupid, or
 seeking to imply that anyone is. I often comment that certain things are
 stupid, but _never_ personalise things, especially on a Digital Mars
group.
 ;) That's just plain bad manners.
guilty as charged. Sorry, I'm very emotional about this but not nearly as eloquent as you.
 mean, when s is an iostream input stream instance? I don't know! Every
time
 I see such thing I have to run to see whether operator void *() means
 good(), or not bad(), or not eof(), or not eof() AND not bad(), or blah
blah
 blah all the way back to the drawing board. Heaven's above, if having
 operator void *() used to denote a boolean state doesn't get people's
alarm
 bells ringing, I'm going to take up ornate pastry making, and leave this
 game to those who clearly grok a picture my feeble brain can never hope to
 comprehend!
They so should have chosen to just overload operator bool() instead. I don't get why they chose to overload operator void*()... that's just silliness! Maybe it was to prevent the kind of use such as if (stream == true) {}
 I'm primarily a coper, rather than an idealist, so if Walter'll give me
the
 compiler switch to warn of non-boolean conditional expressions, I'll
promise
 never to darken the door of this subject again. Over to you, big W ...
Walter will probably never add a warning switch to D... he has always been against them to my knowledge. Sean
Mar 30 2003
parent "Matthew Wilson" <dmd synesis.com.au> writes:
"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
news:b67hji$1sh4$1 digitaldaemon.com...
 "Matthew Wilson" <dmd synesis.com.au> wrote in message
 news:b65slq$r40$1 digitaldaemon.com...

 2. I would like to stipulate that I wasn't calling any person stupid, or
 seeking to imply that anyone is. I often comment that certain things are
 stupid, but _never_ personalise things, especially on a Digital Mars
group.
 ;) That's just plain bad manners.
guilty as charged. Sorry, I'm very emotional about this but not nearly as eloquent as you.
History. & thanks for compliment, I think. ;)
 mean, when s is an iostream input stream instance? I don't know! Every
time
 I see such thing I have to run to see whether operator void *() means
 good(), or not bad(), or not eof(), or not eof() AND not bad(), or blah
blah
 blah all the way back to the drawing board. Heaven's above, if having
 operator void *() used to denote a boolean state doesn't get people's
alarm
 bells ringing, I'm going to take up ornate pastry making, and leave this
 game to those who clearly grok a picture my feeble brain can never hope
to
 comprehend!
They so should have chosen to just overload operator bool() instead. I don't get why they chose to overload operator void*()... that's just silliness! Maybe it was to prevent the kind of use such as if (stream == true) {}
Well, I know why. It was because operator bool did not exist at that time, because bool didn't exist until C++98. However, even with operator bool() we would still have the confusion as to what it meant?
 I'm primarily a coper, rather than an idealist, so if Walter'll give me
the
 compiler switch to warn of non-boolean conditional expressions, I'll
promise
 never to darken the door of this subject again. Over to you, big W ...
Walter will probably never add a warning switch to D... he has always been against them to my knowledge.
Then I must sadly restake my assertion that we must enforce bool conditionals. (Frankly I'd prefer the warning and avoid the fight.)
 Sean
Mar 30 2003
prev sibling parent "Luna Kid" <lunakid neuropolis.org> writes:
Matt,

 What does

  string  line;

  while(s >> line)

 mean, when s is an iostream input stream instance? I don't know!
(I must say I like these 7 lines of a good example much better than "pontifications" of any length...)
 cannot believe that <...> the same experienced practitioners have
 not been bitten by the meaning of implicit conversion operators.
In the other thread ("Re: Identity & equivalence") I expressed my (quite similar) stance on this:
 ...  And "if (object)" would automatically convert the object
 to bool.

 And by the way, I'd just *love* to have other user-defined conversions
 between different types as well.

 (Maybe this is asking too much - perhaps it's better to stop before
 the language starts to approach C++ in complexity, right?)

 -Antti
Some of it *is* practical. All of it, unleashed, leads to horror you can see in C++.
What I only dream of now, is just operator bool()... Cheers, Luna Kid
Mar 30 2003
prev sibling parent reply Antti Sykari <jsykari gamma.hut.fi> writes:
"Luna Kid" <lunakid neuropolis.org> writes:

 What I would like to see in a "dream language", is using
 if (...) for checking normal boolean stuff (as defined e.g.
 in C++), *and* some facilities to express the idioms you
 see all around, but in some *clean* manner. In a cleaner
 way, than they are expressed now, being those crippled
 if(x) statements.
So you want a clean idiom which expresses "this object is ok"? Make it a rule that things that can be either ok or non-ok include a "valid()" member function. This means for starters all reference type objects. I don't mean that valid() should be an overridable member function of Object, but rather a final and inlined one, so that it wouldn't bloat the vtable and cause any run-time overhead. class Object { final bit valid() { return this != null; } } This will make the programmer's intention as clear as possible: Object f(); g() { Object o = f(); if (o.valid()) use(o); else dont_use_it(); } So, valid() is equivalent to comparison with null, except that it's semantically simpler and more straightforward: - checking for validity is, in my opinion, simpler concept than checking for non-equivalence or possibly non-identity with null - there's only one way to write it, whereas you can compare with equivalence to null in 4 ways: - if (o != null) - if (o !== null) - if (null != o) - if (null !== o) (And in production code you will most certainly see all of these...) This is idiom is also often used with other things that can be invalidated, such as iterators: f(int_iterator ii) { while (ii.valid()) print(ii.get_next()); } Naturally, iterators should be structs in that case, so that their valid() member function wouldn't be confused with Object.valid(). One of the major downsides of this kind of valid() is, indeed, that it cannot be used with classes that already have a member function valid(). It would be possible to define valid() as a function which first checks for null and then calls user-defined valid() if the class has one. This would, however, add further complication to the language. (Although in that, it would be similar to the null-checking "=="...) -Antti
Mar 30 2003
parent reply "Luna Kid" <lunakid neuropolis.org> writes:
[Comments embedded.]

----- Original Message -----
From: "Antti Sykari" <jsykari gamma.hut.fi>
Newsgroups: D
Sent: 2003. március 30. 13:30
Subject: Re: On "if (x)" and initialization...


 So, valid() is equivalent to comparison with null, except that it's
 semantically simpler and more straightforward:
...
Yes, basically that's it. It just raises a few small annoying questions to me. One, as you noted, is its name (let's assume it's easy -- well, but to find a short, nice, non-obtrusive one...). Then, is it OK to restrict the thing to classes? ("if (str)" is all too common.) Also, doing == null is too restrictive, as validity is context dependent (str.empty() may mean invalid, even if str != null), etc. But I'm really starting to think that my idea for a dedicated syntax was quite superfluous. The more I think about it, the better I like the _existing_ "if (x)" construct... At least I have no problem decoding it, and it is prefectly expressive to me, once I manage to memorize this "heretic" rule (which many other C++ "sinners" find a joy to obey to): an object is valid, if it's true in a boolean context... Er, what exactly was the problem with this?... Cheers, Luna Kid
Mar 30 2003
parent "Luna Kid" <lunakid neuropolis.org> writes:
 [Comments embedded.]
(Hehh, my mail was like 3 times longer and uglier, when I put the line up there... :) I stole that nice notation from Daniel Yokomiso, by the way.")
Mar 30 2003
prev sibling next sibling parent reply Antti Sykari <jsykari gamma.hut.fi> writes:
"Matthew Wilson" <dmd synesis.com.au> writes:

 habit, and it does not impede the speed of my development; I still write
 code _very_ quickly, but more safely and, as I emphasised before, much more
 *maintainably*. That's the important part of it.
You're quite on the right track when talking about maintainability. When you encounter the line if (hilavitkutin != null) you indeed know instantly that hilavitkutin is a reference type. And when you see if (kalapala != 0) it's perfectly clear that the variable is an integer one, not to mention things like if (!some_input_stream.eof()) So this kind of verbosity should be definitely encouraged in code that is to be read by someone. But the compiler (or IDE, or whatever) has the access to the type information, so why doesn't it transform to less readable, terse code to more readable and maintainable code automatically, as a side effect of the compilation? Why must the burden of annotating the code with redundant information be left to the programmer? Suppose that you have file test.d (and also suppose that if (o) was legal) and you compile it: test.d (before compilation): void f(Object o) { if (o) use(o); } then you compile it -- execute yourfancydcompiler test.d -- and it changes copies test.d to test.d.orig and makes a new test.d: test.d (after compilation): void f(Object o) { if (o != null) use(o); } It's the small things that make the perfect development environment, right? -Antti
Mar 30 2003
next sibling parent "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
I was going to say that I am *not* against this sort of thing, but as I was
typing it out, I realized that I would probably hate this behavior myself if
it happened.

For one thing, the compiler is changing all your nice terse code into
long-winded explicit code.  Now when you want to maintain it you have to
deal with the long version.

For another, everytime you compile your editor will have to reload the
changes.  If you were making changes while you were compiling, you could be
in big trouble.

Perhaps there could be a compiler switch that told the compiler to 'pretty
up' the source as it goes.  Maintenance coders would like it.  In fact the
compiler wouldn't have to have such a thing;  D is easy enough to parse that
it would be easy for a 3rd party guy to make such a cleanup tool.

Sean


"Antti Sykari" <jsykari gamma.hut.fi> wrote in message
news:87vfy1krgi.fsf_-_ hoastest1-8c.hoasnet.inet.fi...
 "Matthew Wilson" <dmd synesis.com.au> writes:

 habit, and it does not impede the speed of my development; I still write
 code _very_ quickly, but more safely and, as I emphasised before, much
more
 *maintainably*. That's the important part of it.
You're quite on the right track when talking about maintainability. When you encounter the line if (hilavitkutin != null) you indeed know instantly that hilavitkutin is a reference type. And when you see if (kalapala != 0) it's perfectly clear that the variable is an integer one, not to mention things like if (!some_input_stream.eof()) So this kind of verbosity should be definitely encouraged in code that is to be read by someone. But the compiler (or IDE, or whatever) has the access to the type information, so why doesn't it transform to less readable, terse code to more readable and maintainable code automatically, as a side effect of the compilation? Why must the burden of annotating the code with redundant information be left to the programmer? Suppose that you have file test.d (and also suppose that if (o) was legal) and you compile it: test.d (before compilation): void f(Object o) { if (o) use(o); } then you compile it -- execute yourfancydcompiler test.d -- and it changes copies test.d to test.d.orig and makes a new test.d: test.d (after compilation): void f(Object o) { if (o != null) use(o); } It's the small things that make the perfect development environment, right? -Antti
Mar 30 2003
prev sibling next sibling parent "Matthew Wilson" <dmd synesis.com.au> writes:
Sounds like an exciting idea, but it'd make a nightmare of make and source
code control. :(

"Antti Sykari" <jsykari gamma.hut.fi> wrote in message
news:87vfy1krgi.fsf_-_ hoastest1-8c.hoasnet.inet.fi...
 "Matthew Wilson" <dmd synesis.com.au> writes:

 habit, and it does not impede the speed of my development; I still write
 code _very_ quickly, but more safely and, as I emphasised before, much
more
 *maintainably*. That's the important part of it.
You're quite on the right track when talking about maintainability. When you encounter the line if (hilavitkutin != null) you indeed know instantly that hilavitkutin is a reference type. And when you see if (kalapala != 0) it's perfectly clear that the variable is an integer one, not to mention things like if (!some_input_stream.eof()) So this kind of verbosity should be definitely encouraged in code that is to be read by someone. But the compiler (or IDE, or whatever) has the access to the type information, so why doesn't it transform to less readable, terse code to more readable and maintainable code automatically, as a side effect of the compilation? Why must the burden of annotating the code with redundant information be left to the programmer? Suppose that you have file test.d (and also suppose that if (o) was legal) and you compile it: test.d (before compilation): void f(Object o) { if (o) use(o); } then you compile it -- execute yourfancydcompiler test.d -- and it changes copies test.d to test.d.orig and makes a new test.d: test.d (after compilation): void f(Object o) { if (o != null) use(o); } It's the small things that make the perfect development environment, right? -Antti
Mar 30 2003
prev sibling parent "Mike Wynn" <mike.wynn l8night.co.uk> writes:
 When you encounter the line

   if (hilavitkutin != null)
you've not got what you expected .... the above code will seggy if hilavitkutin is null you mean if (hilavitkutin !== null) // ! = =
Mar 31 2003
prev sibling next sibling parent reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
Perhaps what is needed is an explicit conversion to bool, or an explicit
nonzero / non-null check.

Wait, we already have it!  It's called '!!'.

Object o = someobj;
if (!!o)
{
    o.Print();
}

If you want to disallow implicit conversion to bool, at least keep the '!'
operator so we can do this trick, which is still terse, yet explicit.  I
argue that it's *not* that hard to read.  Once you've seen it once you will
know the idiom.

Unless someone has an idea for another operator that means explicit check if
non-null?

I'm not that against some other statement construct for this purpose,
either:

if_valid(o)
{
}

Or perhaps this behavior could be made part of the 'with' statement:

with(o)  // skips the whole block if o is null
{
}

Sean



"Matthew Wilson" <dmd synesis.com.au> wrote in message
news:b65qho$pqk$1 digitaldaemon.com...
 Since the vast bulk of my experience is C & C++, I am coming from that
 perspective (where implicit conversions are both easy and nasty). My
 experience (and I have a lot of it in terms of clearing up other people's
 messes) informs me that both these languages should follow Java's lead in
 the boolean-ness of conditional expressions. I do this myself as a matter
of
 habit, and it does not impede the speed of my development; I still write
 code _very_ quickly, but more safely and, as I emphasised before, much
more
 *maintainably*. That's the important part of it.

 To the degree we are discussing it, terseness is an irrelevance. What
 matters is correctness, clarity  and maintainability. People with a lot
more
 weight and "name" in the industry than little old me have documented war
 stories up to their armpit. I mean no discourtesy to you (or anyone else
who
 espouses your point of view), but I find that programmers who do, or have
 done, a lot of maintenance and/or trouble-shooting & remediation are
 unaninmous in their willingness to sacrifice terseness (not to mention the
 odd right arm) for correctness, clarity and maintainability.

 I am a little surprised that a language that seeks to make it hard to do
the
 hard mistakes of other languages, and makes it impossible to do the simple
 mistakes, passes the book on this point. I'm not advocating a nannying
 language, such as Java - printf() is well worth the risk - but boolean
 conditionals seems to be such a good reward for such a little sacrifice.

 However, we are debating needlessly. I know full well that I've got more
 chance of persuading Microsoft to write a standards-compliant Java
compiler
 than I have in persuading the vast bulk of developers to accept extra
typing
 when they deem it's not needed.

 To satisfy everyone, perhaps all we need is an optional compiler warning -
 in the
 vein of DMC++s -wc - that tells us about it. (And the ability to promote
it
 to an error, of course). Walter, I imagine this would be pretty easy to
do?
 "Luna Kid" <lunakid neuropolis.org> wrote in message
 news:b64rc4$4m3$1 digitaldaemon.com...
 Wouldn't you normally write ?:
 if (obj) {}
 if (!obj) {}
far
 better than C and C++ (and, I think, D). The expressions in
conditionals
 should be explicitly boolean. Hence

 int    i = 1;
 X    x = new X();

 if(i)
 {

 if(!x)
 {

 Neither of those are sensible syntax. They are pandering to the
ludicrous
 proposition that the extra typing to get to ...
Well, apart from it *being* sensible syntax (e.g. when x is boolean), I'd like to stress another point. Terseness is a very valid and important goal - it is one of the most important properties of an all-around language. Some of it should, naturally, be traded off for other valid goals, like readability (see PERL for a bad-balance example, or Eiffel, on the "too verbose" end to some). Since if (x is initialized) do something with x else do error handling is among the most common coding idioms, one cannot ignore the relief the short if (x) form gives to one's fingers. It's not at all just an unfortunate accident that the syntax allows it in so many practical languages - instead, the opposite is true: the support is well worse the risks. However, it is also true, that there could be much better ways to support that idiom, than tweaked "if" statements... Using e.g. exception handling (in languages where it's convenient to use) the above can be rewritten to something like: try something with x else if (x is not initialized) // "catch" do error handling Exceptions, however, are practical only for heavier cases, where e.g. errors can arise at multiple points etc. Exceptions are *not* optimal (both in terms of readability and efficiency) for the simplest and (therefore?) most frequent cases, where a single "if" would also do perfectly. So - for the very frequent simple cases exceptions give you nothing but unnecessary overhead - legacy code will be never rewritten from "if (x is initialized)" to "catch (x is not initialized)" in order to use exception handling just because it's available and is considered "modern style" DbC invariant would also be much better, but they are just impossible, or non-trivial, or too much work to add for simple, built-in types. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ About initializations.... In short: practice sadly blurs the two completely different concepts, but "being zero" is NOT THE SAME THING as "being uninitialized". (But I guess most of you are well aware of this classic problem of automatic zero-init.) Even, "being uninitialized because of a bug" or "not got a valid value by run-time input" are two subtly different things. Now, unfortunately, as the "ideal language" is still yet to be defined, there is no standard, clear and explicit notation for if (initialized x) do something with x else do error handling programmers, when handling the above-mentioned different cases, fall back "randomly" to various techniques available in the language they usewith whatever available (some form of an "if" caluse, exception handling, assertions or other invariant checking (DbC stuff) etc.). Some languages - implicitly - support this fallback (e.g. with imlicit conversion to bool and supporting the short if(x) form), some others pretend as if the need to express briefly that "if x is OK" never existed in the real world, forcing the fallback more painful than necessary (e.g. by saying "use exceptions" or "compare x to some value" or "define an is_initialized() boolean function"). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ So, to sum it up... The "Right Thing" for coding the simple and very frequent case of "checking the usability of an object before use" would be *explicitly* supported by a good language, in some dedicated way. The "ideal language" would acknowledge that objects tend to be in "usable" and "unusable" states. It would go further than silently encouraging programmers writing "if (x)"... Thanks, Luna Kid
Mar 30 2003
parent reply "Matthew Wilson" <dmd synesis.com.au> writes:
Please not !! !!!! This is the scourge of so called, and almost always
self-styled, C++ "gurus". (Of course, this was me in a few of my former
programming lives.)

I am encouraged, however, by everyone's willingness to discuss this topic,
and think that maybe we can get somewhere. (See new post.)

"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
news:b67h67$1s59$1 digitaldaemon.com...
 Perhaps what is needed is an explicit conversion to bool, or an explicit
 nonzero / non-null check.

 Wait, we already have it!  It's called '!!'.

 Object o = someobj;
 if (!!o)
 {
     o.Print();
 }

 If you want to disallow implicit conversion to bool, at least keep the '!'
 operator so we can do this trick, which is still terse, yet explicit.  I
 argue that it's *not* that hard to read.  Once you've seen it once you
will
 know the idiom.

 Unless someone has an idea for another operator that means explicit check
if
 non-null?

 I'm not that against some other statement construct for this purpose,
 either:

 if_valid(o)
 {
 }

 Or perhaps this behavior could be made part of the 'with' statement:

 with(o)  // skips the whole block if o is null
 {
 }

 Sean



 "Matthew Wilson" <dmd synesis.com.au> wrote in message
 news:b65qho$pqk$1 digitaldaemon.com...
 Since the vast bulk of my experience is C & C++, I am coming from that
 perspective (where implicit conversions are both easy and nasty). My
 experience (and I have a lot of it in terms of clearing up other
people's
 messes) informs me that both these languages should follow Java's lead
in
 the boolean-ness of conditional expressions. I do this myself as a
matter
 of
 habit, and it does not impede the speed of my development; I still write
 code _very_ quickly, but more safely and, as I emphasised before, much
more
 *maintainably*. That's the important part of it.

 To the degree we are discussing it, terseness is an irrelevance. What
 matters is correctness, clarity  and maintainability. People with a lot
more
 weight and "name" in the industry than little old me have documented war
 stories up to their armpit. I mean no discourtesy to you (or anyone else
who
 espouses your point of view), but I find that programmers who do, or
have
 done, a lot of maintenance and/or trouble-shooting & remediation are
 unaninmous in their willingness to sacrifice terseness (not to mention
the
 odd right arm) for correctness, clarity and maintainability.

 I am a little surprised that a language that seeks to make it hard to do
the
 hard mistakes of other languages, and makes it impossible to do the
simple
 mistakes, passes the book on this point. I'm not advocating a nannying
 language, such as Java - printf() is well worth the risk - but boolean
 conditionals seems to be such a good reward for such a little sacrifice.

 However, we are debating needlessly. I know full well that I've got more
 chance of persuading Microsoft to write a standards-compliant Java
compiler
 than I have in persuading the vast bulk of developers to accept extra
typing
 when they deem it's not needed.

 To satisfy everyone, perhaps all we need is an optional compiler
warning -
 in the
 vein of DMC++s -wc - that tells us about it. (And the ability to promote
it
 to an error, of course). Walter, I imagine this would be pretty easy to
do?
 "Luna Kid" <lunakid neuropolis.org> wrote in message
 news:b64rc4$4m3$1 digitaldaemon.com...
 Wouldn't you normally write ?:
 if (obj) {}
 if (!obj) {}
is
 far
 better than C and C++ (and, I think, D). The expressions in
conditionals
 should be explicitly boolean. Hence

 int    i = 1;
 X    x = new X();

 if(i)
 {

 if(!x)
 {

 Neither of those are sensible syntax. They are pandering to the
ludicrous
 proposition that the extra typing to get to ...
Well, apart from it *being* sensible syntax (e.g. when x is boolean), I'd like to stress another point. Terseness is a very valid and important goal - it is one of the most important properties of an all-around language. Some of it should, naturally, be traded off for other valid goals, like readability (see PERL for a bad-balance example, or Eiffel, on the "too verbose" end to some). Since if (x is initialized) do something with x else do error handling is among the most common coding idioms, one cannot ignore the relief the short if (x) form gives to one's fingers. It's not at all just an unfortunate accident that the syntax allows it in so many practical languages - instead, the opposite is true: the support is well worse the risks. However, it is also true, that there could be much better ways to support that idiom, than tweaked "if" statements... Using e.g. exception handling (in languages where it's convenient to use) the above can be rewritten to something like: try something with x else if (x is not initialized) // "catch" do error handling Exceptions, however, are practical only for heavier cases, where e.g. errors can arise at multiple points etc. Exceptions are *not* optimal (both in terms of readability and efficiency) for the simplest and (therefore?) most frequent cases, where a single "if" would also do perfectly. So - for the very frequent simple cases exceptions give you nothing but unnecessary overhead - legacy code will be never rewritten from "if (x is initialized)" to "catch (x is not initialized)" in order to use exception handling just because it's available and is considered "modern style" DbC invariant would also be much better, but they are just impossible, or non-trivial, or too much work to add for simple, built-in types. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ About initializations.... In short: practice sadly blurs the two completely different concepts, but "being zero" is NOT THE SAME THING as "being uninitialized". (But I guess most of you are well aware of this classic problem of automatic zero-init.) Even, "being uninitialized because of a bug" or "not got a valid value by run-time input" are two subtly different things. Now, unfortunately, as the "ideal language" is still yet to be defined, there is no standard, clear and explicit notation for if (initialized x) do something with x else do error handling programmers, when handling the above-mentioned different cases, fall back "randomly" to various techniques available in the language they usewith whatever available (some form of an "if" caluse, exception handling, assertions or other invariant checking (DbC stuff) etc.). Some languages - implicitly - support this fallback (e.g. with imlicit conversion to bool and supporting the short if(x) form), some others pretend as if the need to express briefly that "if x is OK" never existed in the real world, forcing the fallback more painful than necessary (e.g. by saying "use exceptions" or "compare x to some value" or "define an is_initialized() boolean function"). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ So, to sum it up... The "Right Thing" for coding the simple and very frequent case of "checking the usability of an object before use" would be *explicitly* supported by a good language, in some dedicated way. The "ideal language" would acknowledge that objects tend to be in "usable" and "unusable" states. It would go further than silently encouraging programmers writing "if (x)"... Thanks, Luna Kid
Mar 30 2003
parent reply "Luna Kid" <lunakid neuropolis.org> writes:
I have to second, what Matt said.

Sean,

 Perhaps what is needed is an explicit conversion to bool,
It should read:
 Perhaps what is needed is an explicit conversion to bool.
;) Cheers, Luna Kid "Matthew Wilson" <dmd synesis.com.au> wrote in message news:b67ol6$21nu$1 digitaldaemon.com...
 Please not !! !!!! This is the scourge of so called, and almost always
 self-styled, C++ "gurus". (Of course, this was me in a few of my former
 programming lives.)

 I am encouraged, however, by everyone's willingness to discuss this topic,
 and think that maybe we can get somewhere. (See new post.)

 "Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
 news:b67h67$1s59$1 digitaldaemon.com...
 Perhaps what is needed is an explicit conversion to bool, or an explicit
 nonzero / non-null check.

 Wait, we already have it!  It's called '!!'.

 Object o = someobj;
 if (!!o)
 {
     o.Print();
 }

 If you want to disallow implicit conversion to bool, at least keep the
'!'
 operator so we can do this trick, which is still terse, yet explicit.  I
 argue that it's *not* that hard to read.  Once you've seen it once you
will
 know the idiom.

 Unless someone has an idea for another operator that means explicit
check
 if
 non-null?

 I'm not that against some other statement construct for this purpose,
 either:

 if_valid(o)
 {
 }

 Or perhaps this behavior could be made part of the 'with' statement:

 with(o)  // skips the whole block if o is null
 {
 }

 Sean



 "Matthew Wilson" <dmd synesis.com.au> wrote in message
 news:b65qho$pqk$1 digitaldaemon.com...
 Since the vast bulk of my experience is C & C++, I am coming from that
 perspective (where implicit conversions are both easy and nasty). My
 experience (and I have a lot of it in terms of clearing up other
people's
 messes) informs me that both these languages should follow Java's lead
in
 the boolean-ness of conditional expressions. I do this myself as a
matter
 of
 habit, and it does not impede the speed of my development; I still
write
 code _very_ quickly, but more safely and, as I emphasised before, much
more
 *maintainably*. That's the important part of it.

 To the degree we are discussing it, terseness is an irrelevance. What
 matters is correctness, clarity  and maintainability. People with a
lot
 more
 weight and "name" in the industry than little old me have documented
war
 stories up to their armpit. I mean no discourtesy to you (or anyone
else
 who
 espouses your point of view), but I find that programmers who do, or
have
 done, a lot of maintenance and/or trouble-shooting & remediation are
 unaninmous in their willingness to sacrifice terseness (not to mention
the
 odd right arm) for correctness, clarity and maintainability.

 I am a little surprised that a language that seeks to make it hard to
do
 the
 hard mistakes of other languages, and makes it impossible to do the
simple
 mistakes, passes the book on this point. I'm not advocating a nannying
 language, such as Java - printf() is well worth the risk - but boolean
 conditionals seems to be such a good reward for such a little
sacrifice.
 However, we are debating needlessly. I know full well that I've got
more
 chance of persuading Microsoft to write a standards-compliant Java
compiler
 than I have in persuading the vast bulk of developers to accept extra
typing
 when they deem it's not needed.

 To satisfy everyone, perhaps all we need is an optional compiler
warning -
 in the
 vein of DMC++s -wc - that tells us about it. (And the ability to
promote
 it
 to an error, of course). Walter, I imagine this would be pretty easy
to
 do?
 "Luna Kid" <lunakid neuropolis.org> wrote in message
 news:b64rc4$4m3$1 digitaldaemon.com...
 Wouldn't you normally write ?:
 if (obj) {}
 if (!obj) {}
is
 far
 better than C and C++ (and, I think, D). The expressions in
conditionals
 should be explicitly boolean. Hence

 int    i = 1;
 X    x = new X();

 if(i)
 {

 if(!x)
 {

 Neither of those are sensible syntax. They are pandering to the
ludicrous
 proposition that the extra typing to get to ...
Well, apart from it *being* sensible syntax (e.g. when x is boolean), I'd like to stress another point. Terseness is a very valid and important goal - it is one of the most important properties of an all-around language. Some of it should, naturally, be traded off for other valid goals, like readability (see PERL for a bad-balance example, or Eiffel, on the "too verbose" end to some). Since if (x is initialized) do something with x else do error handling is among the most common coding idioms, one cannot ignore the relief the short if (x) form gives to one's fingers. It's not at all just an unfortunate accident that the syntax allows it in so many practical languages - instead, the opposite is true: the support is well worse the risks. However, it is also true, that there could be much better ways to support that idiom, than tweaked "if" statements... Using e.g. exception handling (in languages where it's convenient to use) the above can be rewritten to something like: try something with x else if (x is not initialized) // "catch" do error handling Exceptions, however, are practical only for heavier cases, where e.g. errors can arise at multiple points etc. Exceptions are *not* optimal (both in terms of readability and efficiency) for the simplest and (therefore?) most frequent cases, where a single "if" would also do perfectly. So - for the very frequent simple cases exceptions give you nothing but unnecessary overhead - legacy code will be never rewritten from "if (x is initialized)" to "catch (x is not initialized)" in order to use exception handling just because it's available and is considered "modern style" DbC invariant would also be much better, but they are just impossible, or non-trivial, or too much work to add for simple, built-in types. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ About initializations.... In short: practice sadly blurs the two completely different concepts, but "being zero" is NOT THE SAME THING as "being uninitialized". (But I guess most of you are well aware of this classic problem of automatic zero-init.) Even, "being uninitialized because of a bug" or "not got a valid value by run-time input" are two subtly different things. Now, unfortunately, as the "ideal language" is still yet to be defined, there is no standard, clear and explicit notation for if (initialized x) do something with x else do error handling programmers, when handling the above-mentioned different cases, fall back "randomly" to various techniques available in the language they usewith whatever available (some form of an "if" caluse, exception handling, assertions or other invariant checking (DbC stuff) etc.). Some languages - implicitly - support this fallback (e.g. with imlicit conversion to bool and supporting the short if(x) form), some others pretend as if the need to express briefly that "if x is OK" never existed in the real world, forcing the fallback more painful than necessary (e.g. by saying "use exceptions" or "compare x to some value" or "define an is_initialized() boolean function"). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ So, to sum it up... The "Right Thing" for coding the simple and very frequent case of "checking the usability of an object before use" would be *explicitly* supported by a good language, in some dedicated way. The "ideal language" would acknowledge that objects tend to be in "usable" and "unusable" states. It would go further than silently encouraging programmers writing "if (x)"... Thanks, Luna Kid
Mar 30 2003
parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
Pedant!  ;)

Sean

"Luna Kid" <lunakid neuropolis.org> wrote in message
news:b67ppn$22jn$1 digitaldaemon.com...
 I have to second, what Matt said.

 Sean,

 Perhaps what is needed is an explicit conversion to bool,
It should read:
 Perhaps what is needed is an explicit conversion to bool.
;) Cheers, Luna Kid
Mar 30 2003
parent reply "Luna Kid" <lunakid neuropolis.org> writes:
Mmm... Actuall, I start liking Sean's "with" idea more and more:

    > Or perhaps this behavior could be made part of the 'with' statement:
    >
    > with(o)  // skips the whole block if o is null
    > {
    > }

Luna Kid


"Sean L. Palmer" <palmer.sean verizon.net> wrote in message
news:b67tuh$255m$1 digitaldaemon.com...
 Pedant!  ;)

 Sean

 "Luna Kid" <lunakid neuropolis.org> wrote in message
 news:b67ppn$22jn$1 digitaldaemon.com...
 I have to second, what Matt said.

 Sean,

 Perhaps what is needed is an explicit conversion to bool,
It should read:
 Perhaps what is needed is an explicit conversion to bool.
;) Cheers, Luna Kid
Mar 31 2003
next sibling parent reply "Luna Kid" <lunakid neuropolis.org> writes:
 Mmm... Actuall, I start liking Sean's "with" idea more and more:

     > Or perhaps this behavior could be made part of the 'with' statement:
     >
     > with(o)  // skips the whole block if o is null
     > {
     > }
Just for the record: depending on the (awaited) resolution of the recently discussed paradox of "references can be null and cannot be null" with(o) becomes redundant if "references cannot be null" will be chosen. (Which is very unlikely, I'd guess.) Luna Kid
Mar 31 2003
parent reply "Luna Kid" <lunakid neuropolis.org> writes:
     > Or perhaps this behavior could be made part of the 'with'
statement:
     >
     > with(o)  // skips the whole block if o is null
     > {
     > }
Just for the record: depending on the (awaited) resolution of the recently discussed paradox of "references can be null and cannot be null" with(o) becomes redundant if "references cannot be null"
(Ehhhhh... I mean the null-checking. Anyway, why I wrote that message trivial at all?... Man, I need a sleep again... Sorry!) Lunatic Kid
Mar 31 2003
parent reply "Luna Kid" <lunakid neuropolis.org> writes:
 (Ehhhhh... I mean the null-checking. Anyway, why I wrote
 that message trivial at all?... Man, I need a sleep again...
^^^^^^^^^^^^^^^ Nahhh, night good, folks...
Mar 31 2003
parent reply Ilya Minkov <midiclub tiscali.de> writes:
Luna Kid wrote:
(Ehhhhh... I mean the null-checking. Anyway, why I wrote
that message trivial at all?... Man, I need a sleep again...
^^^^^^^^^^^^^^^ Nahhh, night good, folks...
You might consider using a newsreader where you can delete your own messages you have already posted, like Mozilla 1.3. Very useful for paranoid androids and lunatic kids, who almost never sleep and first talk then think, like me and you. :>
Apr 09 2003
parent "Matthew Wilson" <dmd synesis.com.au> writes:
That would be a boon to many more than you two, methinks. :)

"Ilya Minkov" <midiclub tiscali.de> wrote in message
news:b71sq7$1541$2 digitaldaemon.com...
 Luna Kid wrote:
(Ehhhhh... I mean the null-checking. Anyway, why I wrote
that message trivial at all?... Man, I need a sleep again...
^^^^^^^^^^^^^^^ Nahhh, night good, folks...
You might consider using a newsreader where you can delete your own messages you have already posted, like Mozilla 1.3. Very useful for paranoid androids and lunatic kids, who almost never sleep and first talk then think, like me and you. :>
Apr 10 2003
prev sibling parent reply "Matthew Wilson" <dmd synesis.com.au> writes:
I agree it seems kinda nice, but how to do complex conditional, involving
perhaps a couple of objects, and maybe other conditions?



"Luna Kid" <lunakid neuropolis.org> wrote in message
news:b6aerf$158r$1 digitaldaemon.com...
 Mmm... Actuall, I start liking Sean's "with" idea more and more:

     > Or perhaps this behavior could be made part of the 'with' statement:
     >
     > with(o)  // skips the whole block if o is null
     > {
     > }

 Luna Kid


 "Sean L. Palmer" <palmer.sean verizon.net> wrote in message
 news:b67tuh$255m$1 digitaldaemon.com...
 Pedant!  ;)

 Sean

 "Luna Kid" <lunakid neuropolis.org> wrote in message
 news:b67ppn$22jn$1 digitaldaemon.com...
 I have to second, what Matt said.

 Sean,

 Perhaps what is needed is an explicit conversion to bool,
It should read:
 Perhaps what is needed is an explicit conversion to bool.
;) Cheers, Luna Kid
Mar 31 2003
parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
This would only cover half of the issue.  Assuming one wants distinct
semantic actions to replace if (o != null) {} and if (o1 == o2), this would
only address the former.

Me, I think that if (o) is a heavily established idiom, and if D isn't going
to support it, it should consider it an error and prepare for the slew of
complaints from people porting C code.

I'm just tossing out random ideas a lot of the time.  Brainstorming, if you
will.  If I had a truly elegant solution that would address your concerns
I'd post it.

Sean

"Matthew Wilson" <dmd synesis.com.au> wrote in message
news:b6aqbd$1ds9$1 digitaldaemon.com...
 I agree it seems kinda nice, but how to do complex conditional, involving
 perhaps a couple of objects, and maybe other conditions?



 "Luna Kid" <lunakid neuropolis.org> wrote in message
 news:b6aerf$158r$1 digitaldaemon.com...
 Mmm... Actuall, I start liking Sean's "with" idea more and more:

     > Or perhaps this behavior could be made part of the 'with'
statement:
     >
     > with(o)  // skips the whole block if o is null
     > {
     > }

 Luna Kid
Mar 31 2003
next sibling parent "Matthew Wilson" <dmd synesis.com.au> writes:
 I'm just tossing out random ideas a lot of the time.  Brainstorming, if
you
 will.  If I had a truly elegant solution that would address your concerns
 I'd post it.
And the whole newsgroup would breathe a collective sigh of relief. However, I think we should keep plugging. If you can move towards "it should consider it an error and prepare for the slew of complaints from people porting C code" then maybe anything is possible. :=))
Apr 01 2003
prev sibling next sibling parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Sean L. Palmer" <palmer.sean verizon.net> wrote in message
news:b6beok$1qun$1 digitaldaemon.com...
 Me, I think that if (o) is a heavily established idiom, and if D isn't
going
 to support it, it should consider it an error and prepare for the slew of
 complaints from people porting C code.
I have to agree, initially I was a bit against if ( o ) and if ( !o ) but since I've been doing more C I find I'm writing that in D partly because writing if ( o === null ) is prone to me forgetting the last = and I only write == and then get a seggy when o is null. I had considered the if ( !!o ) but never dared to publically voice it, you've missed the other old C idiom that I've not seen for a few years of `if ( o = func(), o )` [I do have a C book that advises the use of if ( ptr ) oevr if ( ptr == NULL )] and I've always found `if ( NULL == ptr )` to be ugly and a little confusing (especially when skim reading code). I think this is quite related to the whole ==, !=, ===, !== issue. three '=' annoys me I've been thinking that the operators for refs should be if ( x ), if ( !x ) // null check. if ( x == y ) // identical check (&x == &y in c++) if ( x != y ) // not identical if ( x $= y ) // compare values refered to (ptrs and refs [objects]) or if ( x = y ) // compare values refered to (ptrs and refs [objects]) for ptrs this is the same as writing if ( *x == *y ) if ( x <> y ) // value of x is not equivilant to y as D blurs the ptr/ref (unlike c++) allowing ptr.structmember (implicit deref) then I've not got a problem with them having a similar othe thing that always annoyed me in C++ was not being able to re-reference a reference. I also find the range of float !<> etc operators confusing, not saying Java, float/double cmp operators do every time I want to use them. as for with( o ) doing a null check and ignoreing if null ... NO I think that is too much hidden behaviour. however with ( o ) { // do this with o if o !== null } else { // do this if o is null } I think is a much better solution, if the else clause if missing then it is effectivly `else { throw new NullPointerException(); }`
 I'm just tossing out random ideas a lot of the time.  Brainstorming, if
you
 will.  If I had a truly elegant solution that would address your concerns
 I'd post it.
likewise, I feel `!=` and `<>` are two not equiv/equal operators but I can not think of two obviously different equal to operators and dis like =, ==, === as operators, I would some days even go as far as saying = should be replaced with := to make a clear distinction between assign and compare. [or even `<-` ]
Apr 01 2003
next sibling parent reply Andy Friesen <andy ikagames.com> writes:
Mike Wynn wrote:
 "Sean L. Palmer" <palmer.sean verizon.net> wrote in message
 news:b6beok$1qun$1 digitaldaemon.com...
 
Me, I think that if (o) is a heavily established idiom, and if D isn't
going
to support it, it should consider it an error and prepare for the slew of
complaints from people porting C code.
I have to agree, initially I was a bit against if ( o ) and if ( !o ) but since I've been doing more C I find I'm writing that in D partly because writing if ( o === null ) is prone to me forgetting the last = and I only write == and then get a seggy when o is null. I had considered the if ( !!o ) but never dared to publically voice it, you've missed the other old C idiom that I've not seen for a few years of `if ( o = func(), o )` [I do have a C book that advises the use of if ( ptr ) oevr if ( ptr == NULL )] and I've always found `if ( NULL == ptr )` to be ugly and a little confusing (especially when skim reading code). I think this is quite related to the whole ==, !=, ===, !== issue. three '=' annoys me I've been thinking that the operators for refs should be if ( x ), if ( !x ) // null check. if ( x == y ) // identical check (&x == &y in c++) if ( x != y ) // not identical if ( x $= y ) // compare values refered to (ptrs and refs [objects]) or if ( x = y ) // compare values refered to (ptrs and refs [objects]) for ptrs this is the same as writing if ( *x == *y ) if ( x <> y ) // value of x is not equivilant to y as D blurs the ptr/ref (unlike c++) allowing ptr.structmember (implicit deref) then I've not got a problem with them having a similar othe thing that always annoyed me in C++ was not being able to re-reference a reference. I also find the range of float !<> etc operators confusing, not saying Java, float/double cmp operators do every time I want to use them. as for with( o ) doing a null check and ignoreing if null ... NO I think that is too much hidden behaviour. however with ( o ) { // do this with o if o !== null } else { // do this if o is null } I think is a much better solution, if the else clause if missing then it is effectivly `else { throw new NullPointerException(); }`
I'm just tossing out random ideas a lot of the time.  Brainstorming, if
you
will.  If I had a truly elegant solution that would address your concerns
I'd post it.
likewise, I feel `!=` and `<>` are two not equiv/equal operators but I can not think of two obviously different equal to operators and dis like =, ==, === as operators, I would some days even go as far as saying = should be replaced with := to make a clear distinction between assign and compare. [or even `<-` ]
Python uses the keyword 'is' where D uses ===. (and 'is not' for !==) Maybe this would be better in that it doesn't look similar to == at all. (and thus would be a lot harder to confuse) if (o is not null) ... // more verbose, but totally unambigious.
Apr 01 2003
parent "Sean L. Palmer" <palmer.sean verizon.net> writes:
Make 'is' a prefix operator:

if (is o)
{ ... }

Postfix 'is' would work too:

if (o is)
{ ... }

for the opposite use it infix with null:

if (o is null)
{ ... }

Sean

"Andy Friesen" <andy ikagames.com> wrote in message
news:b6c8am$2c7l$1 digitaldaemon.com...
 Python uses the keyword 'is' where D uses ===. (and 'is not' for !==)
 Maybe this would be better in that it doesn't look similar to == at all.
 (and thus would be a lot harder to confuse)

 if (o is not null) ... // more verbose, but totally unambigious.
Apr 01 2003
prev sibling next sibling parent reply "Matthew Wilson" <dmd synesis.com.au> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:b6bpor$22l9$1 digitaldaemon.com...
 "Sean L. Palmer" <palmer.sean verizon.net> wrote in message
 news:b6beok$1qun$1 digitaldaemon.com...
 Me, I think that if (o) is a heavily established idiom, and if D isn't
going
 to support it, it should consider it an error and prepare for the slew
of
 complaints from people porting C code.
I have to agree, initially I was a bit against if ( o ) and if ( !o ) but since I've been doing more C I find I'm writing that in D partly because writing if ( o === null ) is prone to me forgetting the last = and I only write == and then get a seggy when o is null.
if(x = 0) which have learned from C/C++'s mistake, and in fact most C & C++ compilers these days warn about it. I've never met anyone that suggested that that was a good way to program. I cannot believe that D _does_ allow it. If it does I may have to go and suck my thumb for a while. That would be too poor. Say it ain't so ... :(
Apr 01 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Matthew Wilson" <dmd synesis.com.au> wrote in message
news:b6d6j8$1qt$1 digitaldaemon.com...
 "Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
 news:b6bpor$22l9$1 digitaldaemon.com...
 "Sean L. Palmer" <palmer.sean verizon.net> wrote in message
 news:b6beok$1qun$1 digitaldaemon.com...
 Me, I think that if (o) is a heavily established idiom, and if D isn't
going
 to support it, it should consider it an error and prepare for the slew
of
 complaints from people porting C code.
I have to agree, initially I was a bit against if ( o ) and if ( !o )
but
 since I've been doing more C I find I'm writing that in D partly because
 writing  if ( o === null ) is prone to me forgetting the last = and I
only
 write == and then get a seggy when o is null.
if(x = 0) which have learned from C/C++'s mistake, and in fact most C & C++
compilers
 these days warn about it. I've never met anyone that suggested that that
was
 a good way to program.

 I cannot believe that D _does_ allow it. If it does I may have to go and
 suck my thumb for a while. That would be too poor. Say it ain't so ... :(
I think you've missed 2 = 's :) I end up writing `if ( o == null )` '=""=' instead of want I wanted which is `if ( o === null )` '=''=''='
Apr 01 2003
parent reply "Matthew Wilson" <dmd synesis.com.au> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:b6djff$ab5$1 digitaldaemon.com...
 "Matthew Wilson" <dmd synesis.com.au> wrote in message
 news:b6d6j8$1qt$1 digitaldaemon.com...
 "Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
 news:b6bpor$22l9$1 digitaldaemon.com...
 "Sean L. Palmer" <palmer.sean verizon.net> wrote in message
 news:b6beok$1qun$1 digitaldaemon.com...
 Me, I think that if (o) is a heavily established idiom, and if D
isn't
 going
 to support it, it should consider it an error and prepare for the
slew
 of
 complaints from people porting C code.
I have to agree, initially I was a bit against if ( o ) and if ( !o )
but
 since I've been doing more C I find I'm writing that in D partly
because
 writing  if ( o === null ) is prone to me forgetting the last = and I
only
 write == and then get a seggy when o is null.
if(x = 0) which have learned from C/C++'s mistake, and in fact most C & C++
compilers
 these days warn about it. I've never met anyone that suggested that that
was
 a good way to program.

 I cannot believe that D _does_ allow it. If it does I may have to go and
 suck my thumb for a while. That would be too poor. Say it ain't so ...
:(
 I think you've missed 2 = 's :)

 I end up writing `if ( o == null )`  '=""='
 instead of want I wanted which is  `if ( o === null )` '=''=''='
Does not compute: what's that got to do with the issue of "if(x = 1)" ? Notwithstanding that confusion, there is certainly a readability argument against having both == and ===. If if(x = 0) is illegal, == means compare value and === is replaced with is (or similar) then there can be no confusion
Apr 01 2003
parent reply "Luna Kid" <lunakid neuropolis.org> writes:
 Notwithstanding that confusion, there is certainly a readability argument
 against having both == and ===.
For one, I hate the idea of having them both. (Or maybe having === alone, hurts me, too.) I'm sure people will have colorful problems with them all over the time, especially those migrating from C/C++. (I'd prefer something like "is", I guess, instead, as others also said here and there. What is wrong with "is"?) Luna Szabi
Apr 03 2003
parent reply Derek Parnell <Derek.Parnell No.Spam> writes:
On Thu, 3 Apr 2003 18:27:14 +0200, Luna Kid <lunakid neuropolis.org> wrote:

 Notwithstanding that confusion, there is certainly a readability 
 argument
 against having both == and ===.
For one, I hate the idea of having them both. (Or maybe having === alone, hurts me, too.) I'm sure people will have colorful problems with them all over the time, especially those migrating from C/C++. (I'd prefer something like "is", I guess, instead, as others also said here and there. What is wrong with "is"?)
Are you suggesting something like ... if (x is y) then I like the idea. It is then easy to extend it to ... if (x is available) for cases where 'x' is not initialized (or has a value of zero if that's a different thing). -- Derek
Apr 03 2003
parent "Luna Kid" <lunakid neuropolis.org> writes:
"Derek Parnell" <Derek.Parnell No.Spam> wrote in message
news:oprm2xwew0yj5swd news.digitalmars.com...
 On Thu, 3 Apr 2003 18:27:14 +0200, Luna Kid <lunakid neuropolis.org>
wrote:
 Notwithstanding that confusion, there is certainly a readability
 argument
 against having both == and ===.
For one, I hate the idea of having them both. (Or maybe having === alone, hurts me, too.) I'm sure people will have colorful problems with them all over the time, especially those migrating from C/C++. (I'd prefer something like "is", I guess, instead, as others also said here and there. What is wrong with "is"?)
Are you suggesting something like ... if (x is y) then I like the idea. It is then easy to extend it to ... if (x is available) for cases where 'x' is not initialized (or has a value of zero if that's a different thing). -- Derek
Exactly. Thanks. :) Luna Kid
Apr 04 2003
prev sibling parent "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:b6bpor$22l9$1 digitaldaemon.com...
 I also find the range of float !<> etc operators confusing, not saying
Java,

 float/double cmp operators do every time I want to use them.
If you use the C float comparison operators, it works just like C99 says it should. The additional float operators are for the other cases in the truth table, ones that come in real handy when doing carefully constructed float code. Other ways I've seen to do it, like using funky intrinsic functions, are even worse.
Jun 25 2003
prev sibling parent reply "Luna Kid" <lunakid neuropolis.org> writes:
Just to summarize the topic...

 "Luna Kid" <lunakid neuropolis.org> wrote in message
 news:b6aerf$158r$1 digitaldaemon.com...
 Mmm... Actuall, I start liking Sean's "with" idea more and more:

     > with(o)  // skips the whole block if o is null
     > {
     > }

[...snip...]
 "Matthew Wilson" <dmd synesis.com.au> wrote in message
 news:b6aqbd$1ds9$1 digitaldaemon.com...
 I agree it seems kinda nice, but how to do complex conditional,
involving
 perhaps a couple of objects, and maybe other conditions?
[...snip...]

"Sean L. Palmer" <palmer.sean verizon.net> wrote in message
news:b6beok$1qun$1 digitaldaemon.com...
 This would only cover half of the issue.  Assuming one wants distinct
 semantic actions to replace if (o != null) {} and if (o1 == o2), this
would
 only address the former.
Yes, as the core of the idea was separating general-purpose conditionals ("normal if") from checking object availability. Actually (despite what I said in private to him earlier...), Sean's with(x) would be _the_ solution. - As to the syntax, both of the controversial, but frequent and practical idioms if (x) and if (x = new object) would be supported cleanly. - As to the semantics: the meaning of the construct could be: "if x is initialized, do the following with it". What does "initialized" means? That x != null would be fine. The current reference semantics allows null values already, which does indicate some sort of "uninitializedness" anyway. (Just as a side-note: besides the != null choice, it might be tempting to say, especially performance-wise, that having class_invariant == true would also be good, but since "with (x)" is a typical run- time success/failure scenario, so, disabling contracts would break the program.) - One "drawback" is the run-time overhead for !=null checking. But no program is meaningful, which operates on uninitialized references anyway, so the code *must* contain the check, either way... Then, it would be the preferable choice that the compiler kindly took this routine burden -- and throw some "object uninitialized" exception when needed. - Note, that this same exception could be thrown, when applying any other operations on null references, such as ==, see the "null == o" thread, for example. This also offers a compromise: Walter may say that "with(x)" means an _explicit_ object validity check, but ever others do only perform no check, or, ideally, verify the class invariant in debug mode. And everyone could be quite OK with this, I think. Sab
Apr 06 2003
parent "Matthew Wilson" <dmd synesis.com.au> writes:
What about conditional

 if (x == y)

where one or both may be null? I assume your with() idea - on which I'm
still cogitating - does not address this issue, which is, in my opinion, a
lot more important than if(x) vs if(x != null)


"Luna Kid" <lunakid neuropolis.org> wrote in message
news:b6q97t$d9f$1 digitaldaemon.com...
 Just to summarize the topic...

 "Luna Kid" <lunakid neuropolis.org> wrote in message
 news:b6aerf$158r$1 digitaldaemon.com...
 Mmm... Actuall, I start liking Sean's "with" idea more and more:

     > with(o)  // skips the whole block if o is null
     > {
     > }

 [...snip...]
 "Matthew Wilson" <dmd synesis.com.au> wrote in message
 news:b6aqbd$1ds9$1 digitaldaemon.com...
 I agree it seems kinda nice, but how to do complex conditional,
involving
 perhaps a couple of objects, and maybe other conditions?
[...snip...]

 "Sean L. Palmer" <palmer.sean verizon.net> wrote in message
 news:b6beok$1qun$1 digitaldaemon.com...
 This would only cover half of the issue.  Assuming one wants distinct
 semantic actions to replace if (o != null) {} and if (o1 == o2), this
would
 only address the former.
Yes, as the core of the idea was separating general-purpose conditionals ("normal if") from checking object availability. Actually (despite what I said in private to him earlier...), Sean's with(x) would be _the_ solution. - As to the syntax, both of the controversial, but frequent and practical idioms if (x) and if (x = new object) would be supported cleanly. - As to the semantics: the meaning of the construct could be: "if x is initialized, do the following with it". What does "initialized" means? That x != null would be fine. The current reference semantics allows null values already, which does indicate some sort of "uninitializedness" anyway. (Just as a side-note: besides the != null choice, it might be tempting to say, especially performance-wise, that having class_invariant == true would also be good, but since "with (x)" is a typical run- time success/failure scenario, so, disabling contracts would break the program.) - One "drawback" is the run-time overhead for !=null checking. But no program is meaningful, which operates on uninitialized references anyway, so the code *must* contain the check, either way... Then, it would be the preferable choice that the compiler kindly took this routine burden -- and throw some "object uninitialized" exception when needed. - Note, that this same exception could be thrown, when applying any other operations on null references, such as ==, see the "null == o" thread, for example. This also offers a compromise: Walter may say that "with(x)" means an _explicit_ object validity check, but ever others do only perform no check, or, ideally, verify the class invariant in debug mode. And everyone could be quite OK with this, I think. Sab
Apr 06 2003
prev sibling parent reply Bill Cox <bill viasic.com> writes:
Hi, Matthew.

I'll second the desire for a real boolean in the condition.  However, it 
would go against Walter's goal of reducing the speed bumps in converting 
from C++ to D.

Your idea of a compiler warning sounds like an excellent compromise to 
me.  I'd certainly use it.

Bill

Matthew Wilson wrote:
 Since the vast bulk of my experience is C & C++, I am coming from that
 perspective (where implicit conversions are both easy and nasty). My
 experience (and I have a lot of it in terms of clearing up other people's
 messes) informs me that both these languages should follow Java's lead in
 the boolean-ness of conditional expressions. I do this myself as a matter of
 habit, and it does not impede the speed of my development; I still write
 code _very_ quickly, but more safely and, as I emphasised before, much more
 *maintainably*. That's the important part of it.
 
 To the degree we are discussing it, terseness is an irrelevance. What
 matters is correctness, clarity  and maintainability. People with a lot more
 weight and "name" in the industry than little old me have documented war
 stories up to their armpit. I mean no discourtesy to you (or anyone else who
 espouses your point of view), but I find that programmers who do, or have
 done, a lot of maintenance and/or trouble-shooting & remediation are
 unaninmous in their willingness to sacrifice terseness (not to mention the
 odd right arm) for correctness, clarity and maintainability.
 
 I am a little surprised that a language that seeks to make it hard to do the
 hard mistakes of other languages, and makes it impossible to do the simple
 mistakes, passes the book on this point. I'm not advocating a nannying
 language, such as Java - printf() is well worth the risk - but boolean
 conditionals seems to be such a good reward for such a little sacrifice.
 
 However, we are debating needlessly. I know full well that I've got more
 chance of persuading Microsoft to write a standards-compliant Java compiler
 than I have in persuading the vast bulk of developers to accept extra typing
 when they deem it's not needed.
 
 To satisfy everyone, perhaps all we need is an optional compiler warning -
 in the
 vein of DMC++s -wc - that tells us about it. (And the ability to promote it
 to an error, of course). Walter, I imagine this would be pretty easy to do?
 
 "Luna Kid" <lunakid neuropolis.org> wrote in message
 news:b64rc4$4m3$1 digitaldaemon.com...
 
Wouldn't you normally write ?:
if (obj) {}
if (!obj) {}
far
better than C and C++ (and, I think, D). The expressions in conditionals
should be explicitly boolean. Hence

int    i = 1;
X    x = new X();

if(i)
{

if(!x)
{

Neither of those are sensible syntax. They are pandering to the
ludicrous
proposition that the extra typing to get to ...
Well, apart from it *being* sensible syntax (e.g. when x is boolean), I'd like to stress another point. Terseness is a very valid and important goal - it is one of the most important properties of an all-around language. Some of it should, naturally, be traded off for other valid goals, like readability (see PERL for a bad-balance example, or Eiffel, on the "too verbose" end to some). Since if (x is initialized) do something with x else do error handling is among the most common coding idioms, one cannot ignore the relief the short if (x) form gives to one's fingers. It's not at all just an unfortunate accident that the syntax allows it in so many practical languages - instead, the opposite is true: the support is well worse the risks. However, it is also true, that there could be much better ways to support that idiom, than tweaked "if" statements... Using e.g. exception handling (in languages where it's convenient to use) the above can be rewritten to something like: try something with x else if (x is not initialized) // "catch" do error handling Exceptions, however, are practical only for heavier cases, where e.g. errors can arise at multiple points etc. Exceptions are *not* optimal (both in terms of readability and efficiency) for the simplest and (therefore?) most frequent cases, where a single "if" would also do perfectly. So - for the very frequent simple cases exceptions give you nothing but unnecessary overhead - legacy code will be never rewritten from "if (x is initialized)" to "catch (x is not initialized)" in order to use exception handling just because it's available and is considered "modern style" DbC invariant would also be much better, but they are just impossible, or non-trivial, or too much work to add for simple, built-in types. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ About initializations.... In short: practice sadly blurs the two completely different concepts, but "being zero" is NOT THE SAME THING as "being uninitialized". (But I guess most of you are well aware of this classic problem of automatic zero-init.) Even, "being uninitialized because of a bug" or "not got a valid value by run-time input" are two subtly different things. Now, unfortunately, as the "ideal language" is still yet to be defined, there is no standard, clear and explicit notation for if (initialized x) do something with x else do error handling programmers, when handling the above-mentioned different cases, fall back "randomly" to various techniques available in the language they usewith whatever available (some form of an "if" caluse, exception handling, assertions or other invariant checking (DbC stuff) etc.). Some languages - implicitly - support this fallback (e.g. with imlicit conversion to bool and supporting the short if(x) form), some others pretend as if the need to express briefly that "if x is OK" never existed in the real world, forcing the fallback more painful than necessary (e.g. by saying "use exceptions" or "compare x to some value" or "define an is_initialized() boolean function"). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ So, to sum it up... The "Right Thing" for coding the simple and very frequent case of "checking the usability of an object before use" would be *explicitly* supported by a good language, in some dedicated way. The "ideal language" would acknowledge that objects tend to be in "usable" and "unusable" states. It would go further than silently encouraging programmers writing "if (x)"... Thanks, Luna Kid
Mar 31 2003
parent "Matthew Wilson" <dmd synesis.com.au> writes:
Good to hear. Reckon we'll get Walter to put it in? :)

"Bill Cox" <bill viasic.com> wrote in message
news:3E87F9DF.9090002 viasic.com...
 Hi, Matthew.

 I'll second the desire for a real boolean in the condition.  However, it
 would go against Walter's goal of reducing the speed bumps in converting
 from C++ to D.

 Your idea of a compiler warning sounds like an excellent compromise to
 me.  I'd certainly use it.

 Bill

 Matthew Wilson wrote:
 Since the vast bulk of my experience is C & C++, I am coming from that
 perspective (where implicit conversions are both easy and nasty). My
 experience (and I have a lot of it in terms of clearing up other
people's
 messes) informs me that both these languages should follow Java's lead
in
 the boolean-ness of conditional expressions. I do this myself as a
matter of
 habit, and it does not impede the speed of my development; I still write
 code _very_ quickly, but more safely and, as I emphasised before, much
more
 *maintainably*. That's the important part of it.

 To the degree we are discussing it, terseness is an irrelevance. What
 matters is correctness, clarity  and maintainability. People with a lot
more
 weight and "name" in the industry than little old me have documented war
 stories up to their armpit. I mean no discourtesy to you (or anyone else
who
 espouses your point of view), but I find that programmers who do, or
have
 done, a lot of maintenance and/or trouble-shooting & remediation are
 unaninmous in their willingness to sacrifice terseness (not to mention
the
 odd right arm) for correctness, clarity and maintainability.

 I am a little surprised that a language that seeks to make it hard to do
the
 hard mistakes of other languages, and makes it impossible to do the
simple
 mistakes, passes the book on this point. I'm not advocating a nannying
 language, such as Java - printf() is well worth the risk - but boolean
 conditionals seems to be such a good reward for such a little sacrifice.

 However, we are debating needlessly. I know full well that I've got more
 chance of persuading Microsoft to write a standards-compliant Java
compiler
 than I have in persuading the vast bulk of developers to accept extra
typing
 when they deem it's not needed.

 To satisfy everyone, perhaps all we need is an optional compiler
warning -
 in the
 vein of DMC++s -wc - that tells us about it. (And the ability to promote
it
 to an error, of course). Walter, I imagine this would be pretty easy to
do?
 "Luna Kid" <lunakid neuropolis.org> wrote in message
 news:b64rc4$4m3$1 digitaldaemon.com...

Wouldn't you normally write ?:
if (obj) {}
if (!obj) {}
far
better than C and C++ (and, I think, D). The expressions in
conditionals
should be explicitly boolean. Hence

int    i = 1;
X    x = new X();

if(i)
{

if(!x)
{

Neither of those are sensible syntax. They are pandering to the
ludicrous
proposition that the extra typing to get to ...
Well, apart from it *being* sensible syntax (e.g. when x is boolean), I'd like to stress another point. Terseness is a very valid and important goal - it is one of the most important properties of an all-around language. Some of it should, naturally, be traded off for other valid goals, like readability (see PERL for a bad-balance example, or Eiffel, on the "too verbose" end to some). Since if (x is initialized) do something with x else do error handling is among the most common coding idioms, one cannot ignore the relief the short if (x) form gives to one's fingers. It's not at all just an unfortunate accident that the syntax allows it in so many practical languages - instead, the opposite is true: the support is well worse the risks. However, it is also true, that there could be much better ways to support that idiom, than tweaked "if" statements... Using e.g. exception handling (in languages where it's convenient to use) the above can be rewritten to something like: try something with x else if (x is not initialized) // "catch" do error handling Exceptions, however, are practical only for heavier cases, where e.g. errors can arise at multiple points etc. Exceptions are *not* optimal (both in terms of readability and efficiency) for the simplest and (therefore?) most frequent cases, where a single "if" would also do perfectly. So - for the very frequent simple cases exceptions give you nothing but unnecessary overhead - legacy code will be never rewritten from "if (x is initialized)" to "catch (x is not initialized)" in order to use exception handling just because it's available and is considered "modern style" DbC invariant would also be much better, but they are just impossible, or non-trivial, or too much work to add for simple, built-in types. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ About initializations.... In short: practice sadly blurs the two completely different concepts, but "being zero" is NOT THE SAME THING as "being uninitialized". (But I guess most of you are well aware of this classic problem of automatic zero-init.) Even, "being uninitialized because of a bug" or "not got a valid value by run-time input" are two subtly different things. Now, unfortunately, as the "ideal language" is still yet to be defined, there is no standard, clear and explicit notation for if (initialized x) do something with x else do error handling programmers, when handling the above-mentioned different cases, fall back "randomly" to various techniques available in the language they usewith whatever available (some form of an "if" caluse, exception handling, assertions or other invariant checking (DbC stuff) etc.). Some languages - implicitly - support this fallback (e.g. with imlicit conversion to bool and supporting the short if(x) form), some others pretend as if the need to express briefly that "if x is OK" never existed in the real world, forcing the fallback more painful than necessary (e.g. by saying "use exceptions" or "compare x to some value" or "define an is_initialized() boolean function"). +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ So, to sum it up... The "Right Thing" for coding the simple and very frequent case of "checking the usability of an object before use" would be *explicitly* supported by a good language, in some dedicated way. The "ideal language" would acknowledge that objects tend to be in "usable" and "unusable" states. It would go further than silently encouraging programmers writing "if (x)"... Thanks, Luna Kid
Mar 31 2003
prev sibling parent reply C <cc.news gateway.mirlex.com> writes:
With respect the the issue of accedentially writing

if( wombat == null ) ...

when the intention is

if( wombat === null ) ...

why not always report value comparason with null as
an error?

id est: `if( wombat == null )` would generate a
compile time error such as `value comparason (==)
with null not allowed, did you mean reference
comparason (===)?`

Such a null value comparason is highly unlikely in
code - I can think of no circumstances where such a
comparason would not be an error (can anyone else?).

This should be possible in only a few lines of
additional code to the compiler, and a line or two
to the documentation.

[Additionally, declaring `if( wombat == null )` as an
error would eliminate the need for checking for null
in the preconditions of the .eq() method.]

C 2003/4/8
Apr 07 2003
next sibling parent reply "Matthew Wilson" <dmd synesis.com.au> writes:
What about when doing

    if(x == y)

where either x or y may be null?

"C" <cc.news gateway.mirlex.com> wrote in message
news:b6vmcc$2la9$1 digitaldaemon.com...
 With respect the the issue of accedentially writing

 if( wombat == null ) ...

 when the intention is

 if( wombat === null ) ...

 why not always report value comparason with null as
 an error?

 id est: `if( wombat == null )` would generate a
 compile time error such as `value comparason (==)
 with null not allowed, did you mean reference
 comparason (===)?`

 Such a null value comparason is highly unlikely in
 code - I can think of no circumstances where such a
 comparason would not be an error (can anyone else?).

 This should be possible in only a few lines of
 additional code to the compiler, and a line or two
 to the documentation.

 [Additionally, declaring `if( wombat == null )` as an
 error would eliminate the need for checking for null
 in the preconditions of the .eq() method.]

 C 2003/4/8
Apr 10 2003
parent reply C <cc.news gateway.mirlex.com> writes:
Matthew Wilson wrote:
 What about when doing
 
     if(x == y)
 
 where either x or y may be null?
 
Well, that was not the issue I was addressing (I was thinking more about avoiding typos for x === null), though I see no reason not to look at that problem too now you have highlighted it. I believe the problem here is that we are calling a method instead of a procedure. Either using generics (templates) for operator overloading or using a different calling convention would be needed to solve this problem. If however a method is used (as is currently the case) then we have two possible solutions which improve the situation. that x is not null. id est. if( x == y ) ... would be compiled as assert( x !== null ); /* implicit assert */ if( x == y ) ... The release version could remove such checks - not a perfect solution, but at least functional. if( x === y || ( x !== null && x == y ) ) ... Assuming eax -> x and ebx -> y this would assemble to ... cmp eax, ebx ; U 1 ; x === y je if_block ; V test eax, eax ; U 1 ; x !== null jnz if_else_block ; V mov esi, [ebx] ; U 1 ; call x == y call [esi+eq_method] ; U * if_block: ... jmp if_end_block if_else_block: ... if_end_block: [Timings are for a Pentium (586) series processor] The statements including and after the 'mov' command would be required anyway for the call to the .eq() method - or may be replaced by inlining said method. Using this format would take and additional 4 cycles on a 486, 2 on a pentium and 1 on a P4 (depending on caching). However, as these tests would be likely to be explicitly needed within the eq method anyway, the main loss is in a slight (8-19 byte) increase in programme size for each == operator. Also the programme will actually run faster in the case where x and y are the same object. This is probably the best solution for D (in my opinion), as a semantics would do what would be expected. (id est: if x and y are null evaluate true; if x is null and y is not null evaluate false; otherwise compare by value. Further optimisations could be gained by common subexpression elimination (against the implicit compare) for explicit constructs such as if( wombat !== null && wombat == koala ) ... gotya in the semantics - id est the .eq() method is not called when x is null. On the other hand this is better than the current gotya: a crash. Thoughts anyone? C 2003/4/10
Apr 09 2003
parent "Matthew Wilson" <dmd synesis.com.au> writes:
Sure. Pretty much tallys with what I've been saying for a couple of weeks.
There seem to be less than a handful of objectors, but alas one of them is
Walter, and we've not had any comments from him since one that seemed quite
final. Alas we may be stuck with this wart (which is pretty much the last
one, afaics).

Whether == is a free function, a static member, or an implicit function
provided by the compiler doesn't much matter to me, so long as the eq()
method always gets given valid this and rhs operands.

Walter, any more persuaded by the growing advocacy?


"C" <cc.news gateway.mirlex.com> wrote in message
news:b74d16$2s9a$1 digitaldaemon.com...
 Matthew Wilson wrote:
 What about when doing

     if(x == y)

 where either x or y may be null?
Well, that was not the issue I was addressing (I was thinking more about avoiding typos for x === null), though I see no reason not to look at that problem too now you have highlighted it. I believe the problem here is that we are calling a method instead of a procedure. Either using generics (templates) for operator overloading or using a different calling convention would be needed to solve this problem. If however a method is used (as is currently the case) then we have two possible solutions which improve the situation. that x is not null. id est. if( x == y ) ... would be compiled as assert( x !== null ); /* implicit assert */ if( x == y ) ... The release version could remove such checks - not a perfect solution, but at least functional. if( x === y || ( x !== null && x == y ) ) ... Assuming eax -> x and ebx -> y this would assemble to ... cmp eax, ebx ; U 1 ; x === y je if_block ; V test eax, eax ; U 1 ; x !== null jnz if_else_block ; V mov esi, [ebx] ; U 1 ; call x == y call [esi+eq_method] ; U * if_block: ... jmp if_end_block if_else_block: ... if_end_block: [Timings are for a Pentium (586) series processor] The statements including and after the 'mov' command would be required anyway for the call to the .eq() method - or may be replaced by inlining said method. Using this format would take and additional 4 cycles on a 486, 2 on a pentium and 1 on a P4 (depending on caching). However, as these tests would be likely to be explicitly needed within the eq method anyway, the main loss is in a slight (8-19 byte) increase in programme size for each == operator. Also the programme will actually run faster in the case where x and y are the same object. This is probably the best solution for D (in my opinion), as a semantics would do what would be expected. (id est: if x and y are null evaluate true; if x is null and y is not null evaluate false; otherwise compare by value. Further optimisations could be gained by common subexpression elimination (against the implicit compare) for explicit constructs such as if( wombat !== null && wombat == koala ) ... gotya in the semantics - id est the .eq() method is not called when x is null. On the other hand this is better than the current gotya: a crash. Thoughts anyone? C 2003/4/10
Apr 10 2003
prev sibling parent C <cc.news gateway.mirlex.com> writes:
C wrote:

 [Additionally, declaring `if( wombat == null )` as an
 error would eliminate the need for checking for null
 in the preconditions of the .eq() method.]
Oops -- no it would not :-(. Rest of the post is still valid at least. C 2003/4/10
Apr 09 2003