December 01, 2003
Walter wrote:

> Several C++ compilers do emit warnings for such. I find those warnings to be
> irritating rather than useful. For example, they will warn about:
> 
>     int foo()
>     {
>         while (1)
>         {
>                 ....
>                     return ...;
>         }
>     }
> 
> where it is *not possible* for the code to fall off the end, but the warning
> happens, and to get rid of it I have to put in a return statement that will
> never execute. I find being forced to add code that will never execute to be
> inelegant and potentially confusing. Hence my motivation for having D ensure
> that it never executes by raising an exception if it does, but that doesn't
> muck up the source code.

There are a couple things I really don't like about that code anyway.  For
instance, it is usually bad practice to return from inside a loop--your language
has to be very good at cleaning up its stack in these cases.  Second, if you
want to loop forever until something important happens, use while(true) instead
of a number.  Explicit booleans can make conditionals absolutely clear.
Lastly, if you want to break a loop early, that is what the break keyward is
for.  I have seen several programs where there was a similar "loop" in the code,
but instead of while(1) it was while(0).  In essense the code would never run,
but because it is not commented out, you might waste time looking in there.

Anyhoo, I really don't like that snippet above for my own sense of code style
purposes.  It really isn't that clear.

I have read in many places that it is much better to have the principle of one
place of exit.  Instead of having something like this:

if (foo < bar) return -1;
if (foo > bar) return 1;

return 0;

It would be better overall to have something like this:

int ordinal = 0;

if (foo < bar) ordinal--;
if (foo > bar) ordinal++;

return ordinal;

There are a couple of reasons, first of which is that there is a clear exit
point that will always be taken.  Second of which we are being a little more
semantically clear in that we are comparing the relative order of two objects,
and returning a value where the sign is more important than the value.  0 means
the objects are equal, negative means the second object should come before the
first, and positive means the second object should come after the second.  (This
is adapted from how Comparators work in Java).

While the first example is technically legal, the maintainer who comes along
afterwords has to figure out what is going on.  In this example it is relatively
clear.  However, I have had to maintain some methods where the return was
buried within several statements inside the conditional, and not really clear
where it was.  By enforcing the principle of one place of exit, the snippet you
provided would be better written as:

int foo() {
     while(true) {
          .....
               break;
     }

     return ...;
}

Since that is the true intention of the code.

December 01, 2003
I think the principle of the easiest thing would mean that we have the compiler
require the "default" statement.  That would require the developer to think
about what will happen if something other than the expected happens.  It is
easier than finding out about it the hard way.

The important thing to realize is that D is the only language I am aware of
where the lack of a default clause to handle errors of this type will throw
an exception.  The number of people who will be caught by this trap is
staggering.

It's not just C/C++ developers.  There are also Objective-C, C#, Java, VB,
Perl, Python, etc.  Please, if it is an error not to handle all switch types,
require the developer to put in the default statement.

If nothing else, they can output some debug info to the std err stream.

Matthew Wilson wrote:

> Does anyone disagree that C/C++'s switch semantics are dangerous, even if
> the (we) old farts have gotten used to it and rarely get bitten?
> 
> Does anyone think that it should be fixed in a way where implicit dangers
> still lurk for the unwary, whether that be inability to grok the new
> dangers, or the inability to get out of the mindset of the old (C/C++)
> semantics?
> 
> Isn't the only sensible approach to have the compiler enforce the semantics,
> and not allow any possibility of mistakes on our part?
> 
> Given that, why don't we simply accept the reality and have something along
> the lines:
> 
> 1. Each case must end in break, throw, return, fallthrough or goto
> 2. The default case must be included.
> 
> At first blush it seems nice to allow default to be skipped when switching
> on an enum if all enum values are given cases. However, since they might be
> updated in one bit of client code after the creation of the object code
> containing the switch, this is probably not wise. Maybe this is where
> Walter's exception would get thrown. But I think this stinks (and I'm not
> alone), so I'd rather see either the default be required and the code
> explicitly request that the exception be throw, or we could have another
> case keyword unexpected

<snip/>

December 01, 2003
Ilya Minkov wrote:

> Roberto Mariottini wrote:
> 
>> I also support requiring default. The laziness is your biggest enemy,
>> so type those 8 keys on the keyboard and that's all. But I know I'm almost alone
>> here: people want to save typing, not to produce robust code.
> 
> 
> Requiring default will bring us to people typing "default: break;" instead of "default: assert(0)"  just exactly for the reason you stated!

For some people, that is exactly what they want.  You do need to walk a balance
between *encouraging* good coding practice, and *requiring* it.


December 01, 2003
I think your numbers are spot on.

For me, personally, it's been reversed.  Missing default:assert(0); hasn't bitten me much, because any switch on an enum that I expect can grow already has a default:assert(0); written in explicitly.  But the implicit fallthrough has bitten me so many times it makes me scream every time it happens (and it happens fairly frequently).

I know that the C fallthru behavior ends up on many a FAQ, and if you took a poll of C users, they would rank it high on the list of bug sources, probably just a few rungs down from dangling pointers, memory leaks, and off-by-one errors.

Sean

"Matthew Wilson" <matthew.hat@stlsoft.dot.org> wrote in message news:bqefkr$2dnm$1@digitaldaemon.com...
> > Part of my reluctance to do that is implict fallthrough just has never
> been
> > an issue for me in 25 years of programming. But the implicit
> default:break;
> > has bitten me many times!
>
> I can honestly say that neither issue has hurt me once in, say, the last five years. But what've either of our cat's whiskers got to do with it. There aren't many people who spend as much time as we on the keyboard - lucky bleeders! - so my question is: do you want your language to be a desirable option only for those who've been bitten for hard enough and
long
> enough in older curmudgeonlier languages. There aren't that many of us
left;
> most have slothed off into middle management by now.
>
> Surely you want to appeal to younger programmers. Since universities are
not
> teaching much worth absorbing these days, why not build things into your language that help people who are of intermediate level, rather than just doing the bits you deem are needed for you and those like you(/us)?
>
> 1. If every aspect of switch is explicit and compile-time, how many users
of
> D will be hurt? 0
> 2. If things remain implicit and, worse, there is runtime handling of
> code-time errors, how many users of D will be hurt? Probably about 20-40%
> now. Probably about 90-95% of the eventual target user base.
>
> If I'm wrong about this, can someone please tell me. I don't want to hear about any individual wants personally, we've already gone through that already. (Personally, I'd rather have it precisely have the semantics of
C's
> switch, but I'd rather have D robust and successful than have to type a
few
> less keystrokes.)
>
> Just point out where I'm wrong with these projections. (Notwithstanding
the
> inherent inaccuracies in the precise numbers).
>
> Matthew
>
>


December 01, 2003
The default, implicit, behavior should be the most common behavior needed by the programmer.  For this reason, "in" parameters do not need explicitly specified as "in".

break is much more common than fallthru, and would be even more so if case supported ranges or multiple values.

Sean

"Georg Wrede" <Georg_member@pathlink.com> wrote in message news:bqf21n$81m$1@digitaldaemon.com...
> The rant about touch typing was (among other things) for the guys who wanted an implicit break in every case. Sure, it's nice to save ink, but the pros of it don't outweigh the cons.


December 01, 2003
Hear, hear!

You've put it better than I did in any of my rants.

:)

"Berin Loritsch" <bloritsch@d-haven.org> wrote in message news:bqfjgb$10o9$1@digitaldaemon.com...
> I think the principle of the easiest thing would mean that we have the
compiler
> require the "default" statement.  That would require the developer to
think
> about what will happen if something other than the expected happens.  It
is
> easier than finding out about it the hard way.
>
> The important thing to realize is that D is the only language I am aware
of
> where the lack of a default clause to handle errors of this type will
throw
> an exception.  The number of people who will be caught by this trap is staggering.
>
> It's not just C/C++ developers.  There are also Objective-C, C#, Java, VB, Perl, Python, etc.  Please, if it is an error not to handle all switch
types,
> require the developer to put in the default statement.
>
> If nothing else, they can output some debug info to the std err stream.
>
> Matthew Wilson wrote:
>
> > Does anyone disagree that C/C++'s switch semantics are dangerous, even
if
> > the (we) old farts have gotten used to it and rarely get bitten?
> >
> > Does anyone think that it should be fixed in a way where implicit
dangers
> > still lurk for the unwary, whether that be inability to grok the new dangers, or the inability to get out of the mindset of the old (C/C++) semantics?
> >
> > Isn't the only sensible approach to have the compiler enforce the
semantics,
> > and not allow any possibility of mistakes on our part?
> >
> > Given that, why don't we simply accept the reality and have something
along
> > the lines:
> >
> > 1. Each case must end in break, throw, return, fallthrough or goto 2. The default case must be included.
> >
> > At first blush it seems nice to allow default to be skipped when
switching
> > on an enum if all enum values are given cases. However, since they might
be
> > updated in one bit of client code after the creation of the object code containing the switch, this is probably not wise. Maybe this is where Walter's exception would get thrown. But I think this stinks (and I'm
not
> > alone), so I'd rather see either the default be required and the code explicitly request that the exception be throw, or we could have another case keyword unexpected
>
> <snip/>
>


December 01, 2003
In article <bqf21n$81m$1@digitaldaemon.com>, Georg Wrede wrote:
> If it were obligatory to write the default statement, then these latter folks would just learn that that is something that has to be there, and obviously the line would be 'default: break;'. When their programs don't work the way they expect, then they have a very hard time finding out why. And since the compiler couldn't warn or error about this, the only way is to figure out why it acts other than we wished.

This reminds of the classic way Java novices learn to use exception specifications instead of the infamous "try ... catch { }" idiom.

Step 1: "My program doesn't compile." "Wrap your functions in try
statements and accompany them with empty catch statements."
Step 2: "Now it compiles!" "Great! Did you try to run it?"
Step 3: "Now it crashes..." "All right. Now let me tell you about exception
specifications..."

(It's funny 'cos it's true!)

In an ideal language, the programmer should not be forced to write something "just because". Every line of code should mean something. "default: break;" does not say much, so maybe it would be best to just leave it unsaid? A single "return 0"; in the end of the function is not very informative either. C++ is overly verbose and tedious because it forces you to say "public" and "virtual" and "= 0" and "const" everywhere and demands that you maintain two copies of function and member function declarations (at worst three if you want insulation). And it forces you to say "break" all the time.

> The rant about touch typing was (among other things) for the guys who wanted an implicit break in every case. Sure, it's nice to save ink, but the pros of it don't outweigh the cons.

Perhaps I'm reaching for the Dark Side by saying that the most common operation should be the default -- so that the programmer wouldn't have to type and read as much. In other word, I'm suggesting that the programmers should follow their natural tendency to be lazy.  But on the other hand, shouldn't this principle be most satisfying to also the maintenance programmer, who would not be forced to search for the missing "break" in the switch statement (breaking is the most common operation, so why state the obvious, and the rare "fallthrough" or "goto case" would catch the reader's attention properly), and to spend time wondering if the return statement at the end of function was missing by purpose or by mistake?

In short, requiring a "break" in a switch statement feels similar to requiring an empty "return" in the end of a function that does not in fact return anything.

Of course, there are differing opinions as to what the most common operation in fact is. Some might even carry the opinion that in the switch statement, it's falling through -- obviously. Why else would C's switch statement fall through by default?

Another feeling that comes with this is that in general, certain things should not happen silently.  Such as throwing compiler-generated exceptions.

If you want to make a function which throws an exception if the end of the function is reached, it would be in my opinion fair to force the programmer to write "assert(0)" or "throw ShouldNotBeHereException" or something similar before the end of the function.

And if the programmer just happened to forget the return statement (or the exception), the compiler would immediately complain about it.

-Antti

December 01, 2003
In article <bqfjgb$10o9$1@digitaldaemon.com>, Berin Loritsch says...
>
>I think the principle of the easiest thing would mean that we have the compiler require the "default" statement.

>If nothing else, they can output some debug info to the std err stream.

Maybe the compiler could add that instead of throwing a fatal error. during compilation the module name and the line number are available.

Ant


December 02, 2003
Terse code is much easier to scan visually (think scanning a 1000-line program written by a novice vs. an equivalent 100-line program written by a guru)

In wordy code, there are more places for bugs to hide.

It is easy to maintain code that isn't there.

It is hard to remove code once it has been added.

IMHO, the shorter a piece of code is, the better, up to near the information limit.  Simplify, simplify, simplify, until there is no more redundancy, fluff, or contorted logic remaining.

Sean

"Antti Sykäri" <jsykari@gamma.hut.fi> wrote in message news:slrnbsn7ls.17n.jsykari@pulu.hut.fi...
> In an ideal language, the programmer should not be forced to write something "just because". Every line of code should mean something. "default: break;" does not say much, so maybe it would be best to just leave it unsaid? A single "return 0"; in the end of the function is not very informative either. C++ is overly verbose and tedious because it forces you to say "public" and "virtual" and "= 0" and "const" everywhere and demands that you maintain two copies of function and member function declarations (at worst three if you want insulation). And it forces you to say "break" all the time.
>
> Perhaps I'm reaching for the Dark Side by saying that the most common operation should be the default -- so that the programmer wouldn't have to type and read as much. In other word, I'm suggesting that the programmers should follow their natural tendency to be lazy.  But on the other hand, shouldn't this principle be most satisfying to also the maintenance programmer, who would not be forced to search for the missing "break" in the switch statement (breaking is the most common operation, so why state the obvious, and the rare "fallthrough" or "goto case" would catch the reader's attention properly), and to spend time wondering if the return statement at the end of function was missing by purpose or by mistake?
>
> In short, requiring a "break" in a switch statement feels similar to requiring an empty "return" in the end of a function that does not in fact return anything.
>
> Of course, there are differing opinions as to what the most common operation in fact is. Some might even carry the opinion that in the switch statement, it's falling through -- obviously. Why else would C's switch statement fall through by default?
>
> Another feeling that comes with this is that in general, certain things should not happen silently.  Such as throwing compiler-generated exceptions.
>
> If you want to make a function which throws an exception if the end of the function is reached, it would be in my opinion fair to force the programmer to write "assert(0)" or "throw ShouldNotBeHereException" or something similar before the end of the function.
>
> And if the programmer just happened to forget the return statement (or the exception), the compiler would immediately complain about it.
>
> -Antti



December 02, 2003
Yeah, I agree. I'd like to use smthng like:

switch a
case 1,3..8,15,99:
//etc....
default:
//etc....
end

It is easier than the fallthrough approach....


In article <bqg1ki$1n9k$1@digitaldaemon.com>, Sean L. Palmer says...
>
>The default, implicit, behavior should be the most common behavior needed by the programmer.  For this reason, "in" parameters do not need explicitly specified as "in".
>
>break is much more common than fallthru, and would be even more so if case supported ranges or multiple values.
>
>Sean
>
>"Georg Wrede" <Georg_member@pathlink.com> wrote in message news:bqf21n$81m$1@digitaldaemon.com...
>> The rant about touch typing was (among other things) for the guys who wanted an implicit break in every case. Sure, it's nice to save ink, but the pros of it don't outweigh the cons.
>
>


3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19