Bookstore

Recent

Author Topic: [SOLVED] Conditional test statement/semicolon Hell!  (Read 2103 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 698
Re: Conditional test statement/semicolon Hell!
« Reply #15 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
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 6057
    • wiki
Re: Conditional test statement/semicolon Hell!
« Reply #16 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.
« Last Edit: March 26, 2020, 01:42:18 pm by Martin_fr »

Handoko

  • Hero Member
  • *****
  • Posts: 3434
  • My goal: build my own game engine using Lazarus
Re: Conditional test statement/semicolon Hell!
« Reply #17 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

And/or a warning message (on the Messages window), if the IDE detect such the thing on compile time.
« Last Edit: March 26, 2020, 02:03:16 pm by Handoko »

440bx

  • Hero Member
  • *****
  • Posts: 1558
Re: Conditional test statement/semicolon Hell!
« Reply #18 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.

« Last Edit: March 26, 2020, 02:12:17 pm by 440bx »
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 6057
    • wiki
Re: Conditional test statement/semicolon Hell!
« Reply #19 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

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.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 6057
    • wiki
Re: Conditional test statement/semicolon Hell!
« Reply #20 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.

440bx

  • Hero Member
  • *****
  • Posts: 1558
Re: Conditional test statement/semicolon Hell!
« Reply #21 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.)

using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

ASBzone

  • Sr. Member
  • ****
  • Posts: 323
  • Automation leads to relaxation...
    • BrainWaveCC Utilities
Re: Conditional test statement/semicolon Hell!
« Reply #22 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...  ::)
-ASB: https://www.BrainWaveCC.com

Lazarus v2.0.7 r62681 / FPC v3.2.0-beta-r44391 (via FpcUpDeluxe) -- Windows 64-bit install w/32-bit cross-compile
Primary System: Windows 10 Pro x64, Version 1909 (Build 18363.720)
Other Systems: Windows 10 Pro x64, Version 1909 or greater

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 6057
    • wiki
Re: Conditional test statement/semicolon Hell!
« Reply #23 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.
« Last Edit: March 26, 2020, 04:38:48 pm by Martin_fr »

440bx

  • Hero Member
  • *****
  • Posts: 1558
Re: Conditional test statement/semicolon Hell!
« Reply #24 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.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 6057
    • wiki
Re: Conditional test statement/semicolon Hell!
« Reply #25 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....




madref

  • Hero Member
  • *****
  • Posts: 772
  • ..... A day not Laughed is a day wasted !!
    • Nursing With Humour
Re: Conditional test statement/semicolon Hell!
« Reply #26 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
You treat a disease, you win, you lose.
You treat a person and I guarantee you, you win, no matter the outcome.

Lazarus 2.0.6 / FPC 3.0.4
Lazarus Trunc / FPC Trunc
Mac OS X Mojave

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 6057
    • wiki
Re: Conditional test statement/semicolon Hell!
« Reply #27 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.

MarkMLl

  • Hero Member
  • *****
  • Posts: 698
Re: Conditional test statement/semicolon Hell!
« Reply #28 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
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 6057
    • wiki
Re: Conditional test statement/semicolon Hell!
« Reply #29 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.