Would like a preprocessor.

P

Paul Lutus

Christopher said:
Paul Lutus said:
Christopher Barber wrote:

/ ...
The reason I hate to tell you this is because it [ goto, break ] is always a bad
programming idea.

Nonesense! What's wrong with labeled break/continue? Can you explain
exactly what kind of bad things can happen if you use it?

It creates terrible, impossible-to-maintain code. It violates every
precept of structured programming.

You have to do better than that.

I can't believe this classic case needs to be restated.

http://www.acm.org/classics/oct95/

http://cs-exhibitions.uni-klu.ac.at/contentStrucProgr.php

http://acweb.colum.edu/users/rcourington/Progclass/struprog.html

Ad infinitum.


You are simply reasserting that it is
bad
without providing details. In my own experience with these features, it
usually leads to clearer code.


Unrestricted 'goto' as in C or BASIC is indeed rare in new languages, but
constrained forms such as labeled 'break' and 'continue' continue to be
included in new languages.

IMHO only as a crutch for those not fully capable of structured programming.
In Java at least, a labelled "break" or "continue" must refer to an
enclosing labelled scope, not an arbitrary label located anywhere. This is
an improvement, but since any program can be written without these devices,
and since the consensus seems to be that these devices undermine structured
programming, I think in time they will disappear, as goto is disappearing.
C# even introdued an actual 'goto' that lets
you
jump to labels within a switch statement. These features were designed
after careful consideration by experienced programmers and language
designers.

"Experienced" is a non sequitur, it can mean anything (streetwalkers are
experienced). As you can see by reading the above articles, one will find
it difficult to defend this inclusion. IMHO this device was included to
avoid alienating too many legacy programmers. It was most certainly not
included to increase the degree to which C# represents the best in
structured programming.
 
C

Christopher Barber

Paul Lutus said:
Please read the standard literature on this topic.


False. You need to realize that a compiler turns a structured program
listing into optimized code that bears very little resemblance to the
original, and the more sophisticated the compiler, the less resemblance to
the original there is. The choice to use goto or break is solely an issue
of code maintainability and comprehension, it doesn't affect the running
speed of the resulting program if the compiler is at all efficient.

Hmmm. Have you ever actually measured the difference?
 
C

Christopher Barber

Paul Lutus said:
Christopher said:
Paul Lutus said:
Christopher Barber wrote:

/ ...

The reason I hate to tell you this is because it [ goto, break ] is
always a bad
programming idea.

Nonesense! What's wrong with labeled break/continue? Can you explain
exactly what kind of bad things can happen if you use it?

It creates terrible, impossible-to-maintain code. It violates every
precept of structured programming.

You have to do better than that.

I can't believe this classic case needs to be restated.

http://www.acm.org/classics/oct95/

http://cs-exhibitions.uni-klu.ac.at/contentStrucProgr.php

http://acweb.colum.edu/users/rcourington/Progclass/struprog.html

All of these address unconstrained 'goto' and say nothing about labeled
'break' and 'continue', which is what we were talking about. They are simply
not the same thing; e.g. you cannot write an arbitrary state machine written
using 'goto' into one using 'break' and 'continue' without introducing
conditionals and state variables.
IMHO only as a crutch for those not fully capable of structured programming.
In Java at least, a labelled "break" or "continue" must refer to an
enclosing labelled scope, not an arbitrary label located anywhere. This is
an improvement, but since any program can be written without these devices,

Programs can be written without many of the useful shortcuts provided by
modern programming languages. So what? Does that mean that useful
abstractions must not be used because they are not strictly "necessary".
and since the consensus seems to be that these devices undermine structured
programming, I think in time they will disappear, as goto is disappearing.

What consensus? Did someone take a vote?
"Experienced" is a non sequitur, it can mean anything (streetwalkers are
experienced).

So people like James Gosling, Bill Joy and Guy Steele are not experienced
enough for you?
 
P

Paul Lutus

Christopher Barber wrote:

/ ...
All of these address unconstrained 'goto' and say nothing about labeled
'break' and 'continue', which is what we were talking about.

The exact same issues are present, and the exact same arguments can be, and
are, made.
They are
simply not the same thing;

With the exception of the required nesting scope issue, they simply are the
same thing. You can use break and continue to jump to an arbitrary location
with almost the same freedom as goto.

/ ...
Programs can be written without many of the useful shortcuts provided by
modern programming languages. So what?

So what, indeed. Read the articles I posted again. These devices undermine
structured programming.
Does that mean that useful
abstractions must not be used because they are not strictly "necessary".

These are not useful abstractions. They are devices from an earlier
programming era that undermine the principles of structured programming.
What consensus? Did someone take a vote?

Okay, thank you for posting. I didn't realize I was speaking to a religious
zealot.
So people like James Gosling, Bill Joy and Guy Steele are not experienced
enough for you?

And learn how debate works. Make your argument using logic and reason, not
by name-dropping (a classic error called "argument ad authoritatem", one
avoided by all educated people).
 
P

Paul Lutus

Christopher said:
Hmmm. Have you ever actually measured the difference?

Did you read what I said? Did you try to find out whether it is so? By
definition, an efficient compiler will create an optimal object file
regardless of the legal source syntax required to create it.
 
B

Bent C Dalager

False. You need to realize that a compiler turns a structured program
listing into optimized code that bears very little resemblance to the
original, and the more sophisticated the compiler, the less resemblance to
the original there is. The choice to use goto or break is solely an issue
of code maintainability and comprehension, it doesn't affect the running
speed of the resulting program if the compiler is at all efficient.

While try/catch in itself isn't particularly slow, it often involves
the creation of an Exception object, and this certainly can be
slow. As I understand it, the creation of the stack trace takes a lot
of time.

Cheers
Bent D
 
R

Rene

While try/catch in itself isn't particularly slow, it often involves
the creation of an Exception object, and this certainly can be
slow. As I understand it, the creation of the stack trace takes a lot
of time.

An exception object is an object like everything else and can therefor be
cached and pre-inizialized. For example, if the exception is only used to
fail fast but not to provide a stack trace you can do something like this

{
Exception cachedExecption = new Exception();

// do lots of stuff

// do more stuff

{ // nested level somewhere
...
if(expected != reality) throw cachedException;
be_merry(very);
result = do_some(more);
if(result != newreality) throw cachedException;

The throwing of the exception then is instantaneous, though there is of
course a penalty whenever the method is called (but then you can do a
static initialization of the exception). Now the important thing of that is
to label the exception carefully and DOCUMENT this behavour and act
accordingly in the catch clause's because the thrown exception will have a
completely unusable stacktrace and if the behaviour is either not
documented or the catch rethrows this wrong stacktrace, you're bound to
make your fellow programmers really angry when they found out about this
after three hours searching in the wrong place. Yes it's a hack. Like goto,
this is not for the apprentice.

I've never used it but I read about it in a book about java performance
tuning.

CU

René
 
G

Grant Wagner

Paul said:
Christopher said:
The reason I hate to tell you this is because it [ goto, break ] is always a bad
programming idea.

Nonesense! What's wrong with labeled break/continue? Can you explain
exactly what kind of bad things can happen if you use it?

It creates terrible, impossible-to-maintain code. It violates every precept
of structured programming. This is why "goto" is gradually disappearing
from computer languages.

Labelled break:

boolean found = false;
findIntersection:
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if (arr1 == arr2[j]) {
found = true;
break findIntersection;
}
}
}

Unlabelled break:

boolean found = false;
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if (arr1 == arr2[j]) {
found = true;
break;
}
}
if (found) {
break;
}
}

Avoid break entirely:

boolean found = false;
for (int i = 0; i < arr1.length && !found; i++) {
for (int j = 0; j < arr2.length && !found; j++) {
found = (arr1 == arr2[j]);
}
}

I must admit, I find the labelled break to be the easiest to understand. The
condition dictating the assignment of true to "found" and the exit point of the
nested loop are located in a single place. The loops have a single entry point
(at findIntersection:), and a single exit point (also at findIntersection:).
I'm not convinced the first example is violating every precept of structured
programming. How is it much different then:

boolean isIntersectionPresent(int[] arr1, int[] arr2) {
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if (arr1 == arr2[j]) {
return true;
}
}
}
return false;
}

The second and third examples separate the assignment of "found" from the it's
use to terminate the loops. If the exit condition changes, you must locate
everywhere you test the exit condition and change them.
 
C

Chris Uppal

Grant said:
Labelled break:
[...]
Unlabelled break:
[...]
Avoid break entirely:
[...]
(This is buggy, BTW -- but it doesn't affect your point, or mine)

And lastly:
boolean isIntersectionPresent(int[] arr1, int[] arr2) {
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if (arr1 == arr2[j]) {
return true;
}
}
}
return false;
}


This is the /only/ one of the four that I would consider natural. The others
are -- to varying degrees -- obfuscated.

Granted that there are cases where other considerations would mean that one of
the others was to be preferred, but such cases are in the small minority.

-- chris
 
T

Tor Iver Wilhelmsen

Chris Uppal said:
boolean isIntersectionPresent(int[] arr1, int[] arr2) {
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if (arr1 == arr2[j]) {
return true;
}
}
}
return false;
}


This is the /only/ one of the four that I would consider natural. The others
are -- to varying degrees -- obfuscated.


But it uses multiple returns; most of the "structured programming"
texts that whine about goto also wail about the evil of multiple
method exits.

The alternative to flow control constructs like labeled break/continue
et al is to implement some state machine inside the method. Not a good
candidate for readability.

Oh, and (if I forgot to mention it before), every loop construct and
conditional statement has an implicit goto. People still use them.
 
C

Chris Uppal

Tor said:
But it uses multiple returns; most of the "structured programming"
texts that whine about goto also wail about the evil of multiple
method exits.

I take it from your choice of words that you are not in perfect agreement with
those structured programming texts ;-)

/I/ certainly am not. Let me put it this way:

The advice not to use multiple-returns is /wrong/. It always /has/ been wrong.
It always /will/ be wrong.

It is not a "matter of personal taste", it is not a "useful guideline that may
sometimes be broken", it is not even merely "unhelpful". It is /wrong/.

And the same thing goes for multiple exits from loops.

I have wasted far too much time trying to unravel the compled knots that
programmers get themselves into while following this absurd "principle", to
have much patience with its supporters. Let it be said clearly: the "no early
returns" idea is not only wrong, it is /stupid/.

So there !

(Fortunately, the fashion for this predjudice is dying out as the dinosaurs of
programming themselves die out; taking their multi-thousand line functions with
them...)

Oh, and (if I forgot to mention it before), every loop construct and
conditional statement has an implicit goto. People still use them.

Indeed. So do function calls (or method calls). And function returns involve
an implicit /assigned/ goto, which is -- of course, even worse !

-- chris
 
C

Christopher Barber

Paul Lutus said:
With the exception of the required nesting scope issue, they simply are the
same thing. You can use break and continue to jump to an arbitrary location
with almost the same freedom as goto.

The nesting scope issue is quite a big semantic difference, although you
clearly do not grok the difference.
So what, indeed. Read the articles I posted again. These devices undermine
structured programming.

I did. The articles do not explain why labeled break or continue are
bad. Perhaps you can offer a concrete example. Perhaps not.
These are not useful abstractions.

I and many other people have found them to be useful abstractions. I use
labeled loops very infrequently, but they are indeed useful from time to time.
They are devices from an earlier programming era that undermine the
principles of structured programming.

No, labeled break/continue is a more recent language concept. (At least
I don't know any older languages that have this feature.)
Okay, thank you for posting. I didn't realize I was speaking to a religious
zealot.

Claiming there is a consensus does not make it so. Labeling people who
disagree with you as "religious zealots" doesn't prove anything either.
Furthermore, what kind of zealot do you think I am? I am a pragmatist. I am
happy to use language features that carry their own weight, without worrying
that I might be reprimanded by the United Brotherhood of Structured
Programmers.
And learn how debate works. Make your argument using logic and reason, not
by name-dropping (a classic error called "argument ad authoritatem", one
avoided by all educated people).

I know perfectly well how debate works. You suggested that anyone with
experience and knowledge of Strutured Programming would never put features
such as labeled break and continue into their language. I refuted you by
pointing out that Java was designed by people who have undeniable experience.
In this case the name dropping was appropriate.

So far, your side of the argument has consisted of nothing more than pointing
to some old articles on 'goto' and vague statements about Structured
Programming and maintainability.

- Christopher
 
C

Christopher Barber

Paul Lutus said:
Did you read what I said? Did you try to find out whether it is so? By
definition, an efficient compiler will create an optimal object file
regardless of the legal source syntax required to create it.

But the compiler still cannot ignore the real semantic differences between
try/throw and break/continue. The designers of Java intended try/throw to be
used for "exceptional" conditions, not regular control flow, and most compiler
writers only try to optimize for the case in which no exception is thrown. I
think if you actually do the measurement on this "efficient compiler" you
speak of, you will almost certianly find that there is indeed a performance
difference.
 
P

Paul Lutus

Christopher Barber wrote:

/ ...
I did. The articles do not explain why labeled break or continue are
bad.

They do exactly that. It created unclear code that undermines the most basic
ides of structured programming and produces code that is more difficult to
debug, modify, or understand.
Perhaps you can offer a concrete example.

The articles do this also, very clearly.

/ ...
So far, your side of the argument ...

So somehow the bedrock principles of structured programming have become my
side of an argument? How post-modern.
 
P

Paul Lutus

Christopher Barber wrote:

/ ...
But the compiler still cannot ignore the real semantic differences between
try/throw and break/continue.

That would produce different algorithms, so you in fact did not read what I
said.

You are missing a very fundamental point.

1. The only way to justify goto, break, continue, et al.. is to show that
these constructs create the same logic, the same algorithm, as the more
structured alternatives. If, on the other hand, these methods changed the
basic algorithm, rather than merely the style of the source file, they
would be immediately disallowed, because the point -- design of a specific
algorithm with a specific outcome -- would be undermined.

2. Given all of (1) above, and given that the algorithm is the same in all
syntactically acceptable styles of programming it, an optimal compiler will
produce the same object code file for all the variations.
The designers of Java intended try/throw to
be used for "exceptional" conditions, not regular control flow, and most
compiler
writers only try to optimize for the case in which no exception is thrown.
I think if you actually do the measurement on this "efficient compiler"
you speak of, you will almost certianly find that there is indeed a
performance difference.

Not for an optimally efficient compiler, unless two different algorithms
were intended. Surely you see this -- for each algorithm, there is ONE
optimal object file, just as there is ONE optimal outcome for each
Traveling Salesman problem.
 
P

Paul Lutus

Malcolm said:
Paul Lutus ([email protected]) wrote:

: Not for an optimally efficient compiler, unless two different algorithms
: were intended. Surely you see this -- for each algorithm, there is ONE
: optimal object file,

Ignoring the fact that there is more than one meaning for "optimal",

No, there is just one in this context.
I
don't see how you can assert that there is only one possible object file
that is optimal.

That is because you don't know the meaning of optimal. There is only one
optimal object file for a given algorithm.
How can you be sure that there are not two possible
arrangements of low level intructions that both result in the same high
level result, and that both are not optimal in the same way, such as the
size of the code or the time required for the code to process identical
inputs?

Study the classic Traveling Salesman and similar problems, and note that the
problem is one of producing the same algorithm using two or more syntax
variations in a source file. Trivial reorderings aside, either the result
is the same or the compiler is not optimal.
 
M

Malcolm Dew-Jones

Paul Lutus ([email protected]) wrote:

: Not for an optimally efficient compiler, unless two different algorithms
: were intended. Surely you see this -- for each algorithm, there is ONE
: optimal object file,

Ignoring the fact that there is more than one meaning for "optimal", I
don't see how you can assert that there is only one possible object file
that is optimal. How can you be sure that there are not two possible
arrangements of low level intructions that both result in the same high
level result, and that both are not optimal in the same way, such as the
size of the code or the time required for the code to process identical
inputs?

The simple re-ordering of some assignments to variables that are not used
until some undeterminable later time sounds like the sort of thing that
would produce different object files that provide the same high level
result and which would, in at least some examples, contain code that is
identical in every way except for the reordering of some instructions.
(I am of course talking about a compiler re-ordering the code.)


: just as there is ONE optimal outcome for each : Traveling Salesman
problem.

I don't see that either. Let's travel through the following net.


Town two.
Town one. Town four.
Town three.


I think that Town one.=>Town two.=>Town three.=>Town four.
and Town one.=>Town three.=>Town two.=>Town four.

are both optimum routes.
 
R

Rene

Paul Lutus said:
That is because you don't know the meaning of optimal. There is only one
optimal object file for a given algorithm.

Sorry but here you are very wrong.

*The* optimal object code does not exist. There is *always* a trade off.

You may have the optimal object code for runtime (ie the fastest code)
You may have the optimal object code for size (ie the smallest code)
You may have the optimal object code for ressource (ie the code using least
ressources, most often memory)
You may have the optimal object code for readabilty (ie the easiest to
undestand object code)

There is *always* a trade off in programming. Most often between runtime,
complexity and memory usage. Sometimes code size is also an issue (think
MIDP)

Does the term "loop unrolling" ring a bell? It is one of the very basic
optimizations. It makes the (object) code bigger, less easier to understand
but faster.


CU

René
 
B

Bent C Dalager

Not for an optimally efficient compiler, unless two different algorithms
were intended. Surely you see this -- for each algorithm, there is ONE
optimal object file, just as there is ONE optimal outcome for each
Traveling Salesman problem.

I am not sure what you are trying to say here. Are you talking of
optimal solutions or optimal costs?

Taking a travelling salesman example, let us say you have 8
destinations equally spaced along the periphery of a circle and a
fifth one (the starting point) in the center of the circle, it is easy
to see that there are multiple optimal solutions (16 I think). This is
largely given by the symmetry of the problem. There is, however, only
one optimal shortest travel distance (i.e., optimal cost) - it is the
same for all the 16(?) optimal solutions.

So what do you actually mean by "one optimal outcome"?

Cheers
Bent D
 
P

Paul Lutus

Rene said:
Sorry but here you are very wrong.

*The* optimal object code does not exist. There is *always* a trade off.

I didn't say the optimal exists, one can refer to an idea without having it
available. So, contrary to your assertion, here I am very right. My use of
the expression "optimal" means just what it says -- it's the ideal result
of optimization.
You may have the optimal object code for runtime (ie the fastest code)
You may have the optimal object code for size (ie the smallest code)
You may have the optimal object code for ressource (ie the code using
least ressources, most often memory)
You may have the optimal object code for readabilty (ie the easiest to
undestand object code)

But a change in a source file that is meant to be performance-neutral and
adhere to the original intent, must produce the same object result,
regardless of the definition of "optimal". My original point.

If the ideal compiler has been arranged to produce the shortest possible
program, this result will obtain regardless of which valid syntax choices
are exercised by the programmer for a given algorithm. Same for fastest or
any other desired trait.
There is *always* a trade off in programming. Most often between runtime,
complexity and memory usage. Sometimes code size is also an issue (think
MIDP)

True, red herring. It is not what we are discussing.
Does the term "loop unrolling" ring a bell? It is one of the very basic
optimizations. It makes the (object) code bigger, less easier to
understand but faster.

Yes, and this exact optimization should be performed by an ideal compiler
regardless of the specific contents of the source file, whether or not
"goto, while, continue" et. al. were used or not. That was my point.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,082
Latest member
KetonaraKetoACV

Latest Threads

Top