Recent

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

440bx

  • Hero Member
  • *****
  • Posts: 1938
Re: Question ?!!!!
« Reply #60 on: June 01, 2020, 12:21:51 pm »
in my oppinion it brings too much overload to the language syntax.
On the contrary, unlike inline variables it does not overload the "begin" and "end" keywords as block delimiters.

I think a feature like this is justified only if it brings considerable gains in performance.
That feature has nothing to do with performance.  It wouldn't affect performance one way or the other.  What that feature is about is localizing constant, type and variable definitions within a function/procedure.  That means, instead of potentially having a significant number of locals, which turn out to be globals within the function/procedure/method, it would allow a much smaller number of locals because "throw away temporary variables" would be confined to the scope.  That would make the code easier to understand and maintain.

By the way, would not this syntax cause some confusion with a possible future implementation of anonymous methods?
It shouldn't.  Inline scopes should always be identified by a keyword to indicate their presence.


Delphi actually allows scoping inline variables if you put then INSIDE a nested begin..end block.
THAT is syntax overloading.  "begin"/"end" are very poor block delimiters.  The reason is, in a Pascal block, the programmer is supposed to be able to declare constants and types but, apparently these block features would not be available by overloading "begin"/"end".  Overloading "begin"/"end" as block delimiters is just a hack.  Another "writable constants" bright idea.

Type inference makes some assignments a little less redundant to write and adds simplicity to the code. The only negative point I see is the syntax that not follows the original Pascal concepts of declaring everything BEFORE the begin..end;
That's not the only potential problem with type inference.  Pascal's strong type checking depends on explicit type declarations, type inference has the potential to create situations where the compiler would infer a type that is not the one the programmer had in mind.

However, I wish I could declare a variable in a loop like this in FPC:
Code: Pascal  [Select][+][-]
  1. for var i := 1 to 5 do
  2.  
With inline scopes you can do that and then some, all without altering the way variables are declared.

but I understand that if it costs turning the language into a Frankenstein, with various pieces without consistency, I prefer FPC stays the way it is.
Too late for that.  If memory serves, writable constants were the first "Frankengimmick" that Borland put into Pascal and, unfortunately, far from the last one.

Fortunately, or maybe unfortunately, it's quite likely that the probability of seeing the Pope named the sexiest male on earth is likely greater than seeing inline scopes implemented in FPC.



hence I suggested for the latter example to create index as a keyword. The compiler can know that an index variable is required, even nested, and the ugly var is gone.
Code: Pascal  [Select][+][-]
  1. // in this case suppose index is a keyword, requesting the compiler to create it
  2. for index := 0 to 4 do
  3.   for index := 3 to 7 do;
  4.  
Effect is the same, but I believe the syntax is a lot cleaner..
And how would a two dimensional array "A" element be addressed ?... A[index, index] ? being able to address only the elements on the diagonals of square arrays doesn't seem to be a very useful "feature".

As far as controlling repetitions, that nested loop is basically a convoluted way of writing "for i := 1 to 25 do ;"  The other examples you showed have the same problems.

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

Thaddy

  • Hero Member
  • *****
  • Posts: 10293
Re: Question ?!!!!
« Reply #61 on: June 01, 2020, 01:03:28 pm »
They are not really problems for the compiler side. But as I stated many times that I find it important that declaration and implementation are separated. Such constructs as I presented are cleaner though, because of inference and there is less wrong with that.
I'd rather see only inference for those kind of instructions than explicit declarations in an implementation part: that is NOT Pascal.
IF such things are implemented, try to keep the separation, is more or less my way of thinking.
Many C and C++ programmers agree, btw, - e.g. Linus Torvalds - inline declarations are evil. Perhaps apart from loop variables as intrinsic.
Not from a point of convenience, but from a point of maintainability and team work.
People tend to focus on convenience..., which is wrong for large code bases.
« Last Edit: June 01, 2020, 01:11:38 pm by Thaddy »
I am more like donkey than shrek

Warfley

  • Sr. Member
  • ****
  • Posts: 282
Re: Question ?!!!!
« Reply #62 on: June 02, 2020, 03:53:56 pm »
In my opinion there is (at least in pascal) only one argument in favor of inline variable declaration, which is scoping.

When using scoped variables you can have different types for the same variable name, not access variables outside their scope (i.e. you know exactly where each variable belongs) and managed variables would only be initialized when the scope is entered (i.e. on an if, only if that branch is taken) and destroyed when the scope is left (which could lead to better performance and a fine grade of control over how and when memory is used e.g. by arrays).

That said all of these points are not really strong arguments because:
1. using same name for different types means you name is meaningless, this is more a symptom of bad naming
2. If you have to many scopes so you loose track of your variables, probably your function is to big and you should outsource some scopes to (nested) functions
3. If you need the performance of managed types, you can still call finalize and initialize by hand for memory areas, or use functions (which through inlining most certainly will not add overhead). And for the memory usage, one can always free managed types, e.g. Strings or Arrays by setting them to nil

So In a clean code base I don't see any reason why this would be required. Things like being able to use the same name for different types makes the code even worse in my opinion. The only thing where I can see real advantages imho is the for and for-in loops. While looping variables should be recognizable by their naming, I've already had this code:
Code: Pascal  [Select][+][-]
  1. for i:=0 to len -1 do
  2.   foo(i);
  3.   bar(i);
Where I forgott the begin/end (because it was a oneliner at first and then I've added more lines), and in this cases a compiler error that I'm accessing the loop variable outside it's scope would be nice

Thaddy

  • Hero Member
  • *****
  • Posts: 10293
Re: Question ?!!!!
« Reply #63 on: June 02, 2020, 04:04:25 pm »
That last part is python syntax... by indentation...
I am more like donkey than shrek

Warfley

  • Sr. Member
  • ****
  • Posts: 282
Re: Question ?!!!!
« Reply #64 on: June 02, 2020, 04:23:48 pm »
That last part is python syntax... by indentation...
Yes, but my point was that I've already had the situation that I brainlessly added a line line to a for loop, but because it was previously a one liner, I had no begin-end and  therefore the next line was not part of the for loop.

I now try to use begin-end everywhere (except where it will only be one liners like raising errors or calling exit/break/continue), but in such a case a warning (or compilation error) by the compiler would have been nice. Or in general, if you use a loop variable after the loop

PascalDragon

  • Hero Member
  • *****
  • Posts: 1966
  • Compiler Developer
Re: Question ?!!!!
« Reply #65 on: June 03, 2020, 09:28:58 am »
So In a clean code base I don't see any reason why this would be required. Things like being able to use the same name for different types makes the code even worse in my opinion. The only thing where I can see real advantages imho is the for and for-in loops. While looping variables should be recognizable by their naming, I've already had this code:
Code: Pascal  [Select][+][-]
  1. for i:=0 to len -1 do
  2.   foo(i);
  3.   bar(i);
Where I forgott the begin/end (because it was a oneliner at first and then I've added more lines), and in this cases a compiler error that I'm accessing the loop variable outside it's scope would be nice

Optimally the compiler would warn you that i in the call to bar is undefined. At least with -O3 in trunk (don't know if in 3.2.0 as well) it already does:

Code: Pascal  [Select][+][-]
  1. program tforvar;
  2.  
  3. procedure Foo(aArg: LongInt);
  4. begin
  5.  
  6. end;
  7.  
  8. procedure Test;
  9. var
  10.   i: LongInt;
  11. begin
  12.   for i := 0 to 20 do
  13.     Foo(i);
  14.   Foo(i);
  15. end;
  16.  
  17. begin
  18.   Test;
  19. end.

Code: [Select]
PS E:\fpc\git> .\compiler\ppc386.exe -n -Furtl\units\i386-win32 -viwnh -FEtestoutput -O3 .\fpctests\tforvar.pp
Target OS: Win32 for i386
Compiling .\fpctests\tforvar.pp
tforvar.pp(3,15) Hint: Parameter "aArg" not used
tforvar.pp(14,8) Warning: Local variable "i" does not seem to be initialized
Linking testoutput\tforvar.exe
19 lines compiled, 0.0 sec, 29120 bytes code, 1316 bytes data
1 warning(s) issued
1 hint(s) issued

It's a work in progress however.

440bx

  • Hero Member
  • *****
  • Posts: 1938
Re: Question ?!!!!
« Reply #66 on: June 03, 2020, 09:44:45 am »
It's a work in progress however.
Nice that the compiler is keeping track of "no initialization" across "for" loops.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 10293
Re: Question ?!!!!
« Reply #67 on: June 03, 2020, 10:01:02 am »
Really nice, given -Sew : treat warnings as errors (which the compiler demands from compiling itself!)
I am more like donkey than shrek

 

TinyPortal © 2005-2018