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.
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?
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.
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 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.
...but there's limits as to what can be done without breaking the language.
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.
if <condition> then
<single statement>
else
<single statement> ;
try
<statement sequence>
finally
<statement sequence>
end;
@MarkMLIQuote...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.
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?
... danger is that you place a semicolon immediately after then or else ...
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.Particularly when the "{" and "}" also define a new scope (as they do in C which is what allows for inline variable declarations)
if (foo) { if (bar) { a=1; c=a; } else { b=1; }}
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.
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)... 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.
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.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:
...
So either way (separator or terminator), a if/else would not have any semicolon.
That's because humans are more forgivving about little changes than machines. Unfortunately this does not work.
For instance, in C:Does it though? Or does it terminate the "if" statement, making the "else" a separate statement?the semicolon terminates the empty 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.For instance, in C:Does it though? Or does it terminate the "if" statement, making the "else" a separate statement?the semicolon terminates the empty 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.As I said, I have not gone through the formal C definition to check what terminology is used, and how this is actually defined...
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.
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.
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".
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.
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.I always find this so stupid and it takes more time to compile.
if a = b then ; else writeln('a <> b');
Sometimes it's much easier to write what you what to check
If a <> b then written ('a <>b');
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.
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 for Pascal, that only becomes relevant, if the definition of "if then else" changes.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.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.
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".
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.
If IsNew Then Begin End Else 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.Yes there are plenty of differences caused by the difference between terminator and separator.
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.
[...] Using begin … end pairs is definitely a valid solution to avoid the potential pitfalls there... [...]
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
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
For instance, in C: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.the semicolon terminates the empty statement.
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.
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.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.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.
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.
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.
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.
@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 ?
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.
On an even more absurd note: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.
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)
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".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.
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".
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.
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.
[...]
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.
[...]
"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:
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.
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.
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.
And he pointed out that if is one instruction.
And the same with if then else.
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 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.
Now, the reason Pascal doesn't require it in that case is because the semicolon is not a terminator
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.