Recent

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

philtroy

  • Newbie
  • Posts: 3
Inline variable declatations
« Reply #15 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.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Question ?!!!!
« Reply #16 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.

« Last Edit: June 10, 2019, 11:21:49 am by marcov »

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: Inline variable declatations
« Reply #17 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.)

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

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: Question ?!!!!
« Reply #18 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
« Last Edit: June 08, 2019, 11:57:32 pm by VTwin »
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

ASerge

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

440bx

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

« Last Edit: June 10, 2019, 01:39:00 am by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

philtroy

  • Newbie
  • Posts: 3
Re: Question ?!!!!
« Reply #21 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


Zoran

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

ASerge

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

440bx

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

« Last Edit: June 10, 2019, 04:07:43 pm by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: Question ?!!!!
« Reply #25 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  ::)
Specialize a type, not a var.

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: Question ?!!!!
« Reply #26 on: June 10, 2019, 05:31:52 pm »
Btw, if you break out of a for loop, the variable retains its value.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Question ?!!!!
« Reply #27 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 )

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: Question ?!!!!
« Reply #28 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: 14201
  • Probably until I exterminate Putin.
Re: Question ?!!!!
« Reply #29 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 »
Specialize a type, not a var.

 

TinyPortal © 2005-2018