Lazarus

Programming => General => Topic started by: GypsyPrince on March 26, 2020, 09:33:14 am

Title: [SOLVED] Conditional test statement/semicolon Hell!
Post by: GypsyPrince on March 26, 2020, 09:33:14 am
Just a general statement here...

Whomever decided the method for using/not using semicolons with If-Then and Case conditional test statements must have been eating mushrooms laced with LSD at the time.

A simple If block - no big deal. But for nested If blocks... kinda makes me want to seriously rethink learning this language. Could there possibly be a more flawed and headache inducing language feature?

Holy tomatoes, Batman!


Edit:
Programming languages are tools meant to be bent and shaped in whatever direction serves the whims of the person using them.  They are not holy relics to be worshipped in a glass case.  In other words... do your own thing that works for you and ignore the purists.  Do what ever works best for your particular situation and not necessarily whatever someone else thinks you should do.
Title: Re: Conditional test statement/semicolon Hell!
Post by: PascalDragon on March 26, 2020, 09:39:07 am
The important point to know is that Pascal uses the semicolon as a statement separator, not a terminator like C does. Thus one can drop the semicolon before an end and multiple semicolons are allowed as well. The semicolon also separates branches of a case-statement. And the syntax for an if-statement is if expr then block|stmt else block|stmt and neither a block, nor a stmt is terminated by a semicolon.
Title: Re: Conditional test statement/semicolon Hell!
Post by: GypsyPrince on March 26, 2020, 09:45:05 am
@PascalDragon

It's frying my brain trying to keep them organized.

I'm going to need a HUGE bottle of aspirin...

LOL :o
Title: Re: Conditional test statement/semicolon Hell!
Post by: PascalDragon on March 26, 2020, 09:49:05 am
Where exactly do you have your problems? Because honestly I don't think about semicolons in 99% of the cases.
Title: Re: Conditional test statement/semicolon Hell!
Post by: marcov on March 26, 2020, 09:49:37 am
Just a general statement here...

Whomever decided the method for using/not using semicolons with If-Then and Case conditional test statements must have been eating mushrooms laced with LSD at the time.

Yes. Fixed in Pascal successor Modula2 in 1980.
Title: Re: Conditional test statement/semicolon Hell!
Post by: MarkMLl on March 26, 2020, 09:52:09 am
Just a general statement here...

Whomever decided the method for using/not using semicolons with If-Then and Case conditional test statements must have been eating mushrooms laced with LSD at the time.

Take it up with Wirth, and with the designers of ALGOL in the late 1950s.

Quote
A simple If block - no big deal. But for nested If blocks... kinda makes me want to seriously rethink learning this language. Could there possibly be a more flawed and headache inducing language feature?

It's known as the dangling else problem. It was fixed in ALGOL-68, but Wirth chose not to fix it in Pascal although he did in Modula-2.

You can make life easier for yourself by using OTHERWISE rather than ELSE in a case statement.

Me, I treat  ;  as a strict separator which is how it was described in the books when I was learning the language. I'd not say that I never have problems with this, but unfortunately it's a language definition flaw that we all have to live with.

MarkMLl
Title: Re: Conditional test statement/semicolon Hell!
Post by: GypsyPrince on March 26, 2020, 09:54:09 am
I use deeply nested If blocks.  Some have single statements while some have compound statements. For sake of not racking my brain, I'm simply putting begin/end in each level.  It's working now without compiler error, but my brain hurts.

Efficiency comes from consistency and repetition. I wish the Free Pascal developers would require the semicolon at the end of all statements, or none. Like it is, I don't think FP could be used in a high-production office setting.
Title: Re: Conditional test statement/semicolon Hell!
Post by: PascalDragon on March 26, 2020, 10:01:13 am
I use deeply nested If blocks.  Some have single statements while some have compound statements. For sake of not racking my brain, I'm simply putting begin/end in each level.  It's working now without compiler error, but my brain hurts.

Using beginend pairs is definitely a valid solution to avoid the potential pitfalls there...

Efficiency comes from consistency and repetition. I wish the Free Pascal developers would require the semicolon at the end of all statements, or none. Like it is, I don't think FP could be used in a high-production office setting.

Then those that successfully use Delphi/FPC in high-production office settings will disagree. :-X And while I might not use FPC officially at work (there we use C++) I can quickly pump out working Object Pascal code with no problems...
Title: Re: Conditional test statement/semicolon Hell!
Post by: GypsyPrince on March 26, 2020, 10:08:23 am
@PascalDragon

Quote
Then those that successfully use Delphi/FPC in high-production office settings will disagree. :-X And while I might not use FPC officially at work (there we use C++) I can quickly pump out working Object Pascal code with no problems...

I'm certain when I get several more hours of FP/Lazarus under my belt I'll have a different attitude. Right not all my years of experience in C and wanting to terminate everything is working against me.
Title: Re: Conditional test statement/semicolon Hell!
Post by: MarkMLl on March 26, 2020, 10:18:43 am
I wish the Free Pascal developers would require the semicolon at the end of all statements, or none. Like it is, I don't think FP could be used in a high-production office setting.

In that case it wouldn't be Pascal any more. This is a language /definition/ issue, not an /implementation/ issue... there's a few things that have been improved over the years (like tolerating ; in a couple of places where it was specifically prohibited by Wirth) but there's limits as to what can be done without breaking the language.

MarkMLl


Title: Re: Conditional test statement/semicolon Hell!
Post by: GypsyPrince on March 26, 2020, 10:46:43 am
@MarkMLI

Quote
...but there's limits as to what can be done without breaking the language.

Actually, no, there's not. Just as spoken languages are allowed to evolve, so are programming languages. Programming languages/environments are tools meant to serve the programmer - nothing more.  They certainly are not holy relics.  Implementing the option to terminate each statement with a semicolon (I stress the word "option", as it would not be a requirement) would certainly not "break" the language.  Is there some regard for Pascal as a holy relic? would it really hurt someone's feelings if a few things were changed to make it more user-friendly and efficient?  I certainly hope not because Shakespeare would be rolling over in his grave if he knew the extent to which the English language has changed since he helped formalize it.

Again, a programming language is simply a tool to be used as needed. It's not something to be worshipped or guarded against change.
Title: Re: Conditional test statement/semicolon Hell!
Post by: 440bx on March 26, 2020, 10:49:10 am
I wish the Free Pascal developers would require the semicolon at the end of all statements, or none. Like it is, I don't think FP could be used in a high-production office setting.
A lot of Pascal compilers "tolerate" semicolons where there aren't supposed to be any. 

Neither "end" nor "else" are statements (or begin a statement), therefore there should not be a semicolon before them.  In the case of "end" the compiler has been "trained" to tolerate them but, in the case of "else" allowing a semicolon would change the semantics, therefore that's a no-go.

You'll get used to semicolons soon enough. 

A rare but, much more annoying problem with Pascal's design is the use of "begin"/"end"  to mark the beginning and end of function/procedure blocks while also using them as compound statement "delimiters".   Combine that with the fact that functions and procedures can be nested and that opens the door to some really annoying problems.  For instance
Code: Pascal  [Select][+][-]
  1.   program FunWithBeginEnd;
  2.  
  3.     procedure ProcedureName;
  4.  
  5.       procedure AnotherProcedure;     { procedure has no blockbody       }
  6.  
  7.     begin       { Top to bottom associates with AnotherProcedure, bottom }
  8.     end;        { to top, associates with ProcedureName.                 }
  9.  
  10.   begin
  11.     begin
  12.     end;
  13.   end.
  14.  
When there aren't hundreds of lines of code in the way, it's easy to see the problem but, in a large program it's a different thing.  A much more common problem is the "extra" begin or the "missing" end.   The compiler gets to the very bottom of the source and "informs" you that it expected a semicolon.  If you've made more than a few changes you can still remember then you're in for some fun.



Title: Re: Conditional test statement/semicolon Hell!
Post by: MarkMLl on March 26, 2020, 11:14:25 am
As part of the bigger picture, also that "classic" Pascal uses e.g.

Code: [Select]
if <condition> then
  <single statement>
else
  <single statement> ;

while newer features use e.g.

Code: [Select]
try
  <statement sequence>
finally
  <statement sequence>
end;

There is of course also the overloading of  try  which can herald both a  try-finally  or a  try-except  statement (I'd prefer  start-finally  as an alternative). And many other problems.

I agree that the language should be reworked, particularly since Wirth admitted Pascal's flaws by eliminating some of them in Modula-2. Ain't gonna happen.

MarkMLl
Title: Re: Conditional test statement/semicolon Hell!
Post by: marcov on March 26, 2020, 11:57:49 am
@MarkMLI

Quote
...but there's limits as to what can be done without breaking the language.

Actually, no, there's not. Just as spoken languages are allowed to evolve, so are programming languages.

That's because humans are more forgivving about little changes than machines. Unfortunately this does not work.

Quote
Programming languages/environments are tools meant to serve the programmer - nothing more.  They certainly are not holy relics.  Implementing the option to terminate each statement with a semicolon (I stress the word "option", as it would not be a requirement) would certainly not "break" the language.

Before the ELSE, the semicolon or not has meaning. Search for the already mentioned phrase "dangling else"

Title: Re: Conditional test statement/semicolon Hell!
Post by: Handoko on March 26, 2020, 12:23:06 pm
I do not against FP/Pascal to evolve for better, but I never have problem with conditional test statement.

One thing for sure is, I always avoid deeply nested if block. And I sometimes combine if block with case statement. That works for me.
Title: Re: Conditional test statement/semicolon Hell!
Post by: MarkMLl on March 26, 2020, 12:38:43 pm
I for one agree with the OP that this is something that could usefully be fixed. Unfortunately, in common with just about everybody else who complains about this, I get the impression that he fails to understand that a subtle fix along the lines of "let's accept an optional  ;  at this point in the syntax" would break things, and as such it's not going to happen.

Far better would be a per-unit switch to always insisting on an explicit  end  to all statement sequences, it lacks the elegance of Pascal's "this applies to a <single statement>, which might be a <compound statement>" syntax rule, but it would be sufficiently blatant that it would be difficult to get confused (this is the form used by ALGOL-68, Modula-2, Ada etc.). There would be the downside that it would be incompatible with ALGOL-60's inline conditional, but since Pascal (unfortunately) doesn't support that...

MarkMLl
Title: Re: Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 26, 2020, 01:33:38 pm
A simple If block - no big deal. But for nested If blocks... kinda makes me want to seriously rethink learning this language. Could there possibly be a more flawed and headache inducing language feature?

(Deeply) nested IF blocks (no matter of where semicolons are allowed or forbidden) are always messy. In any language.

Some language have mandatory "blocks" around the conditional code. Like "then ... ENDIF", if ... fi (reverse if), or "{}".
Pascal offers begin end, just not mandatory.

Still even with blocks, in any language deeply nesting "if" gets messy.
Indent can help. But very few language have a mandatory indent.


In Pascal, if you place a semicolon incorrectly before a "else" you get an error (except if you are nested in a "case", and the case block has no begin/end).

The only danger is that you place a semicolon immediately after then or else (but see further down, for highlighting such error)
Code: Pascal  [Select][+][-]
  1. if a= b then ;
  2.    DoEqual;  // unconditional, because the line above had an empty statement for the conditional code.

But then, other languages that do not have mandatory blocks, will in most cases behave exactly like that.



Writing readable if/then code is not so much about what tokens are mandatory. Writing in a language with mandatory {}, still allows the programmer to write messy code.
Code: C  [Select][+][-]
  1. if (foo)
  2. { if (bar) { a=1;
  3. c=a; }
  4. else
  5. { b=1;
  6. }}

Design your code to avoid deeply nested if.

And where that fails, use an editor (such as the Lazarus IDE} that has plenty of highlighting to show you were each if/else ends.
At least if you write each statement on a new line, and keep some indent.

- You get vertical colored lines. (see image) / Also nested "if" has a different color. And ";" are marked, if they belong to (the end) of an if/else
- You can add color for common errors (my IDE is set to mark certain errors in red, see image)

To get the error, go to "user defined markup) https://wiki.lazarus.freepascal.org/IDE_Window:_Editor_User_Defined_Words
And add terms like "then;" and "then ;" / "then  ;" with a color of your choice.
Title: Re: Conditional test statement/semicolon Hell!
Post by: Handoko on March 26, 2020, 01:54:33 pm
... danger is that you place a semicolon immediately after then or else ...

The line above is very important especially for newbies, can someone please add it to the documentation or wiki page?
https://www.freepascal.org/docs-html/3.0.0/ref/refsu58.html (https://www.freepascal.org/docs-html/3.0.0/ref/refsu58.html)

And/or a warning message (on the Messages window), if the IDE detect such the thing on compile time.
Title: Re: Conditional test statement/semicolon Hell!
Post by: 440bx on March 26, 2020, 02:03:18 pm
Writing readable if/then code is not so much about what tokens are mandatory. Writing in a language with mandatory {}, still allows the programmer to write messy code.
Code: C  [Select][+][-]
  1. if (foo)
  2. { if (bar) { a=1;
  3. c=a; }
  4. else
  5. { b=1;
  6. }}
Particularly when the "{" and "}" also define a new scope (as they do in C which is what allows for inline variable declarations)

Design your code to avoid deeply nested if.
That's very good advice.  Nested if(s) are logically prone to errors, hard to read and, hard to maintain. 

Pascal isn't perfect but, it is truly a superbly well designed language. 

That said, it would have been nice if the semicolon had been a statement terminator instead of a separator.  As far as when they are needed, statement terminators are more predictable than separators.  The combination of semicolon as a statement separator and allowing the empty statement to be nothing but a space can definitely be a source of confusion for Pascal newcomers.

Title: Re: Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 26, 2020, 02:22:19 pm
... danger is that you place a semicolon immediately after then or else ...

The line above is very important especially for newbies, can someone please add it to the documentation or wiki page?
https://www.freepascal.org/docs-html/3.0.0/ref/refsu58.html (https://www.freepascal.org/docs-html/3.0.0/ref/refsu58.html)

And/or a warning message (on the Messages window), if the IDE detect such the thing on compile time.
The doc, is from the fpc doc. If you feel strongly about it, mention it on the fpc mail list. (to find out, if you should file a issue report)

The IDE does not detect such semicolon. After all that is valid code. I frequently have stuff like
Code: Pascal  [Select][+][-]
  1. if cond then
  2.   ; // do nothing yet
Of course, the semicolon on the next line - with a comment that there is an empty statement (a todo) - is much easier to spot.

The semicolon on the same line happens (often a left over from code completion). Unfortunately there is no dedicated build in detection. The only way is the user defined markup.
Title: Re: Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 26, 2020, 02:27:59 pm
That said, it would have been nice if the semicolon had been a statement terminator instead of a separator.  As far as when they are needed, statement terminators are more predictable than separators.  The combination of semicolon as a statement separator and allowing the empty statement to be nothing but a space can definitely be a source of confusion for Pascal newcomers.

Not sure that would make a different in the if/else case.

Afaik, the entire "if ... then ... else ...;" is one statement. Otherwise there would have to be statement-separators.
But if it is one statement, then it also would not be allowed to have any statement terminator in it.

So either way (separator or terminator), a if/else would not have any semicolon.

For all else, you can (and many do) have the semicolon in (almost?) all places where a terminator would go. You just are not forced to do that.

"statement; end" => that semicolon is not needed, it creates an empty statement. (That would be different if it were a terminator). But you can have that semicolon.
Title: Re: Conditional test statement/semicolon Hell!
Post by: 440bx on March 26, 2020, 02:54:51 pm
Not sure that would make a different in the if/else case.
...
So either way (separator or terminator), a if/else would not have any semicolon.
It does make a difference.  The difference is that, while Pascal will not accept a semicolon after the "then" condition when it is followed by "else", C will require it.  For instance, in C:
Code: C  [Select][+][-]
  1. if (a == b) ; else printf("a <> b");
the semicolon terminates the empty statement.

In Pascal, the compiler will be unhappy with:
Code: Pascal  [Select][+][-]
  1. if a = b then ; else writeln('a <> b');
because since neither "then" nor "else" are statements, they are not supposed to be separated by a statement separator and the empty statement (unlike in C) does not need to be terminated (since statement terminators don't exist in Pascal.)

Title: Re: Conditional test statement/semicolon Hell!
Post by: ASBzone on March 26, 2020, 03:49:53 pm
That's because humans are more forgivving about little changes than machines. Unfortunately this does not work.

Some humans.  Have you seen grammar nazis at work on some forums?

Besides, most people forget that it often takes language decades to hundreds of years to change to a point where enough people accept the change.

I have often thought that it would be nice to invoke a mode in FPC that allows language refinements that have been discussed on occasion (such as each block type having its own end, without a superfluous begin, etc), but I recognize that these would not be trivial changes, and -- even optional -- would not result in much benefit in the near term.

So I sit quietly, smile and nod at some of the discussions about language enhancements...  ::)
Title: Re: Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 26, 2020, 04:34:10 pm
For instance, in C:
Code: C  [Select][+][-]
  1. if (a == b) ; else printf("a <> b");
the semicolon terminates the empty statement.
Does it though? Or does it terminate the "if" statement, making the "else" a separate statement?

I do not know how other language define "if then else" in terms of "statement".
But FPC does document it is one single statement: https://www.freepascal.org/docs-html/current/ref/refsu57.html#x163-18500013.2.3

Now of course "begin end" is a single (combined) statement. And "begin end" can have semicolons inside. But then "begin end" has its own terminator "end" (after which there may or may not be a semicolon)

"If then else" has no such dedicated "end". It ends like any other statement, and may then be separated from the next statement, if there is a next statement.

The "else" is however part of the same statement. The "if then" can not be separated from the else. Equally the "if then" can not be terminated, if an "else" should follow.

So even if ";" was a terminator in Pascal, using it in the middle of "if then ; else" would terminate the "if" statement, and after that there could not be an "else".

To use the semicolon in that way "if then ; else", the definition of the "if then else" as a statement would need to be changed.



But on that note: Yes, if the definition of "if then else" was changed accordingly, it would also need the change of ";" to terminator, as otherwise "if then ; else" would mean that there are 2 statement in the "then" part, which (without begin/end) is not allowed either.
But since "if then else" is as it is, that does not currently matter.
Title: Re: Conditional test statement/semicolon Hell!
Post by: 440bx on March 26, 2020, 05:28:00 pm
For instance, in C:
Code: C  [Select][+][-]
  1. if (a == b) ; else printf("a <> b");
the semicolon terminates the empty statement.
Does it though? Or does it terminate the "if" statement, making the "else" a separate statement?
The semicolon terminates the inner empty statement, not the if statement.  "else" by itself isn't a statement, it must be matched to the "if" that owns it.   If the "else" part was by itself (a separate statement) the C compiler would complain about it.
Title: Re: Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 26, 2020, 05:45:15 pm
The semicolon terminates the inner empty statement, not the if statement.  "else" by itself isn't a statement, it must be matched to the "if" that owns it.   If the "else" part was by itself (a separate statement) the C compiler would complain about it.
As I said, I have not gone through the formal C definition to check what terminology is used, and how this is actually defined...

But, what then is the "if"? A statement? If it is a statement, then where/how is it terminated? You say the ";" terminates "the inner statement, but not the if". Should there be a 2nd ";" to terminate the "if"?  I know there isn't, but why?

It seems that in C it also depends on how the "if" and "else" are defined. And (not so much) on that the ";" is a terminator, rather than a separator.

If in Pascal, the "else" was changed to start a new statement, then a separator would go into that place....



Title: Re: Conditional test statement/semicolon Hell!
Post by: madref on March 26, 2020, 05:49:57 pm
Code: Pascal  [Select][+][-]
  1. if a = b then ; else writeln('a <> b');
I always find this so stupid and it takes more time to compile.
Sometimes it's much easier to write what you what to check
Code: Pascal  [Select][+][-]
  1. If a <> b then written ('a <>b');


And it's way sexier
Title: Re: Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 26, 2020, 05:57:18 pm
Just a note, this started off with:
That said, it would have been nice if the semicolon had been a statement terminator instead of a separator.  As far as when they are needed, statement terminators are more predictable than separators.  The combination of semicolon as a statement separator and allowing the empty statement to be nothing but a space can definitely be a source of confusion for Pascal newcomers.

And there are several issues in there that can become subject of discussions.

The part, my response is tailored too, is that the potentially "if/then" related "source of confusion for Pascal newcomers" is the difference between terminator and separator.

However, as far as I am concerned, the different use of the ";" in the if/then context, is based on how the "if/then" is defined. Depending on that definition a ";" after the "then" (sub-) statement would occur (even if it was a separator).

If the "else" was a new statement, then a separator would be needed.

The semicolon terminates the inner empty statement, not the if statement. 
If that is correct, then in C there are 2 nested statements open, only one of them gets ever closed. That would be a very curious definition.
Title: Re: Conditional test statement/semicolon Hell!
Post by: MarkMLl on March 26, 2020, 06:01:35 pm
Does it though? Or does it terminate the "if" statement, making the "else" a separate statement?

I do not know how other language define "if then else" in terms of "statement".

In some cases by treating  if  as a prefix operator that evaluates a boolean, and  then  and  else  as prefix predicates that execute a statement block.

The elegance of the ALGOL-60/Pascal way is difficult to beat, but unfortunately the "dangling else" issue is a sufficient pain in the arse as far as pragmatics are concerned to make the ALGOL-68/Modula-2/Ada way superior- in my opinion at least.

MarkMLl
Title: Re: Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 26, 2020, 06:11:55 pm
Does it though? Or does it terminate the "if" statement, making the "else" a separate statement?

I do not know how other language define "if then else" in terms of "statement".

In some cases by treating  if  as a prefix operator that evaluates a boolean, and  then  and  else  as prefix predicates that execute a statement block.

Thanks, that would be very much in line, that the ";" after the "then statement" is not primarily a result of the separator/terminator definition, but it is a consequence of how "if then" is defined.

Though as I written, if hypothetically such a change was to be introduced in Pascal, depending on how that definition would be changed, in addition to that change it may be (or may not be) necessary to also switch to terminator (but only as a 2ndary issue).


If in Pascal the "else" was a prefix, and would not separate the "else statement" (including the "else" itself) from the "then statement", then after the "then statement" a separator ";" would be needed before the "prefixed else statement" could begin.
Title: Re: Conditional test statement/semicolon Hell!
Post by: 440bx on March 26, 2020, 06:31:09 pm
Code: Pascal  [Select][+][-]
  1. if a = b then ; else writeln('a <> b');
I always find this so stupid and it takes more time to compile.
Sometimes it's much easier to write what you what to check
Code: Pascal  [Select][+][-]
  1. If a <> b then written ('a <>b');
It was just a very handy example.  I agree that the second form is usually preferable.  That said, there are times when the logical expression is quite complex (something that should be avoided) and it is simpler to have if <expression> then else < statement>; instead of having to add another pair of parenthesis around the expression for a "not" to be placed in front of it.



that the ";" after the "then statement" is not primarily a result of the separator/terminator definition, but it is a consequence of how "if then" is defined.
Yes, it is because the empty statement must be terminated.  In Pascal no separator is needed because the empty statement is by itself therefore doesn't need to be separated from anything.  The difference between terminator and separator is the reason C requires it while Pascal will complain about it.

As far as "requiring two semicolons", the reason that isn't necessary is because the compiler sees "if statement else statement".  It sees only _one_ statement.   If it saw more than one statement then it would require "{" and "}" and note that there is no semicolon required after  the closing "}".  The compiler knows that the "}" marks the end of the compound statement.

Title: Re: Conditional test statement/semicolon Hell!
Post by: MarkMLl on March 26, 2020, 07:07:14 pm
If in Pascal the "else" was a prefix, and would not separate the "else statement" (including the "else" itself) from the "then statement", then after the "then statement" a separator ";" would be needed before the "prefixed else statement" could begin.

But at the same time there's the problem of working out when the boolean (presumably on the evaluation stack) can be discarded since it is no longer needed by a predicate associated with its evaluator.

I'm currently trying to write a lexer for (an enhancement of) Smalltalk-style keywords/selectors. Doing things in such a way that they're useful without breaking existing features is very much on my mind.

MarkMLl
Title: Re: Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 26, 2020, 08:18:49 pm
that the ";" after the "then statement" is not primarily a result of the separator/terminator definition, but it is a consequence of how "if then" is defined.
Yes, it is because the empty statement must be terminated.  In Pascal no separator is needed because the empty statement is by itself therefore doesn't need to be separated from anything.  The difference between terminator and separator is the reason C requires it while Pascal will complain about it.
But for Pascal, that only becomes relevant, if the definition of "if then else" changes.

Currently, if I read the documentation correctly, "if then else" is one statement. Therefore it can

Currently (in Pascal) it is a statement. If you but a terminator in there, then terminate it (it is in the word). For that to work, it would need to be like "begin end".

And that much I said several times: IF the definition of "if then else" is changed, then the separator/terminator distinction may become relevant. Or it may not. That depends how it is changed.
But likely it would need the subsequent change from separator to terminator, if and once the primary issue in the definition was changed. So in some way, you are right, but only if you assume other changed to implicitly having been made before.

With the current definition of "if then else" you can not put a separator in there (we agree, I believe) because only one statement is allowed in each of then/else, but a separator would make it more than one.

But with the current definition of "if then else" you can also not put a terminator in there, because it would terminate the "if then" itself.

If you do see the statement after the "then" as a nested statement, and ";" was a terminator, then there would be a need for a 2nd terminator of the outer "if". Or you need additional rules/definitions.
Title: Re: Conditional test statement/semicolon Hell!
Post by: 440bx on March 26, 2020, 08:56:05 pm
But for Pascal, that only becomes relevant, if the definition of "if then else" changes.

Currently, if I read the documentation correctly, "if then else" is one statement. Therefore it can

Currently (in Pascal) it is a statement. If you but a terminator in there, then terminate it (it is in the word). For that to work, it would need to be like "begin end".
I am not completely sure I have understood what you're saying but, the thing about terminators and separators doesn't just affect the "if/then/else" statement, it affects the entire grammar.

In C, which uses terminators, no ";" is necessary after a close brace "}" because the close brace terminates a compound statement.  This is unlike in Pascal where "end" terminates a compound statement BUT, it is _not_ a statement separator.

For instance, the following will not compile
Code: Pascal  [Select][+][-]
  1. program TestSeparators;
  2.  
  3. var
  4.   a : integer = 1;
  5.   b : integer = 2;
  6.  
  7. begin
  8.   begin
  9.     a := 3; { superfluous semicolon ";" }
  10.   end       { <--- missing ";" statement separator }
  11.  
  12.   b := 5;
  13. end.
The equivalent code in C compiles fine because "}" is a terminator and that's all that's needed between statements.
Title: Re: Conditional test statement/semicolon Hell!
Post by: GypsyPrince on March 26, 2020, 08:58:13 pm
So... using some advice from Thaddius about 4 years ago, I tinkered a little bit and cam up with a solution that works great for me - no one else is likely to use it themselves.

Conventional method:
Code: Pascal  [Select][+][-]
  1. If IsNew = True Then //If the feature is new...
  2.     Begin
  3.         Case Locale Of //Determine the sending application's locale and let User know this feature is not yet available...
  4.             LOC_ENUS : Application.MessageBox(m_FTR_ENG_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1033 - English (U.S.A.)...
  5.             LOC_ESES : Application.MessageBox(m_FTR_ESP_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1034 - Spanish (Spain)...
  6.             Else       Application.MessageBox(m_FTR_ENG_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //Any other locale...
  7.         End;
  8.     End  
  9. Else //If the feature is old but is incomplete...
  10.     Begin
  11.         Case Locale Of //Determine the sending application's locale and let User know this feature is not yet available...
  12.             LOC_ENUS : Application.MessageBox(m_FTR_ENG_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1033 - English (U.S.A.)...
  13.             LOC_ESES : Application.MessageBox(m_FTR_ESP_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1034 - Spanish (Spain)...
  14.             Else       Application.MessageBox(m_FTR_ENG_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //Any other locale...
  15.         End;
  16.     End;

I added some "alias" macros, the restructured the code a bit as follows:

My method:
Code: Pascal  [Select][+][-]
  1. {$macro on}{$Define EndProcedure:=end}{$Define EndFunction:=end}{$Define EndTry:=end}{$Define EndIf:=end}{$Define EndSelect:=end}
  2.  
  3. If IsNew = True Then Begin //If the feature is new...
  4.     Case Locale Of //Determine the sending application's locale and let User know this feature is not yet available...
  5.         LOC_ENUS : Application.MessageBox(m_FTR_ENG_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1033 - English (U.S.A.)...
  6.         LOC_ESES : Application.MessageBox(m_FTR_ESP_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1034 - Spanish (Spain)...
  7.         Else       Application.MessageBox(m_FTR_ENG_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //Any other locale...
  8.     EndSelect;
  9.  End Else Begin //If the feature is old but is incomplete...
  10.     Case Locale Of //Determine the sending application's locale and let User know this feature is not yet available...
  11.         LOC_ENUS : Application.MessageBox(m_FTR_ENG_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1033 - English (U.S.A.)...
  12.         LOC_ESES : Application.MessageBox(m_FTR_ESP_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1034 - Spanish (Spain)...
  13.         Else       Application.MessageBox(m_FTR_ENG_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //Any other locale...
  14.     EndSelect;
  15. EndIf;

Notice
a. the "Begin" keyword for the first condition moved up and to the end of the "If" statement.
b. the non-terminated "End" for the first condition moved down and in front of the "Else" keyword.
c. the "Begin" keyword for the second/Else condition moved up and following the "Else" keyword.
d. the terminated "End" keyword for the second condition replaced with the alias "EndIf".
e. the terminated "End" keyword for the Case selection block replaced with the alias "EndSelect".

Unfortunately, existing keywords cannot be replaced with aliases. Otherwise, I could replace "Then Begin" with just "Then", and replace "End Else Begin" with just "Else" (or ElseIf) and viola... you have Visual Basic.

Like I said, most folks will not want to use this. But it works great for me.
Title: Re: Conditional test statement/semicolon Hell!
Post by: bytebites on March 26, 2020, 09:06:21 pm
Conventional method is not to use
Code: Pascal  [Select][+][-]
  1. If IsNew = True Then
but
Code: Pascal  [Select][+][-]
  1. If IsNew Then

I like this compact formatting style
Code: Pascal  [Select][+][-]
  1. If IsNew Then Begin
  2.  
  3. End Else Begin
  4.  
  5. End;
Title: Re: Conditional test statement/semicolon Hell!
Post by: GypsyPrince on March 26, 2020, 09:11:33 pm
@bytebites

Actually, that was just a quick mock-up, and will be reversed. I always test for False instead of True because False is always equal to zero whereas True is not always equal to the same value...
Title: Re: Conditional test statement/semicolon Hell!
Post by: 440bx on March 26, 2020, 09:14:04 pm
Code: Pascal  [Select][+][-]
  1. If IsNew Then Begin
  2.  
  3. End Else Begin
  4.  
  5. End;
It seems that a fair number of people like that "style" in spite of the fact that it is incorrect and makes the code less maintainable.

That "style" was discussed ad nauseam in the thread https://forum.lazarus.freepascal.org/index.php/topic,46163.0.html
Title: Re: Conditional test statement/semicolon Hell!
Post by: bytebites on March 26, 2020, 09:26:44 pm
You don't need any reason to that "fact".  :P
Title: Re: Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 26, 2020, 09:27:08 pm
I am not completely sure I have understood what you're saying but, the thing about terminators and separators doesn't just affect the "if/then/else" statement, it affects the entire grammar.
Yes there are plenty of differences caused by the difference between terminator and separator.

Not been talking about them, I tried to make this clear:
The part, my response is tailored too, is that the potentially "if/then" related "source of confusion for Pascal newcomers" is the difference between terminator and separator.

This thread was about the if/then stuff. I only state:
- The absence of a ";" for
   - an empty statement (or even after a none empty statement)
   - between "then" and "else" of an "if"

- This absence is not (or at least not only; and in my opinion: not primarily) due to the terminator/separator difference.

- This absence is first/before caused by the definition of "if then else" being a statement (see the fpc docs)

Both (a terminator or separator) would break the "one statement" definition of the "if then else".


Yes, you could allow terminators for sub-statement within the overall "if then else" statement.
But you also need to drop the requirement that "if then else" has a terminator of its own, or it will be "if a then b; else c; ;" (2 final terminators).

But (in a scenario with stmt terminators) a statement should have a terminator. If not, would it still be a statement? So by those changes the definition of "if then else" as a statement would have been voided.

And hence, before the terminator/separator difference matters (in this one and specific context), other definitions must be changed first.



 
Title: Re: Conditional test statement/semicolon Hell!
Post by: Otto on March 26, 2020, 10:46:41 pm
Hello everyone.

[...] Using beginend pairs is definitely a valid solution to avoid the potential pitfalls there... [...]

Recently I worked on the conversion and improvement of some programs written in pascal-like languages that, however, required the << begin ... end >> construct.
To resolve the validation issue, I used the "Jedi Code Formatter" as I described in this post #37 (https://forum.lazarus.freepascal.org/index.php/topic,48642.msg351464.html#msg351464).
Of course this would only be a practical solution, but it could be useful to someone.

Otto.
Title: Re: Conditional test statement/semicolon Hell!
Post by: MarkMLl on March 26, 2020, 10:54:13 pm
It seems that a fair number of people like that "style" in spite of the fact that it is incorrect and makes the code less maintainable.

That "style" was discussed ad nauseam in the thread https://forum.lazarus.freepascal.org/index.php/topic,46163.0.html

By definition, there's no such thing as an "incorrect style" unless you're talking about something like Python or some of the early PCs which mandated a particular layout of BASIC sourcecode.

There's "inconsistent style", there's "styles best avoided because they're widely agreed to be illegible", and there's "styles that are mandated for this particular project". But I'd quite happily bet that even the most outlandish layout would make perfect sense when applied to one particular algorithm or data definition.

MarkMLl
Title: Re: Conditional test statement/semicolon Hell!
Post by: madref on March 26, 2020, 10:55:11 pm
Why not use the principles of good old Modula-2.
It has only 1 begin and 1 end at every function or procedure.


Much easier
Title: Re: Conditional test statement/semicolon Hell!
Post by: MarkMLl on March 26, 2020, 11:06:11 pm
Why not use the principles of good old Modula-2.
It has only 1 begin and 1 end at every function or procedure.

Much easier

Remember that there's also an  end  at the completion of an  if  statement (also while, loop and a few others).

I agree, particularly since modern Pascal is half way there already with the  try  statements. But it would have to be on a per-unit basis, i.e. a complete switch of syntax rather than trying to compromise the existing Pascal syntax.

MarkMLl
Title: Re: Conditional test statement/semicolon Hell!
Post by: ASerge on March 27, 2020, 12:15:10 am
For instance, in C:
Code: C  [Select][+][-]
  1. if (a == b) ; else printf("a <> b");
the semicolon terminates the empty statement.
From the point of view of a person who writes in Pascal, this is terrible code. It is already worth ';', the expression has ended and suddenly some "else". It's a mess.
Title: Re: Conditional test statement/semicolon Hell!
Post by: 440bx on March 27, 2020, 12:53:47 am
By definition, there's no such thing as an "incorrect style" unless you're talking about something like Python ...
There is incorrect style, even in Pascal.  Any "style" that visually violates the structure of the language's grammar is inherently incorrect.  In the case of Pascal and, by having the "begin" on the same line as an "else" (for instance) is often used to align the "end;" with the statement that owns the compound statement, thereby giving the impression that the owning statement is terminated with "end" when in reality it is not.

In addition to that, that "style" creates a textual structure that obfuscates the true logic of the statement making it harder to maintain and, in addition to that, causes problems when it comes to creating test cases for rare conditions.

I know some programmers are very protective of their "style" in spite of the fact that it is inherently incorrect and logically poor.


From the point of view of a person who writes in Pascal, this is terrible code. It is already worth ';', the expression has ended and suddenly some "else". It's a mess.
I agree.  I posted that code as a simple example of the difference between a separator and a terminator.  The only times I think that construction is justified is when the expression is already very complicated and adding more parentheses and a "not" in front of it would make it even more complicated.  In those rare cases, I think that construction is justified.


@Martin

Could you provide an example of how you'd modify the "if/then/else" statement where it would no longer matter whether a ";" is a terminator instead of a separator ?

Title: Re: Conditional test statement/semicolon Hell!
Post by: ASerge on March 27, 2020, 01:43:38 am
From the point of view of a person who writes in Pascal, this is terrible code. It is already worth ';', the expression has ended and suddenly some "else". It's a mess.
I agree.  I posted that code as a simple example of the difference between a separator and a terminator.  The only times I think that construction is justified is when the expression is already very complicated and adding more parentheses and a "not" in front of it would make it even more complicated.  In those rare cases, I think that construction is justified.
I was talking about an extra ";", not about margins and alignment.
Title: Re: Conditional test statement/semicolon Hell!
Post by: 440bx on March 27, 2020, 03:02:54 am
I was talking about an extra ";", not about margins and alignment.
I wasn't talking about margins and alignment either.  As far as the extra ";", that's what a language that uses statement terminators requires.  While I see your point that it looks messy.  To me "if <expression> then else <statement>  feels contradictory because of the "then else" with nothing in between. At least having a semicolon in between gives a visual indication of the existence of an empty statement.

Personally, regardless of separators and terminators, I feel there should be a statement to denote "no operation" such as "nop" or "noop".  It makes it explicit and hard to miss.  I don't like _implied_ empty statements using a space as in Pascal or a semicolon as in C.


Title: Re: Conditional test statement/semicolon Hell!
Post by: PascalDragon on March 27, 2020, 09:37:47 am
I have often thought that it would be nice to invoke a mode in FPC that allows language refinements that have been discussed on occasion (such as each block type having its own end, without a superfluous begin, etc), but I recognize that these would not be trivial changes, and -- even optional -- would not result in much benefit in the near term.

Such a mode would have to be maintained and it makes the parser more complicated with the gain being really questionable. This gets a definite No from me.
Title: Re: [SOLVED] Conditional test statement/semicolon Hell!
Post by: GypsyPrince on March 27, 2020, 05:44:53 pm
@PascalDragon

Here is a small thesis...

What I wound up doing is adding these macros:

Code: Pascal  [Select][+][-]
  1. {$macro on}{$Define EndProcedure:=end}{$Define EndFunction:=end}{$Define EndTry:=end}{$Define EndSelect:=end}{$Define EndIf:=end}
  2.  
  3. If IsNew = False Then Begin //If the feature is old but is incomplete...
  4.     Case Locale Of //Determine the sending application's locale and let User know this feature is not yet available...
  5.         LOC_ENUS : Application.MessageBox(m_BAD_ENG_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1033 - English (U.S.A.)...
  6.         LOC_ESES : Application.MessageBox(m_BAD_ESP_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1034 - Spanish (Spain)...
  7.         Else       Application.MessageBox(m_BAD_ENG_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //Any other locale...
  8.     EndSelect;
  9. End Else Begin //If the feature is new...
  10.     Case Locale Of //Determine the sending application's locale and let User know this feature is not yet available...
  11.         LOC_ENUS : Application.MessageBox(m_BAD_ENG_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1033 - English (U.S.A.)...
  12.         LOC_ESES : Application.MessageBox(m_BAD_ESP_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1034 - Spanish (Spain)...
  13.         Else       Application.MessageBox(m_BAD_ENG_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //Any other locale...
  14.     EndSelect;
  15. EndIf;

which is actually the same as...

Code: Pascal  [Select][+][-]
  1. If IsNew = False Then //If the feature is old but is incomplete...
  2.     Begin    
  3.         Case Locale Of //Determine the sending application's locale and let User know this feature is not yet available...
  4.             LOC_ENUS : Application.MessageBox(m_BAD_ENG_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1033 - English (U.S.A.)...
  5.             LOC_ESES : Application.MessageBox(m_BAD_ESP_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1034 - Spanish (Spain)...
  6.             Else       Application.MessageBox(m_BAD_ENG_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //Any other locale...
  7.         End;
  8.     End
  9. Else //If the feature is new...
  10.     Begin
  11.         Case Locale Of //Determine the sending application's locale and let User know this feature is not yet available...
  12.             LOC_ENUS : Application.MessageBox(m_BAD_ENG_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1033 - English (U.S.A.)...
  13.             LOC_ESES : Application.MessageBox(m_BAD_ESP_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1034 - Spanish (Spain)...
  14.             Else       Application.MessageBox(m_BAD_ENG_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //Any other locale...
  15.         End;
  16. End;

By doing it this way (top example), no changes need to be made to the language itself and all the purists are still happy.  The compiler simply replaces EndIf, EndSelect, EndTry, etc. with the proper "End" keyword and all is perfect.
 
"...all the purists are still happy." - this part I'll never understand because everything I propose is always just an option and doesn't require the user to veer away from their current method of doing things.  But, oh well, some folks just want to whine when you introduce any type of change, even when it doesn't affect them AT ALL, and especially when they are not the developer(s) of the Lazarus program.  I roll on the floor laughing my rear-end off every time I see someone respond about how difficult it would be for the developers to implement this or that feature, or that it would break the language.  When I do see such responses I can't even begin to take the person seriously as a programmer.  If the actual developers of Lazarus reply with that, then it holds authority.  But when someone who isn't involved in the development replies with such things then, well... I can only view them as an "armchair quarterback".  The current structure (visual) of Object Pascal syntax is very confusing to newcomers, as it does not produce a logical/cognitive flow, which is what the brains of new learners want to see.  Logical visual patterns make things easier to learn and retain.  With Microsoft transitioning Windows to a cloud-based service and their deciding to no longer evolve the Visual Basic language or system, the Object Pascal language (Lazarus/Delphi) has a chance to exploded in its user base by attracting former VB programmers (and former assembly/C/C++ programmers like myself) and those who want to stick with desktop development.  As a side note, I am a mechanical/aerospace engineer that also does programming, especially embedded database systems.  There are several industries like mine (defense) where cloud/mobile computing IS NOT AND NEVER WILL BE an option because of security issues and because mobile devices and cloud systems do not have the power to run the processor-intensive engineering/analytics software we use.  So, contrary to popular and misguided pundit opinion, neither desktop systems nor desktop development will ever die.  Object Pascal has the chance to explode in that realm if it were to make just a few minor tweaks and become more syntactically friendly to new users.  I've seen posts by others in this forum who say this or that is what helps new users learn and blah - blah - blah, and that syntactic sugar supposedly doesn't help people learn.  Wrong!  Absolutely wrong!  The mind of "most" users requires the use of logical visual patterns which are both aesthetically pleasing and establish a sense of familiarity in order to learn.  This is the reason for my tinkering with these macros to, some extent, mimic Microsoft's Visual Basic (.NET) which may be the closest-to-perfect programming language ever developed.  As VB is so naturally close to the English human language and is fluid, it is easy to learn and retain.  Unfortunately, it is now bloated, runs via a virtual machine/CLR rather than compiling to true native code, is sluggish and slow because of the previously mentioned issues, and will no longer evolve as a language or development system.  Lazarus and Deplhi have a chance to replace it if the Pascal purists would stop living in an anal retentive bubble and adopt a few minor changes which would make it just a tiny bit more similar (and familiar) to VB.

Another option I tinkered with here is using {$Define EndIf:=//Placeholder} instead of {$Define EndIf:=end}.

Code: Pascal  [Select][+][-]
  1. If IsNew = False Then //If the feature is old but is incomplete...
  2.     Begin    
  3.         Case Locale Of //Determine the sending application's locale and let User know this feature is not yet available...
  4.             LOC_ENUS : Application.MessageBox(m_BAD_ENG_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1033 - English (U.S.A.)...
  5.             LOC_ESES : Application.MessageBox(m_BAD_ESP_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1034 - Spanish (Spain)...
  6.             Else       Application.MessageBox(m_BAD_ENG_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //Any other locale...
  7.         EndSelect;
  8.     End
  9. Else //If the feature is new...
  10.     Begin
  11.         Case Locale Of //Determine the sending application's locale and let User know this feature is not yet available...
  12.             LOC_ENUS : Application.MessageBox(m_BAD_ENG_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1033 - English (U.S.A.)...
  13.             LOC_ESES : Application.MessageBox(m_BAD_ESP_AVBL, PChar(AppName), MB_OK + MB_ICONINFORMATION); //1034 - Spanish (Spain)...
  14.             Else       Application.MessageBox(m_BAD_ENG_NCPT, PChar(AppName), MB_OK + MB_ICONINFORMATION); //Any other locale...
  15.         EndSelect;
  16.     End;
  17. EndIf;


In this last example, it is aesthetically pleasing to the eye in that it creates a logical visual block structure to reduce confusion.  The compiler replaces that "EndIf" with the comment //Placeholder.  After adding "EndIf" to the markup list (Options->Editor->Display->User defined markup->Main settings {tab}) and setting its color scheme to match "Reserved word" in the "Colors" option, it looks just like actual code but is merely a comment in disguise.
Title: Re: Conditional test statement/semicolon Hell!
Post by: ASerge on March 27, 2020, 06:32:05 pm
To me "if <expression> then else <statement>  feels contradictory because of the "then else" with nothing in between. At least having a semicolon in between gives a visual indication of the existence of an empty statement.
You think like a C programmer. For a Pascal programmer, the "if then else" operator is a single operator. The appearance of ";" indicates that there are already two operators, and the second begins with "else". This is a mess.
Title: Re: Conditional test statement/semicolon Hell!
Post by: Otto on March 27, 2020, 06:55:55 pm
You think like a C programmer. For a Pascal programmer, the "if then else" operator is a single operator. The appearance of ";" indicates that there are already two operators, and the second begins with "else". This is a mess.
I think that's the point of the matter.

I, as I imagine many others of you, use different programming languages at the same time; so I have to be particularly careful that the syntax I use is suitable for the kind of language I'm using at the time. It is a little like when you have to do translations between two natural languages (e.g. English and Latin); some grammatical structures that are "regular" in one language would be "irregular" in another.

Personally I believe that in pascal there are no major irregularities, but there is always room for improvements and introductions of new features.

Otto.
Title: Re: Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 27, 2020, 07:22:27 pm
@Martin
Could you provide an example of how you'd modify the "if/then/else" statement where it would no longer matter whether a ";" is a terminator instead of a separator ?

Well before I start, a good definition for "if then else" is not necessary easy to come by.

Also I am going to describe that in layman's terms. Absorb the idea, not the exact terminology.


To Start with: the current Pascal definition.
In the current Pascal definition (one statement), neither separator nor terminator is allowed. (So it does not matter what the ";" is)
SCNR


But for a definition were either is allowed. I do not say that this is a nice definition, or a good one. Only that such a definition exists.
(Actually if C is indeed interpreting "if..." as prefix (as was suggested), then this comes close.)

- Define "if then foo;" as one statement, and define "else foo;" as a 2nd statement.
You will either terminate both, or separate them.

That is kind of similar to C: "if then foo" is a statement with an "if then" prefix (according to an earlier post in this thread).
In the definition, the "if then" (as well as the "else") must be prefixes, which form a combined statement with "foo". Because (as in C) they have no statement terminator of their own. The terminator exists only for the combination of prefix and (then/else-)statement

Also in C, there is a statement terminator after the "if then foo" (potentially implicit in the "}"). Meaning that in some way, the "else" is a new statement (the previous has been terminated).

Or maybe C has a much more complex definition. Somehow they avoid the need to have a terminator for the overall "if then else". (There is no double ";;" )



On an absurd note:
If "if" etc, are prefixes, then maybe "if" and "then" should be 2 prefixed statements (terrible in human terms, but logically somewhat pleasing):
  IF a= b;
  THEN foo;
  ELSE bar;

On an even more absurd note:
there is no need for if then and else to be next to each other.

The "if" would set the test result.
The "then" and "else" would follow (in either order), at some later point, reacting to the last test result.

That could even have some interesting use cases. (One being to make the code harder to read)





Title: Re: Conditional test statement/semicolon Hell!
Post by: 440bx on March 27, 2020, 08:23:26 pm
You think like a C programmer. For a Pascal programmer, the "if then else" operator is a single operator. The appearance of ";" indicates that there are already two operators, and the second begins with "else". This is a mess.
Sometimes I think in C.  Most times I see Assembler as I code and, _many_ times, I think how much simpler the construction would be in COBOL.  Of all the languages, the one that has the most features I miss is, by far, COBOL.

As far as the "if then else" being a single operator, the construction "if then else <statement>" hurts my neurons. Why is there a "then" when the thing is _empty_ and worse, implicitly empty instead of explicitly.  It's like buying a suitcase and putting nothing in it.


@Martin

As far as C goes, the grammar is structured in such a way that there will always be a terminator, be it a ";" or a "}".  In the case of "if/else" the compiler knows (and enforces) that the "if" part contains a statement, since a statement is terminated with a ";", that semicolon, in the absence of an "else", terminates the "if" (the entire statement). if there is an "else" then the semicolon that terminates the "else" terminates the "if" because now the statement is complete.  When the programmer doesn't want the semicolon to terminate everything then he/she uses "{" and "}" and, in that case the last "}" terminates everything.  One way or another, there will always be a terminator that will terminate a statement whether "composite" such as "if/else" or "atomic" such as "a = 3;".



On an even more absurd note:
there is no need for if then and else to be next to each other.

The "if" would set the test result.
The "then" and "else" would follow (in either order), at some later point, reacting to the last test result.

That could even have some interesting use cases. (One being to make the code harder to read)
It's not unusual to see that in Assembly code, particularly optimized assembly code.  A CPU flag is set but tested a few instructions later that don't modify the flag previously set.

You're right, it does make following the code a bit harder than strictly sequential code.

Title: Re: [SOLVED] Conditional test statement/semicolon Hell!
Post by: MarkMLl on March 27, 2020, 08:37:11 pm
By doing it this way (top example), no changes need to be made to the language itself and all the purists are still happy.  The compiler simply replaces EndIf, EndSelect, EndTry, etc. with the proper "End" keyword and all is perfect.

I can assure you that the purists will /not/ be happy, because they reject the usefulness of macros and criticise them as "too C-like".

Now I'm really not getting into that one. But I would say that using non-standard constructs like that will give you real problems if you get stuck and ask the rest of the community for help with code that contains them: you'd be /far/ better advised to take on board the points being made by multiple people here- notably Martin and PascalDragon- and actually get used to the standard syntax.

I can further assure you that if you were in a C or C++ forum and tried dressing stuff up to look Pascal-like, you'd be getting even more stick.

MarkMLl
Title: Re: [SOLVED] Conditional test statement/semicolon Hell!
Post by: 440bx on March 27, 2020, 08:53:45 pm
I can assure you that the purists will /not/ be happy, because they reject the usefulness of macros and criticise them as "too C-like".
Preprocessor macros can occasionally be very useful but, they are more often abused than not.  C provides an almost infinite number of examples of preprocessor abuse.

The problem with preprocessors is, the code the programmer reads isn't the code that got compiled because before it got compiled, the code got chewed by the preprocessor.  It's like giving a large, badly tempered, dog a shoe and expecting to still have a shoe later. 
Title: Re: [SOLVED] Conditional test statement/semicolon Hell!
Post by: GypsyPrince on March 27, 2020, 08:56:21 pm
Quote
I can assure you that the purists will /not/ be happy, because they reject the usefulness of macros and criticise them as "too C-like".

I have little interest in the opinions of purists. I'll do my thing, they can do theirs.  If they choose to worship the language as a holy relic as opposed to experimenting and testing what all it can do, let them have at it.  Their bubble is not mine to tend...
Title: Re: Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 27, 2020, 09:44:13 pm
As far as C goes, the grammar is structured in such a way that there will always be a terminator, be it a ";" or a "}".
We where discussing the difference of an empty statement, in the "then" part being more visible in C, because there would be a ; terminator.

I did so far made my arguments for the case that does NOT have a {} or begin/end.

With {} or Begin/end it is slightly different. "{}" does not contain an empty statement. It is an empty list of statements. "begin end", well good question, I need to research if it contains one empty statement.

But in case there is neither {}, nor begin/end, then you were saying (in diff words) that C was "nicer" because the empty statement would be more visible due to its ; terminator.

And (as I understood your post) that ; was present in C, but not Pascal due to the difference between a terminator and a separator.

I did state, that the none presence of the ; (between then and else) in Pascal was based on the fact that "if then else" is one statement (according to the docs), and not (or not yet/primarily) due to the separator/terminator difference.

- That last sentence (in the described context) is all I am upholding.
- I am not making any comment, on anything else.

Quote
In the case of "if/else" the compiler knows (and enforces) that the "if" part contains a statement, since a statement is terminated with a ";", that semicolon, in the absence of an "else", terminates the "if" (the entire statement). if there is an "else" then the semicolon that terminates the "else" terminates the "if" because now the statement is complete.
So this is a really complex rule. And the compiler needs to look ahead (check for an else) to decide if the "if then" is terminated by the semicolon or not.

Anyway, as I said, when it comes to the formal definition of the syntax of an "if" in C, I do not have that info, and relied solely on posts inside this thread, as well on "reverse interpreting" the resulting c code into a possible/potential definition.

Also it was not at any time my goal (though I did get drawn into that) to argue about why C is as it is. I have no issue with it being what it is.

Nor did I want to imply that based on whatever the formal C definition is, the semicolon (in that particular place) was (or was not) dependent on it being a terminator.
It may well be (but I do not know) that if C would see the semicolon as separator, that it would change.
And it may well be, that for the formal C definition, your statement that the semicolon exists (in that place) is because it is a terminator.

Again, I was only talking about the relevance of that distinction in the current given Pascal definition.

Title: Re: Conditional test statement/semicolon Hell!
Post by: Otto on March 27, 2020, 10:03:29 pm
@440bx
Hello.

[...]
As far as the "if then else" being a single operator, the construction "if then else <statement>" hurts my neurons. Why is there a "then" when the thing is _empty_ and worse, implicitly empty instead of explicitly.  It's like buying a suitcase and putting nothing in it.
[...]

I understand what you mean, but I don't share it. The expression "if <condition>then else <statement>" could be read as "if the condition <condition> is true then do nothing, otherwise do <statement>" vel [Latin] "if the condition <condition> is NOT true then do otherwise <statement>" Which in many human languages is a common expression.

Of course, mine is just an opinion, I don't pretend to be right.

Capisco quello che intendi, ma non lo condivido. L’espressione "if <condition> then else <statement>" potrebbe essere letta come “se la condizione <condition> è vera allora non fare niente, altrimenti fai <statement>” vel [latino]  “se la condizione <condition> è falsa allora fai altrimenti <statement>” Che in molte lingue umane è un espressione comune.

Ovviamente la mia è solo un’opinione, non pretendo di avere ragione.

Otto.
Title: Re: Conditional test statement/semicolon Hell!
Post by: 440bx on March 27, 2020, 11:05:26 pm
"begin end", well good question, I need to research if it contains one empty statement.
It does because the production for a Pascal compound statement is:

"begin" _Statement { ";" _Statement } "end"

and the production for _Statement is structurally along the lines of: (can't be exact since different compilers support many different kinds of statements)

WhileStatement | ForStatement | CaseStatement | EtcStatement | EMPTY

that last one EMPTY is the important one. 

you were saying (in diff words) that C was "nicer" because the empty statement would be more visible due to its ; terminator.
That is correct.

And (as I understood your post) that ; was present in C, but not Pascal due to the difference between a terminator and a separator.
That is also correct.  The ";" is there in C because it is a terminator and not present in Pascal because it is a separator.

I did state, that the none presence of the ; (between then and else) in Pascal was based on the fact that "if then else" is one statement (according to the docs), and not (or not yet/primarily) due to the separator/terminator difference.
Yes, you stated that and that is not the reason.

I'm going to try explaining why a different way.  Imagine that both C and Pascal included a keyword to denote the empty statement.  For simplicity let's say that keyword is empty.  This would yield the following:

In C,

if (<condition>) empty ; else <somestatement>

Note that there is a semicolon because every statement in C _must_ be terminated (empty statements are no exception.)

In Pascal

if <condition> empty else <somestatement>

there is no semicolon because the empty statement is not followed by another statement thus not requiring the ; separator (and else is _not_ a statement.

Hopefully that shows it clearly because, at least at this time, I cannot think of a clearer explanation.

HTH


So this is a really complex rule. And the compiler needs to look ahead (check for an else) to decide if the "if then" is terminated by the semicolon or not.
Like most compilers it looks ahead one symbol but, for the terminating semicolon it doesn't even need to look, never mind ahead and the reason is: whatever production handles <statement> is going to ensure the statement is semicolon terminated therefore, when that production returns to the IfStatement production, that production knows there is a terminating semicolon because if it were missing the production that returned control to it would have issued a syntax error (ignoring error recovery which usually requires the compiler to do syntactic acrobatics.)

Also it was not at any time my goal (though I did get drawn into that) to argue about why C is as it is. I have no issue with it being what it is.
I don't either.  I showed that as an example of the difference it makes in a language to use separators instead of terminators.  Personally, I prefer terminators because that way there is no doubt if a semicolon is needed or not.  The rule is very simple, you got a statement, you put a semicolon at the end.   In Pascal the rules are more complicated due to its use of a separator instead of a terminator.



@Otto,

Ciao!

I understand what you mean, but I don't share it. The expression "if <condition>then else <statement>" could be read as "if the condition <condition> is true then do nothing, otherwise do <statement>" vel [Latin] "if the condition <condition> is true then do otherwise <statement>" Which in many human languages is a common expression.
I see it a different way.  I see this way:  the absence of anything between the "then" and "else" is like someone saying "if it rains else buy popcorn".  Most human beings wouldn't have a clue what to do if it rains, all they get to know is what to do if it doesn't rain.

Of course, that's the way it feels/looks to me.  I understand and accept that other people may see it differently.

Title: Re: [SOLVED] Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 28, 2020, 12:07:52 am
Not going to repeat myself, answered this before (and so have you it seems). Lets agree to disagree.

Conclusion (both):

I do see (and read the docs that way) the entire "if then embedded else embedded" as one statement. There is no terminator nor separator possible inside it.

I do not do "while test(a) ; {while finished, terminate/separate it from whatever follows } do inc(a);"
And that "while" example is not just dreamed up. That is (similar to) how bash does it.


I understand (or assume) you read the fpc docs differently, and therefore have a different view and what is the "if then" and what is the "embedded" statement.
Assuming such a different view, your initial statement is correct.



Btw:
Code: Pascal  [Select][+][-]
  1. begin
  2.   If a then
  3.     foo
  4.   else
  5. end
Here I agree, a terminator (rather than a separator) would require a ; for the empty else statement.
Same for an empty "then" in case there was no "else".

We just differ in what the terminator terminates...



Last minute edit:

I do not see any reference in the docs, that "else" is in any form a statement separator.

So in case the "then_statement" And the "else_statement" were separate statement, they would need a separator. (because that is what you have between 2 statements).

Title: Re: [SOLVED] Conditional test statement/semicolon Hell!
Post by: winni on March 28, 2020, 12:37:49 am
Hi!

There was once (in the 70s) the discussion from Pascal students:

"Where to put begin end"

N. Wirth pointed out: For one statement you don't need them.
And he pointed out that if is one instruction.
And the same with if then else.

So you can build if cascades without begin end.

Winni
Title: Re: [SOLVED] Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 28, 2020, 01:23:48 am
And he pointed out that if is one instruction.
And the same with if then else.

Well, and it is my opinion, that within (the middle of) one (a single) statement there cannot be a statement terminator. (same as there cannot be a separator).

But there I am, repeating myself (again).


I am aware that begin...end is a single (combined) statement too.
But for this it is explicitly defined that the separators apply to the included statements (and if it where terminators, the same explicit definition would have to exist).
Title: Re: [SOLVED] Conditional test statement/semicolon Hell!
Post by: 440bx on March 28, 2020, 01:24:47 am
Not going to repeat myself, answered this before (and so have you it seems). Lets agree to disagree.
No problem.  I'll agree to disagree but, I do want to point out that I was _explaining_ not arguing about separators and terminators.

I will provide a last example, as a last effort, not as an argument.  In the statement:

if a = b then b := a else a := b;

In a language, such as C, that uses statement terminators, the statement "b := a" after the "then" would require a terminating semicolon.  I believe you see that.  Now, the reason Pascal doesn't require it in that case is because the semicolon is not a terminator and "else" is not a statement, therefore, no semicolon.  And, because in Pascal, the semicolon is a separator, including one after "b := a" will result in the compiler emitting an error because "else" is not a statement, therefore it doesn't need to be separated from "b := a".

Conclusion: I agree to disagree and the above is my last effort to explain it.

I do not see any reference in the docs, that "else" is in any form a statement separator.
"else" is neither a statement nor a separator, it is simply a _part_ of an "if" statement.  Like "to" in a "for/to/do" statement.

So in case the "then_statement" And the "else_statement" were separate statement, they would need a separator. (because that is what you have between 2 statements).
yes but, that wouldn't make any sense.  An "else" by itself doesn't have anything to "else" from.

ETA

the inner ";" terminates the inner statement not the outer one which is the "if", that statement will be terminated by the ";" that ends the statement in the "else" part.  If there was no "else" part then the semicolon would terminate the "if" as well.


Title: Re: [SOLVED] Conditional test statement/semicolon Hell!
Post by: Martin_fr on March 28, 2020, 01:54:40 am
Now, the reason Pascal doesn't require it in that case is because the semicolon is not a terminator

Now that is where I disagree.

I believe if that you if you take all Pascal definitions exactly as the are. And only change that ; is a terminator => then (in Pascal) there would still not be a ; in front of the else.

Because if there was, it would terminate the IF statement (that is how "IF" IMHO is defined). So there cannot be a terminator.


You (seem to ) believe  that "if" is defined in such a way that it would not be terminated by a terminator in that Place. I do not see how to derive that from "if then else" is one single statement.

But this is where  we disagree.

The separator/terminator disagreement, IMHO stems from that different view.

Quote
the inner ";" terminates the inner statement not the outer one which is the "if", that statement will be terminated by the ";" that ends the statement in the "else" part.  If there was no "else" part then the semicolon would terminate the "if" as well.
You said that before. That may be true for C.

I do not see that this would be a given in Pascal. Of course currently it is not defined for Pascal, because Pascal has no terminators.

But then, if you switched Pascal to terminators, you would need to add this sort of inner/outer definition.

You would thereby change the definition of "IF".
Because, currently the embedded statement become part of the outer IF. So they are no longer statements on their own. (and not requiring a terminator) Otherwise the "IF" would not truely be one statement, but that is how it is defined in Pascal.

That can be compared to the following C: "if ( (a=b) ==0) {}".  "a=b" is/was a statement, but is now part of the expression. It no longer gets a terminator.
Title: Re: [SOLVED] Conditional test statement/semicolon Hell!
Post by: winni on March 28, 2020, 02:33:53 am
Hi!

The discussion comes to a sudden death if you ask:

How to use then or else without if ???

There you go.

And don't tell me about the "case else". That is bloody Turbo Pascal syntax rubbish.
It is called otherwise.

Winni
TinyPortal © 2005-2018