Lazarus

Free Pascal => General => Topic started by: nouzi on November 11, 2018, 02:07:38 pm

Title: Question ?!!!!
Post by: nouzi on November 11, 2018, 02:07:38 pm
You could have this in free pascal ?
http://blog.marcocantu.com/blog/2018-october-inline-variables-delphi.html?fbclid=IwAR208x_u_TDY1iRILrxn3eZ-IbSFZPq_P_pLmRSY_V5WO-z6A6d1nbbLMB8
Title: Re: Question ?!!!!
Post by: howardpc on November 11, 2018, 02:38:38 pm
FPC introduced initialisation of variables in their declaration long before Delphi.
One drawback of syntax sugars that, for example, make the compiler infer and allocate implicit types to variables, is that they inevitably slow the compiler slightly, and make it that bit more complex and more time-consuming/harder to maintain.

Not to mention that they move Pascal further away from its Wirthian type-safe declarative design.
Title: Re: Question ?!!!!
Post by: Thaddy on November 11, 2018, 03:02:26 pm
FPC introduced initialisation of variables in their declaration long before Delphi.
One drawback of syntax sugars that, for example, make the compiler infer and allocate implicit types to variables, is that they inevitably slow the compiler slightly, and make it that bit more complex and more time-consuming/harder to maintain.

Not to mention that they move Pascal further away from its Wirthian type-safe declarative design.
You're partially barking up the wrong tree, Howard. (Sorry, just let the dogs out  8-), actual dogs, two of them )
What he is referring to is:
Code: Pascal  [Select]
  1. program testinlinevars;
  2. begin
  3.   // imagine lots of previous code
  4.   for var i:integer := 1 to 10 do writeln(i);
  5. end.

Or even with type inference:
Code: Pascal  [Select]
  1. program testinlinevars;
  2. begin
  3.   for var i  := 1 to 10 do writeln(i);
  4. end.

Such code has been requested many times and always refused by the compiler team. In my opinion for all the right reasons.
Yes. The declarative design of Pascal is a feature and a huge asset. Working with C code bases for the last 30 years this kind of syntax should never be introduced and is often forbidden in huge C codebase examples like the Linux kernel.
Title: Re: Question ?!!!!
Post by: Handoko on November 11, 2018, 03:09:27 pm
The reasons for the rejection can be found here: (item #11)
http://wiki.freepascal.org/Modernised_Pascal
Title: Re: Question ?!!!!
Post by: Thaddy on November 11, 2018, 03:12:14 pm
The reasons for the rejection can be found here: (item #11)
http://wiki.freepascal.org/Modernised_Pascal
That's only one of the reasons. There are many more to be found on the dev mailing list. Or even the original papers on the design of the Pascal language by Niklaus Wirth.
Title: Re: Question ?!!!!
Post by: nouzi on November 11, 2018, 03:47:37 pm
thank for all
Title: Re: Question ?!!!!
Post by: dpremus on November 23, 2018, 08:04:07 pm
I hope that we will never have inline variables in FPC.

This approach in C is used for having better performance, but now day compilers should be smart enough to optimize this.

This will introduce more mess in code than benefits.

Do we need Delphi compatibility anymore?

For example, you can't still use a string in Delphi "case" and they talk about language improvements.
Title: Re: Question ?!!!!
Post by: marcov on November 23, 2018, 08:11:16 pm
In the initial discussion I missed it, but the below illustrates the problem perfectly

Code: [Select]

procedure xxx.yyy;
var thisisastaticglobalvar : integer =0;
begin
  var thisisalocalvarbutthesyntaxisthesame: integer =0;
  ..
end;

Same syntax, two lines apart, meaning totally different. This is not just a dig at Embarcadero. The mode objfpc initialized variables just add to the confusion by recycling syntax for initialized local variables;

Code: [Select]
{$mode objfpc}
procedure xxx.yyy;
var weknoweverythingbetterandinfpcthisisaninitializedlocalvar  : integer =0;
begin
  var thisisalocalvarbutthesyntaxisthesame: integer =0;
  ..
end;

Sigh.

Moral of the story: don't recycle syntax for something potentially ambiguous.

"you don't have to use it if you don't like it" is NOT a good argument.
Title: Re: Question ?!!!!
Post by: User137 on November 23, 2018, 09:44:50 pm
Not sure i understand the explanations. Variable scope is same, and this sort of thing is clearly restricted:
Code: Pascal  [Select]
  1. var
  2.   Form1: TForm1;
  3.   Form1: TStringList;
You'll get: Error: Duplicate identifier "Form1". Same should happen if you try to re-declare a variable inside a function, before or after the "begin" word.

Code: Pascal  [Select]
  1. procedure xxx.yyy;
  2. var i: integer = 0;
  3. begin
  4.   var i: integer =0; // Illegal!
  5.   var k: integer =0; // Ok.
  6.   for var n:integer := 1 to 10 do writeln(n); // Ok.
  7.   // variable n doesn't exist here anymore, but k does.
  8.   for var n:integer := 1 to 10 do writeln(n); // Ok.
  9. end;
Title: Re: Question ?!!!!
Post by: jamie on November 23, 2018, 11:10:59 pm
Random variable declaration is a bad idea, very sloppy code however, I do like the idea of
the FOR LOOP control being able to do this because of this simple fact. The loop variable is documented
as undefined out side the FOR LOOP so it would make perfect sense to allow this to take place within
the loop control where the code in the loop would be the only code that can see it.

 The FOR LOOP is not designed to allow the loop variable to be used outside so why not simply allow the
FOR loop control to create a localized variable as am option..

 The WHILE and REPEAT do reserve the ending value of the a loop while the FOR does not depending on what
the compiler decides to do .

 This is my argument unless you want to modify the FOR LOOP control to have a usable ending value when exiting the
block.


Title: Re: Question ?!!!!
Post by: Martin_fr on November 23, 2018, 11:44:57 pm
Random variable declaration is a bad idea, very sloppy code however, I do like the idea of
the FOR LOOP control being able to do this because of this simple fact. The loop variable is documented
as undefined out side the FOR LOOP
IIRC, with the exception when the loop was exited by "break" or the like, in which case it is defined? (need to double check)

Beside search the many discussions on this forum, where there are plenty of reasons why even the for loop var would not be a good idea. (And yes, I did read the arguments that were brought in favour, and none prevailed)

And lastly, if the only concern is, not to accidentally use the var after the loop:
- the compiler should emit a "undefined warning" => if not that would be something that you should request. If it does, -we promote warnings to errors.
- and if that is not good enough, and you really think it needs changed syntax / extra features (I don't, but I humour the idea): in the var block on top "var a: TEnumerable loopcounter;" limit it to be used as loop counter, and only avail in loops in which it is a counter. I don't think that is needed, but it is far less problematic, and solves the problem.
Title: Re: Question ?!!!!
Post by: BeniBela on November 24, 2018, 12:34:24 am
Delphi compatibility is important

All kinds of weird things were added for Delphi compatibility. classes, when there are already objects; interfaces; Delphi's generic syntax; codepage aware strings ...

This syntax should not be the reason to abandon Delphi compatibility
Title: Re: Question ?!!!!
Post by: 440bx on November 24, 2018, 01:33:20 am
Do we need Delphi compatibility anymore?
More people should ask themselves that question.  The world is afraid of C/C++, that leads to choices like Delphi compatibility because of the (justified) fear that a better language would not stand a chance against the popularity that mediocre languages have gained.   Very unfortunate.
Title: Re: Question ?!!!!
Post by: PascalDragon on November 24, 2018, 02:48:39 pm
Delphi compatibility is important

All kinds of weird things were added for Delphi compatibility. classes, when there are already objects; interfaces; Delphi's generic syntax; codepage aware strings ...

This syntax should not be the reason to abandon Delphi compatibility
On the contrary. This syntax is a good reason to abandon Delphi compatibility, because unlike the ones you mentioned this one touches and chances the very core spirit of the Pascal language.

As such the opinion of the development team on this feature is that we will not implement this. FPC has a strong user base by itself as such we can be picky nowadays which nonsense of Delphi we accept and which we don't.

In the initial discussion I missed it, but the below illustrates the problem perfectly

Code: [Select]

procedure xxx.yyy;
var thisisastaticglobalvar : integer =0;
begin
  var thisisalocalvarbutthesyntaxisthesame: integer =0;
  ..
end;

Same syntax, two lines apart, meaning totally different. This is not just a dig at Embarcadero. The mode objfpc initialized variables just add to the confusion by recycling syntax for initialized local variables;

Code: [Select]
{$mode objfpc}
procedure xxx.yyy;
var weknoweverythingbetterandinfpcthisisaninitializedlocalvar  : integer =0;
begin
  var thisisalocalvarbutthesyntaxisthesame: integer =0;
  ..
end;

Sigh.

Moral of the story: don't recycle syntax for something potentially ambiguous.

"you don't have to use it if you don't like it" is NOT a good argument.
Ehm... where was this mentioned? The syntax for initializing inline variables in Delphi is
Code: Pascal  [Select]
  1. procedure xxx.yyy;
  2. begin
  3.   var thisisalocalvarbutthesyntaxisthesame: integer := {!} 0;
  4. end;
  5.  
(Note the ":=" instead of "=")

And where was it mentioned that Delphi now supports the following?
Code: Pascal  [Select]
  1. procedure xxx.yyy;
  2. var thisisastaticglobalvar : integer = 0;
  3. begin
  4. end;
  5.  
And that this is a global variable now merely by being initialized?
Title: Re: Question ?!!!!
Post by: Leledumbo on November 27, 2018, 09:04:08 pm
As soon as this gets implemented, codetools will have to work harder by searching both declaration and execution section, just as your eyes do. Principle of locality in Pascal spirit is implemented through nested procedure, not inline declarations (and single called nested procedure should be inline-able automatically, zeroing the overhead).
Title: Re: Question ?!!!!
Post by: LemonParty on November 28, 2018, 09:51:29 am
Code: Pascal  [Select]
  1. procedure XXX;
  2. var S: String;
  3.  
  4.  procedure Append(Str: String);
  5.  begin
  6.   S:= S + Str;
  7.  end;
  8.  
  9. begin
  10.  Append('apple');
  11.  Append('1');
  12. end;
Try to use inline variables with this code.
Title: Inline variable declatations
Post by: philtroy on June 08, 2019, 09:00:25 pm
Hi

I am new to this forum, and to Free Pascal, but not to Pascal.  I started programming in 1970, and I used Turbo Pascal to write the analysis software used for my doctoral dissertation.  I then used Delphi for several years, before moving on (and perhaps backwards) to Java around 15 years ago.  So here I am at an advanced age still working, and still doing some computer programming (as part of my analytics job).

I am looking for a modern programming language to use to build analytics capabilities for my organization.  Some of those capabilities require user interfaces.  I would really like to jump in and use Free Pascal (I work on Linux mostly but most of my users use Windows) and I really only have two issues with it.  And one of them is the lack of an ability to use inline variable declarations (I do not want and do not totally believe in the value of type inference so that is not an issue for me).  (FYI, I have used C++ and get a sick feeling in my stomach every time I think of that experience, and have looked at Rust, Golang, Kotlin, and Swift and found them all to be wanting for my purposes.)

So why do I feel that inline variable declaration is so important?  From a very practical perspective, less lines of code makes for easier to understand and support code.  If I can save 10 lines of variable declarations by using inline variable declarations it makes it easier for me to follow the whole piece of code.  And I would venture to say for most other people to follow, not only because there are less lines of code, but also because variable declarations can in many cases be closer to where the variables are being used.

I am sure that there are many reasons for not using inline variable declarations (though I cannot think of them right now).  So, why not allow individuals or organizations to choose their own coding standards.  I would be willing to bet a pitcher or two of beer that most would want to use inline variable declarations, but that would be their choice.

In my mind, the best reason for not implementing inline variable declarations, is that it would be hard to do so.  I am not a computer scientist and I do not have experienced developing compilers so I would not know for sure whether that would be the case.  But I did take an introduction to computer science course with Alan Perlis (and if you do not know who he is it might be interesting for you to find out by googling him) sometime around 1984-1985 while a doctoral student at Yale University.  And I seem to remember that in most compilers all local variables are declared in a stack frame on the stack.  Which suggests to me that it might not be so hard to allow new variables to be added to the stack frame at any time, and that the biggest issue might be to make sure that these new variables are not referenced before that point in time.  This in turn might constrain that variable declarations would need to occur in an unambiguous manner before they are being used (but I leave that for the computer scientists).

I have one other comment, which has to do with the declaration that the compiler team would not agree to to make this change.  And this comment is meant to be constructive.  If the community (which I just joined and thus have little say in it) wishes for a feature to be added, perhaps the role of the development team should be discuss the relative merits of implementation of the feature, and the feasibility of the feature, but to then support the decision of the community as to whether the feature is actually implemented. To me, that is what volunteering and community are about, and yes, in my many years of living on this beautiful planet, I have done a little volunteering.

Phil Troy

P.S. Apparently one of Dr. Perlis's famous quotations is "Fools ignore complexity. Pragmatists suffer it. Some can avoid it. Geniuses remove it."  So I suggest that we do our best effort to remove the complexity involved in trying to follow long programs by carefully identifying language features that make those programs shorter without making them more complex.
Title: Re: Question ?!!!!
Post by: marcov on June 08, 2019, 09:36:42 pm
The inline variable discussion raged a few months ago after Delphi announced, and the end decision was to not implement or rediscuss it for the next few years. (and that's only because we've learned to never say never)

So if you really want inline variables, best look elsewhere.

P.s. willy-nilly mixing varying types of lines is IMHO not about reducing complexity. It is increasing it.

Title: Re: Inline variable declatations
Post by: 440bx on June 08, 2019, 10:02:05 pm
P.S. Apparently one of Dr. Perlis's famous quotations is "Fools ignore complexity. Pragmatists suffer it. Some can avoid it. Geniuses remove it."  So I suggest that we do our best effort to remove the complexity involved in trying to follow long programs by carefully identifying language features that make those programs shorter without making them more complex.
Hello Phil,

You already got a pretty clear answer on the inline variables situation. 

Alan Perlis had a lot thought inducing one-liners. :)

The current state of computer language design reminded me of a couple of them...

1. Humans get cancer, Computer Science gets C.
2. C++ is metastasized C.

Someone asked "Why create mediocrity, when you can copy genius?" and the answer is, because it is much easier to copy mediocrity than genius.  (it doesn't take a genius to figure that out.)

Title: Re: Question ?!!!!
Post by: VTwin on June 08, 2019, 11:43:42 pm
I agree with the objections to inline variables, which, imho, add complexity, and avoided them even when available. If a procedure is so long that it is difficult to scroll to the top to find the variables, it is probably too long. I like knowing where they are declared.

Harking back to early FORTRAN, one could simply use a variable without declaring it. Programming was so uncomplicated back then! :D
Title: Re: Question ?!!!!
Post by: jamie on June 09, 2019, 06:16:00 pm
Yes I fully don't want random inline variables scattered all over the place within a block of
code. I Hated that in C/C++, was very hard to follow, especially when they redeclare it as
a different type on the fly... That is a bad idea..

 All variables associated with the block of code should be nested together in a designated location
like they are now..

 However,,,, I Still think for a FOR LOOP control, it should be able to create its own variable within
the FOR LOOP setup and keep the name space local to that FOR control.

  An inner FOR LOOP block of course can see a previous FOR LOOP variable but any code should not
be able to see forward declarations of FOR and Integrated LOOP variable..

 Since these variables are undefined after the loop and are unsafe to use why should the be
visible to code outside ?
The same mechanism used for the "WITH" can also be used here.

 And that's my argument which I know will go no where.

Title: Re: Question ?!!!!
Post by: ASerge on June 09, 2019, 09:00:17 pm
If a procedure is so long that it is difficult to scroll to the top to find the variables, it is probably too long.
+1
In Pascal there is such a wonderful tool like nested functions. Logically independent part of the code is better extract to a separate function, where to declare the variables necessary for it. This reduces complexity because you see less code at a time. Secondly, you also document it by assigning a suitable function name.
For example, in "C" this is not possible, so it had to invent the ability to declare variables anywhere :)

However,,,, I Still think for a FOR LOOP control, it should be able to create its own variable within
the FOR LOOP setup and keep the name space local to that FOR control.
...
The same mechanism used for the "WITH" can also be used here.
For for may be, but for with...
It seems to me that the with instruction increases the complexity. Inside it, I have to think about each property/function: it refers to a Self or to a variable in "with". So I generally try to avoid it.
Title: Re: Question ?!!!!
Post by: 440bx on June 10, 2019, 01:35:42 am
If a procedure is so long that it is difficult to scroll to the top to find the variables, it is probably too long.
+1
In Pascal there is such a wonderful tool like nested functions. Logically independent part of the code is better extract to a separate function, where to declare the variables necessary for it. This reduces complexity because you see less code at a time. Secondly, you also document it by assigning a suitable function name.
Nested functions are a very nice feature when a particular sequence of code is used more than once in a specific function/procedure and no place else.  The keywords are "more than once".  If the sequence of code is used only once then it could have been coded inline and that would have spared the programmer from having to "jump" to their definition to follow the logical flow.

Easy to understand code isn't a function (no pun intended) of how long the function/procedure is.  It's affected a lot more by how many times the programmer's attention has to jump to another location to follow the logical flow.  When code is broken into umpteen pieces that are executed only once, the code resembles more a jigsaw puzzle than a program.  It doesn't take goto-s to create logic flow that is quite reminiscent of spaghetti code.

It's much easier to understand a 500 line function that is totally linear in its execution than one that does the same thing but is broken into 10 (or more) pieces.  You don't have to re-assemble the pieces in your mind and have your focus diverted from the logic just as many times.

For example, in "C" this is not possible, so it had to invent the ability to declare variables anywhere :)
That's not the reason they "invent"ed inline variable declarations. Some C compilers support nested functions (an extension) _and_ inline variable declarations. 

However,,,, I Still think for a FOR LOOP control, it should be able to create its own variable within
the FOR LOOP setup and keep the name space local to that FOR control.
...
The same mechanism used for the "WITH" can also be used here.
For for may be, but for with...
It seems to me that the with instruction increases the complexity. Inside it, I have to think about each property/function: it refers to a Self or to a variable in "with". So I generally try to avoid it.
Poor "with" statement, it gets a bad rap because programmers either misuse it or abuse it.  Used correctly, it is a very nice Pascal feature.  Surprising that the C++ folks haven't copied it.

It would be extremely nice if a limited version of inline variable declaration was added to Pascal.  The "for" loop is the most obvious candidate.

Title: Re: Question ?!!!!
Post by: philtroy on June 10, 2019, 08:21:05 am
Hi

In all seriousness, I thank you all and very much appreciate both the seriousness and the humor of the responses.

:-)

Phil Troy

Title: Re: Question ?!!!!
Post by: Zoran on June 10, 2019, 12:20:05 pm
Oracle's PL/SQL language (which has a Pascal-like syntax - use begin-end for blocks, has var declaration section above code, use procedure/function keywords with pascal-like declaration syntax, nested procedures in procedures) have had variables with block scope for a long time already.

Their syntax is in my opinion much more elegant than what Embarcadero introduced. Every begin-end block (so not only the routine level block,  but any unnamed block) can have it's own var section. So, something like this is allowed:

procedure Proc;
var
  X: Integer; // a variable with procedure scope
begin
  // some code
  var
    Y: Integer; // variable Y has block scope
  begin
     // varible Y is accesible only within this block.
  end;
  // Here, Y is out of scope
end;

So, var section must be just above begin keyword. Then varible has block-scope.
Then, these are truly block-scope variables, not just "inline variables", that Emarcadero introcuded.

I don't think that FPC should add these -- I understand that the options are either implement it in Delphi compatible way, or not at all.
Then, I prefer "not at all".
Title: Re: Question ?!!!!
Post by: ASerge on June 10, 2019, 03:34:39 pm
Nested functions are a very nice feature when a particular sequence of code is used more than once in a specific function/procedure and no place else.  The keywords are "more than once".  If the sequence of code is used only once then it could have been coded inline and that would have spared the programmer from having to "jump" to their definition to follow the logical flow.
Absolutely the opposite opinion. Not exactly "more than once", i.e. just allocate a piece of code to a separate procedure, even if only once, that's good. The amount of code is limited to a small function, you check it, make sure everything is OK and forget. Then later, at the mention of the name, everything becomes clear. But to keep 500 lines of code in memory - that's really too difficult. At the same time, using "inline" for such functions you can not care about performance.
Title: Re: Question ?!!!!
Post by: 440bx on June 10, 2019, 03:56:28 pm
So, var section must be just above begin keyword. Then varible has block-scope.
Then, these are truly block-scope variables, not just "inline variables", that Emarcadero introcuded.
what would be really nice would be to extend the concept of functions and procedures all the way down to scopes.  Instead of defining a function/procedure, define a named scope (the name would only be a "documentation" feature - not really necessary. )

A scope has the same characteristics as a function/procedure except it is not callable.  It can only be inside a function/procedure.  That is fully consistent with the essence of Pascal and offers some very nice abilities.  For instance...
Code: Pascal  [Select]
  1. SomeProc(parameters : types, ...);
  2. const
  3.   aconst : 123;
  4. type
  5.   sometype = 1..10;
  6. var
  7.   whatever : sometype;
  8. begin
  9.   statement;
  10.   statement;
  11.   ...
  12.   scope step1;
  13.   { any definitions/declarations within a scope are local to the scope }
  14.     type
  15.       scopetype = sometype;
  16.     const
  17.       scopeconst = 3;
  18.     var
  19.       scopevar : integer;
  20.   begin
  21.     statement;
  22.     statement;
  23.  
  24.     if somecondition then break; { breaks out of the scope - not the function/procedure - just like in a loop }
  25.  
  26.     statement;
  27.     statement;
  28.   end;
  29.  
  30.   scope step2;
  31.   begin
  32.    statement;
  33.    statement;
  34.    ...
  35.   end;
  36. end;
  37.  

that allows logically grouping statements within a function/procedure.  It also gives the ability to short-circuit (by the use of break) the logical flow within a scope.  The other very nice thing is that there should be significantly fewer variables declared at the function/procedure scope since any and all supporting/helper variables only exist within local scopes.  IOW, fewer "global" function/procedure variables.

Such a feature would simplify a lot of code and make it a lot easier to understand it and maintain it.

Rather unlikely that something like that will be implemented these days.  Too useful.

ETA:

@Serge

Absolutely the opposite opinion. Not exactly "more than once", i.e. just allocate a piece of code to a separate procedure, even if only once, that's good. The amount of code is limited to a small function, you check it, make sure everything is OK and forget. Then later, at the mention of the name, everything becomes clear. But to keep 500 lines of code in memory - that's really too difficult. At the same time, using "inline" for such functions you can not care about performance.
The thing is the programmer doesn't have to keep the 500 lines of code in mind.  All a programmer needs to have in mind is how he/she got to the statement he/she is inspecting, not the whole shebang. 
Plus, even if what you're saying were the case, it is still easier to keep 500 lines of code in mind than the same 500 lines of code _plus_ the 10 function/procedures the code has been broken into, not to mention to also have to keep in mind the _sequence_ in which those functions/procedures have been called.

I know we have a different opinion on that and the great majority of people will see it your way because that's what's been ingrained early in their minds.

It's not the number of lines of code that make a program hard to follow and understand, it's how many times the focus is redirected to some other place/function/procedure/whatever.  Having to constantly take one's focus from one place to another is the essence of spaghetti code. 

Title: Re: Question ?!!!!
Post by: Thaddy on June 10, 2019, 04:41:26 pm
[It would be extremely nice if a limited version of inline variable declaration was added to Pascal.  The "for" loop is the most obvious candidate.
Actually, have a look at this:
Code: Pascal  [Select]
  1. while true do;
But that looks more like type inference  ::)
Title: Re: Question ?!!!!
Post by: SymbolicFrank on June 10, 2019, 05:31:52 pm
Btw, if you break out of a for loop, the variable retains its value.
Title: Re: Question ?!!!!
Post by: marcov on June 10, 2019, 05:35:31 pm
Btw, if you break out of a for loop, the variable retains its value.

Is that documented or empirical evidence (read: compiler quackery )
Title: Re: Question ?!!!!
Post by: SymbolicFrank on June 10, 2019, 05:41:15 pm
From the docs:

Code: [Select]
The value of the loop variable is undefined after a loop has completed or if a loop is not executed at all.
If the loop was terminated prematurely with an exception or a break statement, the loop variable retains the
value it had when the loop was exited.
Title: Re: Question ?!!!!
Post by: Thaddy on June 10, 2019, 05:58:08 pm
I believe it was explained by Jonas somewhere on the bug tracker or the mailing list a couple of years ago:
- if a for loop fully executes then the variable is undefined.
- if a for loop exits prematurely with break, the variable is defined

I can't remember the reasons.. There were a whole lot of discussions because the difference in behavior of the counter in Delphi and FPC when the for loop is fully done.

I guess it is like this:
The value is preserved within the realms of the for loop range. If the full range is satisfied, it becomes undefined.
Hence in the case of break, the value is preserved since it is within the range.

But I can't find the evidence. [edit] I missed the response from SymbolicFrank, that proves it is documented in the official documentation.
Title: Re: Question ?!!!!
Post by: SymbolicFrank on June 10, 2019, 06:01:36 pm
It's useful: you probably want to know it when you break out of the loop: "Found it, this one!".
Title: Re: Question ?!!!!
Post by: marcov on June 10, 2019, 06:02:37 pm
If documented, it is of course ok.
Title: Re: Question ?!!!!
Post by: 440bx on June 10, 2019, 07:13:55 pm
It's useful: you probably want to know it when you break out of the loop: "Found it, this one!".
I'm sure this comment won't be very appreciated by Pascal lovers but, in C/C++ the value of the "for" index variable (if any) is stable.  There are no cases when it is undefined and other cases when it is defined.

That's nice.  OTH, the compiler has to work quite a bit harder when optimizing "for" loop code.  (compilers should work hard anyway.)

In Pascal, if you need to rely on the value of the indexing variable then you have to change the "for" loop into a "while" loop.  I've lost count of the number of times I've forgotten to increment the indexing variable in such translated loops.  Fortunately, the result and the cause are immediately discernible.







Title: Re: Question ?!!!!
Post by: SymbolicFrank on June 10, 2019, 10:03:53 pm
well, you declare it in the var section, retaining the value would make it consistent behaviour. I wouldn't mind.
Title: Re: Question ?!!!!
Post by: Zoran on June 11, 2019, 10:54:01 am
So, var section must be just above begin keyword. Then varible has block-scope.
Then, these are truly block-scope variables, not just "inline variables", that Emarcadero introcuded.
what would be really nice would be to extend the concept of functions and procedures all the way down to scopes.  Instead of defining a function/procedure, define a named scope (the name would only be a "documentation" feature - not really necessary. )

A scope has the same characteristics as a function/procedure except it is not callable.  It can only be inside a function/procedure.  That is fully consistent with the essence of Pascal and offers some very nice abilities.  For instance...
Code: Pascal  [Select]
  1. SomeProc(parameters : types, ...);
  2. const
  3.   aconst : 123;
  4. type
  5.   sometype = 1..10;
  6. var
  7.   whatever : sometype;
  8. begin
  9.   statement;
  10.   statement;
  11.   ...
  12.   scope step1;
  13.   { any definitions/declarations within a scope are local to the scope }
  14.     type
  15.       scopetype = sometype;
  16.     const
  17.       scopeconst = 3;
  18.     var
  19.       scopevar : integer;
  20.   begin
  21.     statement;
  22.     statement;
  23.  
  24.     if somecondition then break; { breaks out of the scope - not the function/procedure - just like in a loop }
  25.  
  26.     statement;
  27.     statement;
  28.   end;
  29.  
  30.   scope step2;
  31.   begin
  32.    statement;
  33.    statement;
  34.    ...
  35.   end;
  36. end;
  37.  

that allows logically grouping statements within a function/procedure.  It also gives the ability to short-circuit (by the use of break) the logical flow within a scope.  The other very nice thing is that there should be significantly fewer variables declared at the function/procedure scope since any and all supporting/helper variables only exist within local scopes.  IOW, fewer "global" function/procedure variables.

Such a feature would simplify a lot of code and make it a lot easier to understand it and maintain it.

Rather unlikely that something like that will be implemented these days.  Too useful.

ETA:

@Serge

Absolutely the opposite opinion. Not exactly "more than once", i.e. just allocate a piece of code to a separate procedure, even if only once, that's good. The amount of code is limited to a small function, you check it, make sure everything is OK and forget. Then later, at the mention of the name, everything becomes clear. But to keep 500 lines of code in memory - that's really too difficult. At the same time, using "inline" for such functions you can not care about performance.
The thing is the programmer doesn't have to keep the 500 lines of code in mind.  All a programmer needs to have in mind is how he/she got to the statement he/she is inspecting, not the whole shebang. 
Plus, even if what you're saying were the case, it is still easier to keep 500 lines of code in mind than the same 500 lines of code _plus_ the 10 function/procedures the code has been broken into, not to mention to also have to keep in mind the _sequence_ in which those functions/procedures have been called.

I know we have a different opinion on that and the great majority of people will see it your way because that's what's been ingrained early in their minds.

It's not the number of lines of code that make a program hard to follow and understand, it's how many times the focus is redirected to some other place/function/procedure/whatever.  Having to constantly take one's focus from one place to another is the essence of spaghetti code.

Yes, these "scopes" would be very nice syntax, quite contrary to new Delphi's "inline vars".
I fully agree with everything said in this post.

However, Emarcadero took quite different way, and I would rather not see any inline variables allowed, than what Delphi introduced.

Title: Re: Question ?!!!!
Post by: Thaddy on June 11, 2019, 11:50:01 am
1. Without reference to what C/C++ compiler(s) it can still be implementation dependent. I can't find any specifications for stable loop count values after exit.
2. Pascal is all about separating declaration from implementation, so Delphi made a big mistake here.
As I wrote before: given that language feature I hope FPC never introduces inline vars. It may be a convenience to the programmer but it is a nightmare for teams and to debug such a feature.
As I also wrote before: many mainline codebases in C/C++ forbid its use for that exact same reason.

That said: type inference for loop variables would be nice and likely easy to implement since those are always ordinals.
That would also prevent re-use after the loop.