Recent

Author Topic: Question ?!!!!  (Read 8859 times)

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 639
Re: Question ?!!!!
« Reply #30 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.

Thaddy

  • Hero Member
  • *****
  • Posts: 10293
Re: Question ?!!!!
« Reply #31 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.
« Last Edit: June 10, 2019, 06:09:58 pm by Thaddy »
I am more like donkey than shrek

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 639
Re: Question ?!!!!
« Reply #32 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!".

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8603
  • FPC developer.
Re: Question ?!!!!
« Reply #33 on: June 10, 2019, 06:02:37 pm »
If documented, it is of course ok.

440bx

  • Hero Member
  • *****
  • Posts: 1936
Re: Question ?!!!!
« Reply #34 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.







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

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 639
Re: Question ?!!!!
« Reply #35 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.

Zoran

  • Hero Member
  • *****
  • Posts: 1574
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Question ?!!!!
« Reply #36 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.


Thaddy

  • Hero Member
  • *****
  • Posts: 10293
Re: Question ?!!!!
« Reply #37 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.
« Last Edit: June 11, 2019, 11:54:37 am by Thaddy »
I am more like donkey than shrek

Blade

  • New Member
  • *
  • Posts: 24
Re: Question ?!!!!
« Reply #38 on: April 24, 2020, 09:35:44 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.

I agree with this sentiment of not introducing inline variables and for the Free Pascal team to be very cautious and picky about anything Embarcadero introduces into Delphi.  If it is something to be considered, then possibly have it as something that can be converted over from Delphi to Lazarus or under a Delphi compatibility mode feature. 

It should be mentioned that Embarcadero has the C++Builder product, and an incentive to blur the lines between their C++ and Object Pascal (Delphi) products.  Even if it means introducing destructive changes to Delphi.  They might think such changes can snag a few more C language family users for a bump in sales.  Embarcadero's perspective can be very short-sighted and for just short term gains, something history has shown.  The Free Pascal team is debatably in a better position to look at the long view, and what's in the best interest of the language.  A lot of people use or will want to use Object Pascal, because it's not C++ and does things differently.
« Last Edit: April 24, 2020, 09:38:12 am by Blade »

avra

  • Hero Member
  • *****
  • Posts: 1945
    • Additional info
Re: Question ?!!!!
« Reply #39 on: April 24, 2020, 12:17:12 pm »
I do not like inline variables because of the bad debugging feeling experience in languages that support them.

The way I see it there are 2 reasons for users asking such a feature:
1) To avoid jumping each time to var section when you need new variable in the middle of some lengthy method
2) To quickly see variable type when variable is in the middle of the code and you are looking at the code or debugging it - and you want to avoid jumping to var section

First can be solved with the editor that on your request just asks for the type of a variable and automatically adds it into var section. Second can be solved by showing some on mouse hint with variable type in both editor and debugger.

Most native compiled languages having inline variables were made in the time when we had 25x80 character terminals without any graphics, so today's perspective is different and we have much better ways to address the problem then breaking the pascal spirit.

As for inline variables in for loop:
Code: Pascal  [Select][+][-]
  1. for var i: integer := 1 to 10 do
I am much more tolerant to such request although it is just a softer version of the general inline variables. I don't like it much, but I can look at it in the code without bad feeling in the stomach.

Although I see the advantage that in suggested example loop variable is not limited to integer types, I guess that most of it's use would be limited to that. Therefore, I would prefer to see this instead:
Code: Pascal  [Select][+][-]
  1. for 10 times do
That would be more in the spirit of pascal, and it would stay a readable sentence - which is in my opinion a crucial pascal feature. Of course, instead of 10 you could use any already declared integer like variable. It would have limited use (no easy way to reference counter in for-loop code), so at the end not that much needed either.

However I do think that we are missing some syntax sugar. For example implementing unified try-except-finally block would bring more clarity to complex code since FreePascal does not have garbage collector and we already have to use try-finally block in order to avoid memory leaks and make sure that each object creation always ends with destruction:
Code: Pascal  [Select][+][-]
  1. try
  2.   ..
  3. except
  4.   ..
  5. finally
  6.   ..
  7. end;
« Last Edit: April 24, 2020, 12:40:54 pm by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

440bx

  • Hero Member
  • *****
  • Posts: 1936
Re: Question ?!!!!
« Reply #40 on: April 24, 2020, 12:47:46 pm »
I do not like inline variables because of the bad debugging feeling experience in languages that support them.
What problems have you experienced ?... I use them in C and find the availability of that feature quite convenient and useful to produce simpler, easier to maintain code (provided the feature isn't abused/misused.)

IMO, part of the real problem is that the keywords "begin" and "end" in Pascal are already quite overloaded and overloading them even more to turn them into a limited form of scope delimiters will only make their inherent problems worse.

Inline variables is a nice feature provided it is well implemented.  The Embarcadero implementation is typical, throw some code at the computer, make it sort of work and call it a feature.  That will be $1500.00, thank you very much.  Not to mention that it adds another "Delphi can do what C does" fuzzy feeling for Delphi programmers to enjoy.



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

avra

  • Hero Member
  • *****
  • Posts: 1945
    • Additional info
Re: Question ?!!!!
« Reply #41 on: April 24, 2020, 01:21:02 pm »
I do not like inline variables because of the bad debugging feeling experience in languages that support them.
What problems have you experienced ?... I use them in C and find the availability of that feature quite convenient and useful to produce simpler, easier to maintain code (provided the feature isn't abused/misused.)
As I said it was more of a bad subjective feeling then a real problem. Inline variables are not such common habit as people would think, so when looking at other people's code before I am aware of them I end up jumping to the wrong places and loosing time. And having an inline variable used for something few lines later is one thing, but used for something in 3 different far apart places when method is pages long... well, to me that's not much different from some C like for-loop written by some 'hacker' that will waste 10 minutes of my time every six months when I have to look at it again. Nothing that a good editor or different mind set can't deal with, but when you are forced to work with many different IDE's and editors you can not be familiar with more then 2 or 3.

Inline variables is a nice feature
We can agree that we disagree. I do not have a problem to stay it that way.
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

munair

  • Hero Member
  • *****
  • Posts: 696
  • keep it simple
    • SharpBASIC
Re: Question ?!!!!
« Reply #42 on: April 24, 2020, 01:28:37 pm »
The way I see it there are 2 reasons for users asking such a feature:
1) To avoid jumping each time to var section when you need new variable in the middle of some lengthy method
2) To quickly see variable type when variable is in the middle of the code and you are looking at the code or debugging it - and you want to avoid jumping to var section
Feature requests are often about convenience that do not justify implementation. When variable declarations are limited to the declaration section, it gives a good overview plus the compiler doesn't need to worry about additional declarations involving extra stack frames elsewhere in the code. Typically, with iteration variables, programmers find it 'annoying' having to declare such a 'tiny' variable in the declaration section. What's more, with multiple iterations, such variables are declared with each loop, which is not efficient. I sometimes used this feature with languages that support it, but from a user experience it is rather trivial and not worth the overhead it creates nor the effort to implement it IMO.
« Last Edit: April 24, 2020, 01:30:29 pm by Munair »

BeniBela

  • Hero Member
  • *****
  • Posts: 751
    • homepage
Re: Question ?!!!!
« Reply #43 on: April 24, 2020, 01:47:44 pm »
The inline for loop declaration would protect one from:

1. using the loop variable before the loop where it is still unitialized

2. using the loop variable after the for loop where is has become uninitlaiized again

3. using a global variable as loop variable




I just cannot use for loops without inline variables. Lazarus can automatically declare the variable for the loop? Well, it does not when there is a global variable with the same name

munair

  • Hero Member
  • *****
  • Posts: 696
  • keep it simple
    • SharpBASIC
Re: Question ?!!!!
« Reply #44 on: April 24, 2020, 02:02:43 pm »
The inline for loop declaration would protect one from:

1. using the loop variable before the loop where it is still unitialized

2. using the loop variable after the for loop where is has become uninitlaiized again

3. using a global variable as loop variable
Point 1 is not an issue because using the iterator for something else before the loop means it should be regarded as a normal variable (which it is) that might need initialization.

Point 2 depends on compiler policy. For example, I remember from QuickBASIC that if a loop completes, the iterator was always max_iter_value + 1  and when the loop was short-cut, the iterator returned the value of the last iteration. There was never an ambiguous situation.

I do not see the problem with point 3 either. Although I cannot remember ever having used a global variable in a sub-scope as iterator, the state of the variable during and after the loop is the same as any other iterator. Naturally, if the iterator is not declared in the respective scope, the compiler will try to find a match in an encompassing scope or the global scope, but that is entirely the programmer's responsibility. In this respect, good programming practice is key and no compiler can beat that.

 

TinyPortal © 2005-2018