December 24, 2006
On Sat, 23 Dec 2006 10:44:16 +0000 (UTC), Wolven <rma@wolven.net>
wrote:

>== Quote from Steve Horne (stephenwantshornenospam100@aol.com)'s article
>> Trying to get the best of both worlds risks bringing in a whole bunch
>> of new problems...
>>   if a == b        //  fine
>>   {
>>     ...
>>   }
>>   if a == b return c;  //  errm - well...
>>   if a == b *c++;       //  aaarrrggghhh!!!
>
>Forgive me for my ignorance (I've never programmed in C), but what isn't clear about those statements?

I never said they were ambiguous - I chose them to be increasingly ugly and with increasing potential to confuse (within the limits of short, simple examples). After all, if the meaning really is ambiguous you just disambiguate with extra parens/braces/whatever. But we don't all agree about what is/is not confusing.

Every programming language I have ever used has a way of explicitly separating the conditional expression from the body statement in an if statement. In C family languages its a closing paren. In Basic and Ada it was the 'then' keyword. In Python it is a colon. There are languages where a line-break is required, and so on.

The reason that every programming language has some way of explicitly separating the conditional expression from the body statement is that doing the separation implicitly allows too much room for confusion.


>Likewise, this one says; if a is equal to b, add one to... pointer c?  Although I'm not positive of the meaning of the *, everything else seems crystal clear.

Based on that interpretation, the pointer isn't incremented. The variable c must be a pointer, and the value it points to is incremented (and its pre-increment value returned, but discarded). The prefix '*' operator dereferences a pointer in the same way that a postfix '^' would do in Pascal. So you spotted the meaning I intended.

Now consider that the '++' operator forms an expression with a side-effect - not a statement. It is only valid as a statement because, in C, any expression is a valid statement. So why not interpret it as an empty-bodied conditional with a side-effect in the condition expression...

  if (a == (b * (c++)))  { /*  null statement  */ }

Of course this is obviously stupid to you and me - why put this expression in an if statement. But then, the same expression rules apply to while loops. And it is quite normal to have while loops that have no body statements, but which exploit side-effects in the condition expression. The compiler has to choose based on syntax rules only, not common sense, and the choice it would make in this case is the stupid one.

So the interpretation that you considered crystal clear (and that I originally intended) is, when you put a bit more thought in, simply wrong. The compiler would interpret it differently.

So tell me again how that isn't confusing...

>I'm just trying to understand WHY C(++) programmers find statements that seem perfectly clear  to me, confusing.

C-family languages already have much more potential for confusion than Pascal-family languages. There even used to be obfuscated C contests. No-one ever ran an obfuscated Pascal contest that I heard of. In fact, C-family languages are infamous for being far more confusing (potentially) than Pascal-family languages. And C-family language programmers have embraced that and accepted it, gaining the advantages and taking responsibility for managing the disadvantages.

C programmers simply aren't prone to whining about potential confusion issues unless they are real.

-- 
Remove 'wants' and 'nospam' from e-mail.
December 28, 2006
>The reason that every programming language has some way of explicitly separating the conditional expression from the body statement is that doing the separation implicitly allows too much room for confusion.

IMHO if someone wants to write parenthesis, he can do it without any problems. I see no room for confusion:

if a == b && c == d
{
 writefln("Equal");
}
else
{
 writefln("Not Equal");
}
December 29, 2006
== Quote from NN (nn-mail@bk.ru)'s article
> I see no room for confusion:
> if a == b && c == d
> {
>  writefln("Equal");
> }
> else
> {
>  writefln("Not Equal");
> }

Exactly.  Now if you could eliminate the ugly {} and ; like...

if a == b && c == d
 writefln("Equal")
else
 writefln("Not Equal")

...you would be getting closer to nice looking, easy to read, easy to learn syntax.  :)
December 29, 2006
NN wrote:
> What about removing unuseful parenthesis in 'if', 'for', 'while' ?

Because having redundancies in the syntax helps prevent bugs such as the following:

> As told by Fred Webb in alt.folklore.computers in 1990:
> 
> |  I worked at Nasa during the summer of 1963.  The group I was working
> |  in was doing preliminary work on the Mission Control Center computer
> |  systems and programs.  My office mate had the job of testing out an
> |  orbit computation program which had been used during the Mercury
> |  flights.  Running some test data with known answers through it, he was
> |  getting answers that were close, but not accurate enough.  So, he
> |  started looking for numerical problems in the algorithm, checking to
> |  make sure his tests data was really correct, etc.
> |
> |  After a couple of weeks with no results, he came across a DO
> |  statement, in the form:
> |       DO 10 I=1.10
> |  This statement was interpreted by the compiler (correctly) as:
> |       DO10I = 1.10
> |  The programmer had clearly intended:
> |       DO 10 I = 1, 10
> |
> |  After changing the `.' to a `,' the program results were correct to
> |  the desired accuracy.  Apparently, the program's answers had been
> |  "good enough" for the sub-orbital Mercury flights, so no one suspected
> |  a bug until they tried to get greater accuracy, in anticipation of
> |  later orbital and moon flights.  As far as I know, this particular bug
> |  was never blamed for any actual failure of a space flight, but the
> |  other details here seem close enough that I'm sure this incident is the
> |  source of the DO story.
December 29, 2006
== Quote from Walter Bright (newshound@digitalmars.com)'s article
> > |  After a couple of weeks with no results, he came across a DO
> > |  statement, in the form:
> > |       DO 10 I=1.10
> > |  This statement was interpreted by the compiler (correctly) as:
> > |       DO10I = 1.10
> > |  The programmer had clearly intended:
> > |       DO 10 I = 1, 10
> > |

I realize the parser ignores "whitespace", but why would it combine what are clearly seperate tokens..  i.e. DO, 10, and I?  Seems like a logic error in the compiler.

I can understand the I=1.10 error, depending on how I was defined.  But I would expect that I was defined as an Integer, in which case the compiler "should" have given an error for trying to assign a decimal to an integer.  From my perspective, it sounds like they were blaming the programmer for what was really a compiler error.  Just my opinion...  :)
December 29, 2006
Wolven wrote:
> I realize the parser ignores "whitespace", but why would it combine what are
> clearly seperate tokens..  i.e. DO, 10, and I?  Seems like a logic error in the
> compiler.

That's the way FORTRAN is defined. Whitespace is ignored.
December 29, 2006
== Quote from Walter Bright (newshound@digitalmars.com)'s article
> Wolven wrote:
> > I realize the parser ignores "whitespace", but why would it combine what are clearly seperate tokens..  i.e. DO, 10, and I?  Seems like a logic error in the compiler.
> That's the way FORTRAN is defined. Whitespace is ignored.

I thought DO10I needed to be declared as REAL.  Are you sure the problem was not those pesky hanging chads?  Boy, those card punchers are a pain, telling you. Which reminds me a story about a paper tape reader...

(just kidding)
December 29, 2006
Walter Bright wrote:
> NN wrote:
>> What about removing unuseful parenthesis in 'if', 'for', 'while' ?
> 
> Because having redundancies in the syntax helps prevent bugs such as the following:
> 
>> As told by Fred Webb in alt.folklore.computers in 1990:
>>
>> |  I worked at Nasa during the summer of 1963.  The group I was working
>> |  in was doing preliminary work on the Mission Control Center computer
>> |  systems and programs.  My office mate had the job of testing out an
>> |  orbit computation program which had been used during the Mercury
>> |  flights.  Running some test data with known answers through it, he was
>> |  getting answers that were close, but not accurate enough.  So, he
>> |  started looking for numerical problems in the algorithm, checking to
>> |  make sure his tests data was really correct, etc.
>> |
>> |  After a couple of weeks with no results, he came across a DO
>> |  statement, in the form:
>> |       DO 10 I=1.10
>> |  This statement was interpreted by the compiler (correctly) as:
>> |       DO10I = 1.10
>> |  The programmer had clearly intended:
>> |       DO 10 I = 1, 10
>> |
>> |  After changing the `.' to a `,' the program results were correct to
>> |  the desired accuracy.  Apparently, the program's answers had been
>> |  "good enough" for the sub-orbital Mercury flights, so no one suspected
>> |  a bug until they tried to get greater accuracy, in anticipation of
>> |  later orbital and moon flights.  As far as I know, this particular bug
>> |  was never blamed for any actual failure of a space flight, but the
>> |  other details here seem close enough that I'm sure this incident is the
>> |  source of the DO story.

Fortran is an evil, evil language.


Sean
December 29, 2006
Waldemar wrote:
> == Quote from Walter Bright (newshound@digitalmars.com)'s article
>> Wolven wrote:
>>> I realize the parser ignores "whitespace", but why would it combine what are
>>> clearly seperate tokens..  i.e. DO, 10, and I?  Seems like a logic error in the
>>> compiler.
>> That's the way FORTRAN is defined. Whitespace is ignored.
> 
> I thought DO10I needed to be declared as REAL.

No. FORTRAN has implicit declaration.
December 29, 2006
Wolven wrote:
> == Quote from Walter Bright (newshound@digitalmars.com)'s article
>>> |  After a couple of weeks with no results, he came across a DO
>>> |  statement, in the form:
>>> |       DO 10 I=1.10
>>> |  This statement was interpreted by the compiler (correctly) as:
>>> |       DO10I = 1.10
>>> |  The programmer had clearly intended:
>>> |       DO 10 I = 1, 10
>>> |
> 
> I realize the parser ignores "whitespace", but why would it combine what are
> clearly seperate tokens..  i.e. DO, 10, and I?  Seems like a logic error in the
> compiler.

How does the compiler know they are separate tokens?  Remember, FORTRAN ignores whitespace.  In this context, the compiler doesn't know it's parsing a DO loop until it encounters the comma.  In other words, you can consider FORTRAN to be an arbitrary look-ahead language, because the compiler only knows how to interpret a specific statement when it reaches the end of the statement.  Things are even worse than they appear, because as far as I know, keywords in FORTRAN are not reserved.


Sean