Recent

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

alpine

  • Hero Member
  • *****
  • Posts: 1302
Re: Question ?!!!!
« Reply #150 on: August 17, 2024, 08:11:58 pm »
Begin and end aren't "block delimiters". Check your Pascal terminology.
The simplest first.  "begin"/"end" become block delimiters when inline variables are implemented.  They delimit the scope/existence of the variables.
I believe it could be written also:
Code: Pascal  [Select][+][-]
  1. for var i: integer := 1 to 10 do
  2.   writeln(i);
or
Code: Pascal  [Select][+][-]
  1. for var i: integer := 1 to 10 do
  2.   repeat
  3.   until true;
No begin/end here, but still a "block" as you named it.

Specifically for what structural deficiency in Pascal you're talking about? In C variables are inline since the language was invented.
The structural deficiency in Pascal is that there is no way to create inline groups of statements (or independent blocks).  Pascal offers nested functions/procedures but that is _not_ a good solution for groups of statements that accomplish a particular task that is only done once in a function/procedure.  The reason nested functions/procedures are not a good solution in that case is because the group of statements is not inline thus forcing the programmer to divert his/her attention to another place to see what code is executed.

*snip*

Lastly, the reason this is related to inline variables is because, it is extremely common to need a temporary variable which is useful in a very limited number of statements and have no business being declared and visible in the entire function/procedure.  This is the problem inline variables solve in a very deficient way.   Why design a good solution when a hack will do ?... it's so much easier to copy mediocrity (in this case from C.)
What do you mean/propose for "independent block" if it is not a nested procedure or the C-like {...} with inlined declarations?

@Weiss
Your opinion is quite welcome because as a new convert you can better judge unlike us who have been writing in pascal since decades.
The advantage of the inline variables is that you can control more precisely their scope by declaring them only where needed, presumably for the current (compound) or the next statement (for loop). It is not uncommon for someone even experienced to make a mistake and use the variable incorrectly again - see https://forum.lazarus.freepascal.org/index.php/topic,68067.msg525290.html#msg525290. No doubt, inlines are good here.
Another advantage is, not mentioned though, that the initialization part becomes part of the execution code and it is not required to be with constant expressions.
And here comes the 'type inference' - the thing that I'm (personally) not happy with. That is the ability to deduce the type of the variable by the type of the initializing expression. While convenient, this can lead to ambiguities and ultimately - more errors. I can remember a thread about the untyped constants type and signedness interpretation. I'm suspecting the same level of confusion here.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Curt Carpenter

  • Hero Member
  • *****
  • Posts: 564
Re: Question ?!!!!
« Reply #151 on: August 17, 2024, 08:33:11 pm »
I normally not just declare something, I always comment what is it, where used and why we need it etc. I do it for myself, it is like a documentation almost. My 2c

I wish I had the discipline to do that more often myself.   It's a kindness to anyone that may need to read your program someday (even if that someone is yourself). 

440bx

  • Hero Member
  • *****
  • Posts: 4735
Re: Question ?!!!!
« Reply #152 on: August 17, 2024, 08:57:11 pm »

What do you mean/propose for "independent block" if it is not a nested procedure or the C-like {...} with inlined declarations?
I presented a first step in this thread.  link to that post is:  https://forum.lazarus.freepascal.org/index.php/topic,43172.msg323311.html#msg323311

The advantages of that solution over the "begin"/"end" hack are many.  Among them: it's a real block therefore it can be exited from e.g, using break; It creates a visual demarcation for groups of statements that _should_ fulfill a logical task (a subtask within a function/procedure.)  Not only can variables be local but, so can be constants and types (apparently Delphi didn't define inline types.)  It eliminates the need to create a new function/procedure just because some statements need to be skipped (because as mentioned previously, the inline group of statements can be exited using break.)  IOW, it prevents having to isolate tiny pieces of code into "remote" (not inline) functions/procedures.

It has been proved that the easiest to understand and maintain processes are _linear_.  The more a process is broken into pieces and the larger the number of possible paths among the pieces, the more difficult the process is to understand and maintain.  (That's what makes spaghetti code difficult to maintain... spaghetti code doesn't need goto(s), all it needs is a large number of code strands whose organization is not obvious - linear organization is obvious.)




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

LV

  • Full Member
  • ***
  • Posts: 153
Re: Question ?!!!!
« Reply #153 on: August 17, 2024, 09:19:40 pm »
I recently came across this Pascal dialect called PascalABC.Net.
https://pascalabc.net/en/
In relation to the topic we're talking about, I thought I'd give it a try.
Here are the test results.

Code: Pascal  [Select][+][-]
  1. program test1;
  2. var
  3.   i: integer;
  4. begin
  5. for i := 1 to 3 do
  6.   writeln(i);
  7. end.
  8.  

Output:
1
2
3
----------------------------

Code: Pascal  [Select][+][-]
  1. program test2;
  2. var
  3.   i: integer;
  4. begin
  5. for i := 1 to 3 do
  6.   writeln(i);
  7.  writeln(i);
  8. end.
  9.  

Output:
1
2
3
3
----------------------------

Code: Pascal  [Select][+][-]
  1. program test3;
  2. begin
  3. for i: integer := 1 to 3 do
  4.   writeln(i);
  5. end.
  6.  

Output:
1
2
3
----------------------------

Code: Pascal  [Select][+][-]
  1. program test4;
  2. begin
  3. for i: integer := 1 to 3 do
  4.   writeln(i);
  5. writeln(i);
  6. end.
  7.  

Output:
test4.pas(5) : Undefined name reference 'i'
----------------------------

Code: Pascal  [Select][+][-]
  1. program test5;
  2. begin
  3. for i: integer := 1 to 3 do
  4.   writeln(i);
  5. begin
  6.   var i: integer = 30;
  7.   writeln(i);
  8. end;
  9. end.
  10.  

Output:
1
2
3
30
----------------------------

Code: Pascal  [Select][+][-]
  1. program test6;
  2. begin
  3. for i: integer := 1 to 3 do
  4.   writeln(i);
  5. begin
  6.   var i: integer = 30;
  7.   writeln(i);
  8. end;
  9. writeln(i);
  10. end.
  11.  

Output:
test6.pas(9) : Undefined name reference 'i'
----------------------------
« Last Edit: August 17, 2024, 09:36:32 pm by LV »

Curt Carpenter

  • Hero Member
  • *****
  • Posts: 564
Re: Question ?!!!!
« Reply #154 on: August 17, 2024, 09:28:14 pm »
It has been proved that the easiest to understand and maintain processes are _linear_.  The more a process is broken into pieces and the larger the number of possible paths among the pieces, the more difficult the process is to understand and maintain.  (That's what makes spaghetti code difficult to maintain... spaghetti code doesn't need goto(s), all it needs is a large number of code strands whose organization is not obvious - linear organization is obvious.)

Do object models in general violate that principle?

440bx

  • Hero Member
  • *****
  • Posts: 4735
Re: Question ?!!!!
« Reply #155 on: August 17, 2024, 10:05:13 pm »
Do object models in general violate that principle?
In practice they most definitely do.  In theory, I'm sure all OOP proponents would say they don't.  For the record, that's _all_ I'm going to say about OOP.  I am _not_ going down that road again.

There is one more thing I'd like to point out about something that is being associated with inline variables which has little to do with inline variables which is, in this code:
Code: Pascal  [Select][+][-]
  1. for var i : integer := 1 to 10 do ;
In that code the variable "i" isn't inline.  if anything it is "in for" <chuckle> which is a completely separate and, different, hack.

For those who doubt that, the following code doesn't work
Code: Pascal  [Select][+][-]
  1. for var i : integer := 1 to 10 do
  2. begin
  3.   var i : integer;
  4.   var x : integer;
  5.  
  6.   x := i * 2;
  7. end;

A compiler that allows defining the index variable in the "for" statement has to pretend the variable is declared within a "begin"/end" block even if one isn't present to prevent the redeclaration of the variable in a following "begin"/"end" associated with the "for" loop.  That's the problem with hacks... they have to account for inconsistencies created by the hack.

In case the above is not clear, the problem is: where does the scope start ? does it start at the "for" where "i" is declared ?  or does it start at the "begin" ? ... since you'll likely get a "duplicate identifier" the logical conclusion is that the scope starts in both places  (unless someone wants to claim an exception for the "for" statement but, that won't work because if the "begin" no longer starts a scope then the variable "x" cannot be declared in that location... :) )

(it's no wonder this stuff comes from C... <chuckle>)


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

alpine

  • Hero Member
  • *****
  • Posts: 1302
Re: Question ?!!!!
« Reply #156 on: August 17, 2024, 10:07:10 pm »

What do you mean/propose for "independent block" if it is not a nested procedure or the C-like {...} with inlined declarations?
I presented a first step in this thread.  link to that post is:  https://forum.lazarus.freepascal.org/index.php/topic,43172.msg323311.html#msg323311
Well, ... no!

The advantages of that solution over the "begin"/"end" hack are many.  Among them: it's a real block therefore it can be exited from e.g, using break;
You can break in the context of loops, not "blocks".

It creates a visual demarcation for groups of statements that _should_ fulfill a logical task (a subtask within a function/procedure.)
You can always use comments for a visual.

Not only can variables be local but, so can be constants and types (apparently Delphi didn't define inline types.)
Why you would need that? For that "block"? Everything there is local, remember? It is always wise to put named consts in front of everything else, preferably in a separate unit.

It eliminates the need to create a new function/procedure just because some statements need to be skipped (because as mentioned previously, the inline group of statements can be exited using break.)  IOW, it prevents having to isolate tiny pieces of code into "remote" (not inline) functions/procedures.
I don't create nested routines just because to be skipped. I create them because they'll do "a logical task" - small enough and with a meaningful name in order not to consult their code each time I encounter them. BTW you're not obliged to call a routine from more than one place, that (code reuse) is not the only reason for people to write them.

It has been proved that the easiest to understand and maintain processes are _linear_.  The more a process is broken into pieces and the larger the number of possible paths among the pieces, the more difficult the process is to understand and maintain.  (That's what makes spaghetti code difficult to maintain... spaghetti code doesn't need goto(s), all it needs is a large number of code strands whose organization is not obvious - linear organization is obvious.)
:o

Do object models in general violate that principle?
So it turns out as I read the above.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

alpine

  • Hero Member
  • *****
  • Posts: 1302
Re: Question ?!!!!
« Reply #157 on: August 17, 2024, 10:18:53 pm »
*snip*
In case the above is not clear, the problem is: where does the scope start ? does it start at the "for" where "i" is declared ?  or does it start at the "begin" ? ... since you'll likely get a "duplicate identifier" the logical conclusion is that the scope starts in both places  (unless someone wants to claim an exception for the "for" statement but, that won't work because if the "begin" no longer starts a scope then the variable "x" cannot be declared in that location... :) )

(it's no wonder this stuff comes from C... <chuckle>)
Please, go to https://www.freepascal.org/docs-html/ref/refsu58.html and put some effort to understand it. The for is a statement. It includes (after do) another statement. And please stop calling begin/end "delimiters" because they're terminal symbols which forms a compound statement.

EDIT: IOW:
Code: Pascal  [Select][+][-]
  1. begin
  2.    ...
  3.   begin
  4.     var i : integer;
  5.     for i := 1 to 10 do ;
  6.   end;
  7.   ...
  8.  
Happy?
« Last Edit: August 17, 2024, 10:25:58 pm by alpine »
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

440bx

  • Hero Member
  • *****
  • Posts: 4735
Re: Question ?!!!!
« Reply #158 on: August 17, 2024, 10:23:18 pm »
I'm afraid you need to understand that programming entails "a little more" than "for" statements.

It is possible to break out of a "for" statement ?... really ??? ... wow!! I had no idea... thank you so much for expanding my programming horizons.  :D

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

MarkMLl

  • Hero Member
  • *****
  • Posts: 8029
Re: Question ?!!!!
« Reply #159 on: August 17, 2024, 10:30:43 pm »
Please, go to https://www.freepascal.org/docs-html/ref/refsu58.html and put some effort to understand it. The for is a statement. It includes (after do) another statement. And please stop calling begin/end "delimiters" because they're terminal symbols which forms a compound statement.

I agree, and since the statement that follows do is not necessarily a compound statement starting with begin it is inappropriate (or, in layman's terms, flat-out wrong) to ascribe begin any significance whatsoever when delimiting the scope of an inline variable declaration.

Any declaration has to be preceded by a header saying /why/ it's being done (i.e. in the context of a program/function/procedure or tentatively a for statement etc.), and followed by a statement which might be a compound statement (i.e. delimited by begin...end).

Hence my earlier examples using /for/ (and, contentiously, /with/) as the header.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

MarkMLl

  • Hero Member
  • *****
  • Posts: 8029
Re: Question ?!!!!
« Reply #160 on: August 17, 2024, 10:36:31 pm »
It is possible to break out of a "for" statement ?

Yes, and at that point the control variable goes out of scope.

I don't give a damn who said that there were cases where it remained in scope. /break/ was added by either UCSD or Borland (can anybody identify which?) and it's /wrong/: if you want the control variable to persist you should use /while/ or /repeat/ both of which refer to a control variable initialised out-of-scope, hence which can be expected to persist out-of-scope.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

440bx

  • Hero Member
  • *****
  • Posts: 4735
Re: Question ?!!!!
« Reply #161 on: August 17, 2024, 11:51:54 pm »
if you want the control variable to persist you should use /while/ or /repeat/ both of which refer to a control variable initialised out-of-scope, hence which can be expected to persist out-of-scope.

MarkMLl
You must have missed the post where I stated as much. 
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8029
Re: Question ?!!!!
« Reply #162 on: August 17, 2024, 11:56:03 pm »
You must have missed the post where I stated as much.

No, it appears that you did :-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

PascalDragon

  • Hero Member
  • *****
  • Posts: 5755
  • Compiler Developer
Re: Question ?!!!!
« Reply #163 on: August 18, 2024, 12:21:54 pm »
I presume that your previous mention of DFA is Data Flow Analysis, which from my POV is Very Deep Magic Indeed.

Correct. :)

I see a lot of "it's not Pascal". Who determines if it's "Pascal"? A group of individuals? We did not invent Pascal, so how can you say something is not "Pascal"?

Because we maintain it. We work with it day in, day out. If we wouldn't do filtering of suggested features FPC would already be an ugly mess of intermingling featureitis. And the adding of Delphi features falls under this filtering as well.

The features we added due to Delphi compatibility pushed back what can be considered in the spirit of the language, but the separation between declaration and use is such a core principle of the language that many of use don't want to cross that line.

That's from the Extended Pascal standard. My point is, what "Looks" Pascal? Why stop the Delphi compatibility? If it's due to manpower/man hours, then allow others to come in and add it behind the {$MODE DELPHI} and you can still boast your Delphi Compatibility. Make that a goal. 100%. Then people can directly move newer Delphi units to Free Pascal again.

100% compatiblity is simply not possible, because there are some undocumented parts, not to mention bugs (just recently we found one in Delphi's expression parser that does not fit with the documented operator precedence and also how it works in different contexts).

Does the below from the (Extended Pascal standard) really look "Pascal"?
Code: Pascal  [Select][+][-]
  1. program PathTest;
  2. import
  3.   SysUtils qualified only (GetEnvironmentVariable => GetEnv);
  4. begin
  5.   WriteLn(SysUtils.GetEnv('PATH'));
  6. end.
  7.  

No, does not look like Pascal to me. But is there a compiler that thinks its Pascal ?

It is valid ISO Extended Pascal, but there aren't that many compilers - if any - out there that support it. However FPC is working step by step towards implementing it.

Quote
if FPC wants to keep compatibility with {$mode delphi} it probably will get implemented.
Why is it so important to keep compatibility with Delphi? Wouldn’t all the delphi users who want to switch to Lazarus have joined us by now?

Delphi users mainly waited for anonymous functions / function references and Extended RTTI as these are increasingly used in Delphi code. Inline variables can easily be converted to classic style, but these other features simply have no easy replacement.

In Delphi, you have two options: 1) You can use inline variables. 2) Or you can declare them outside the begin...end block as usual. It's up to you to decide which one you prefer. Am I wrong?

You forget two important points:
  • even if you don't use the feature you need to be able to understand it to read and understand third party code
  • the feature still needs to be maintained in the compiler

MarkMLl

  • Hero Member
  • *****
  • Posts: 8029
Re: Question ?!!!!
« Reply #164 on: August 18, 2024, 02:00:08 pm »
... but the separation between declaration and use is such a core principle of the language that many of use don't want to cross that line.

I fully agree, and that's why I argued an approach which relied on a header clause ("for" or "with" in my examples) to indicate that something was being defined. As I've said, "begin" won't work because the affected statement doesn't have to be a compound, and I /really/ don't like lobbing in "var" and hoping that a program's maintainer doesn't overlook it while speed-reading.

However I fully accept that that doesn't have the support of the core team, and would very much prefer it if we could finally put the threads discussing this to bed and keep our fingers crossed that the bug report is both favourably received and feasible to implement.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018