Recent

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

440bx

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

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Conditional test statement/semicolon Hell!
« Reply #31 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
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: Conditional test statement/semicolon Hell!
« Reply #32 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.

440bx

  • Hero Member
  • *****
  • Posts: 3945
Re: Conditional test statement/semicolon Hell!
« Reply #33 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.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

GypsyPrince

  • Guest
Re: Conditional test statement/semicolon Hell!
« Reply #34 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.

bytebites

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

GypsyPrince

  • Guest
Re: Conditional test statement/semicolon Hell!
« Reply #36 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...

440bx

  • Hero Member
  • *****
  • Posts: 3945
Re: Conditional test statement/semicolon Hell!
« Reply #37 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
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

bytebites

  • Hero Member
  • *****
  • Posts: 633
Re: Conditional test statement/semicolon Hell!
« Reply #38 on: March 26, 2020, 09:26:44 pm »
You don't need any reason to that "fact".  :P

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: Conditional test statement/semicolon Hell!
« Reply #39 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.



 

Otto

  • Full Member
  • ***
  • Posts: 226
Re: Conditional test statement/semicolon Hell!
« Reply #40 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.
Of course this would only be a practical solution, but it could be useful to someone.

Otto.
Kind regards.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Conditional test statement/semicolon Hell!
« Reply #41 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
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

madref

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

Lazarus 3.99 (rev main_3_99-649-ge13451a5ab) FPC 3.3.1 x86_64-darwin-cocoa
Mac OS X Monterey

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Conditional test statement/semicolon Hell!
« Reply #43 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
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

ASerge

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

 

TinyPortal © 2005-2018