Recent

Author Topic: Set type parameter  (Read 2000 times)

simsee

  • Full Member
  • ***
  • Posts: 184
Set type parameter
« on: March 18, 2023, 07:40:10 pm »
Just out of curiosity: (see code) why can I have a parameter of type array of char, but not of type set of char and consequently must, in this second case, first define a new type? Thank you.

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$mode ObjFpc}
  3.  
  4. procedure Proc1(P : array of char);
  5. begin
  6. end;
  7.  
  8. procedure Proc2(P : set of char); //error
  9. begin
  10. end;
  11.  
  12. begin
  13. end.

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: Set type parameter
« Reply #1 on: March 18, 2023, 08:05:34 pm »
Everything should be declared before you use it (in Pascal). Open arrays are exception.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Kays

  • Hero Member
  • *****
  • Posts: 575
  • Whasup!?
    • KaiBurghardt.de
Re: Set type parameter
« Reply #2 on: March 18, 2023, 08:10:08 pm »
As a matter of fact you always need to specify a data type name (for value and variable parameters); “anonymous” data types are not permitted in the formal parameter list. The FPC – as extension – just allows (“open”) array of …, too, as you can see in the syntax diagram.
Yours Sincerely
Kai Burghardt

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: Set type parameter
« Reply #3 on: March 18, 2023, 08:19:49 pm »
As already hinted by the previous two posters:
Code: Pascal  [Select][+][-]
  1. procedure Proc1(P : array of char);
  2. begin
  3. end;
This does not define a function that takes a dynamic array as parameter, but is an open array, which is it's own type and semantic concept. It is a different type from when you use "array of ..." in a variable definition.

For example:
Code: Pascal  [Select][+][-]
  1. procedure DynamicArray(arr: TStringArray);
  2. begin
  3.   SetLength(arr, 3); // Works because it is a dynamic array
  4. end;
  5.  
  6. procedure OpenArray(arr: array of String);
  7. begin
  8.   SetLength(arr, 3); // Doesn't work because not an dynamic array
  9. end;  

Simply put, the construct "array of type" can be different things depending if it is in a parameter list or in a type definition

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: Set type parameter
« Reply #4 on: March 18, 2023, 08:33:39 pm »
Quote from: pascal
The FPC – as extension – just allows (“open”) array of …,
Isn't it for Delphi compatibility rather than FPC's own extension?
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Kays

  • Hero Member
  • *****
  • Posts: 575
  • Whasup!?
    • KaiBurghardt.de
Re: Set type parameter
« Reply #5 on: March 18, 2023, 08:56:33 pm »
Quote from: pascal
The FPC – as extension – just allows (“open”) array of …,
Isn't it for Delphi compatibility rather than FPC's own extension?
Indeed the notion of open arrays are of Borland Pascal’s origin. The wording wasn’t suggesting (or wasn’t meant to suggest) open arrays were FPC’s original idea. It is nevertheless an extension to Pascal. Some compilers support it, others don’t. Don’t be surprised if it doesn’t work with a different compiler. I just wanted to point that out.
Yours Sincerely
Kai Burghardt

simsee

  • Full Member
  • ***
  • Posts: 184
Re: Set type parameter
« Reply #6 on: March 18, 2023, 09:22:42 pm »
Thanks a lot for your explanations. An open array is not a type. However, the notion of open array has always seemed a bit strange to me. Wouldn't it have been easier to treat this kind of situation as a dynamic array type parameter?
« Last Edit: March 18, 2023, 09:28:53 pm by simsee »

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: Set type parameter
« Reply #7 on: March 19, 2023, 12:31:18 am »
I think that open arrays are one of the contenders for the worst constructs introduced to pascal. They look like dynamic arrays, behave in 80% of the time like dynamic arrays, and the only way most people find out that they are something different is by trying to use them as a dynamic array and it failing in the other 20%. It's not just not intuitive, this is counter intuitive design.

But open arrays actually have a bit of a justification for their existance. They allow to define a fixed but arbitrary number of parameters at compiletime. A dynamic array will be created at runtime, when you create a dynamic array of int with "[1, 2, 3]", it will allocate memory for 3 ints on the heap and fill that array. An open array on the other hand can be prepared more flexible. An open array is afaik nothing other than just 2 pointers, one pointing to the first element, one pointing to the last element. So for example the compiler can push the parameters on the stackframe for the called function and pass those parameters. If the parameters are constants, the compiler can create this as a hidden variable and pass those parameters to it.
It also works out of the box with both static and dynamic arrays, while if it were just a dynamic array, any static array would first need to be copied to a new memory location for the dynamic array.

As an example on how this looks compiled, check out this simple example: https://godbolt.org/z/6hGPP58nc
Code: Pascal  [Select][+][-]
  1. function Sum(arr: array of Integer): Integer;
  2. var
  3.   i: Integer;
  4. begin
  5.   Result := 0;
  6.   for i:=Low(arr) to High(arr) do
  7.     Result += arr[i];
  8. end;
  9.  
  10. procedure ReadAndSum;
  11. var
  12.   a, b, c, s: Integer;
  13. begin
  14.   ReadLn(a);
  15.   ReadLn(b);
  16.   ReadLn(c);
  17.  
  18.   s := Sum([a, b, c]);
  19.   WriteLn(s);
  20. end;

What happens to call sum is the following:
Code: ASM  [Select][+][-]
  1.         movl    %r12d,8(%rsp)
  2.         movl    %r13d,12(%rsp)
  3.         movl    %r14d,16(%rsp)
  4.         leaq    8(%rsp),%rdi
  5.         movl    $2,%esi
  6.         call    sum(array_of_longint)
As you can see, the 3 variables are pushed onto the stack, before calling the sum function. This way the whole construction of an dynamic array can be avoided.

Also not to mention they allow in the cdecl calling convention to be used as varadic function arguments to be compatible with C (e.g. for using or being used by other libraries or code)

So while I would fully agree that open arrays are not well designed, because of the fact that they are really unintuitive, the idea behind them is not that bad and they are actually useful
« Last Edit: March 19, 2023, 12:44:01 am by Warfley »

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: Set type parameter
« Reply #8 on: March 19, 2023, 09:16:16 am »
As far as I know it is not a Borland extension but part of ISO 7185 Pascal:
Code: Pascal  [Select][+][-]
  1. {$mode ISO}
  2. procedure Proc1(P : array of char);
  3. begin
  4. end;
  5. begin
  6. end.
FreePascal is usually rather strict with ISO.
Dynamic arrays, however, are not part of ISO and introduced much later and indeed by Borland.

So if there is any syntactic confusion, blame dynamic array syntax. IOW it is the other way around as has been written above.

The remarks about typing are correct, btw and the recommended way to handle strongly typed dynamic array parameters over array of const and/or open array parameters.

The above example also works in P5, which is more or less the reference implementation for ISO Pascal.
(And P5 compiles in FreePascal  8) )

Maybe Scott Franco can give you even Moore info (the latter is an inside joke). He is the in-house expert on ISO modes and a - occasionally visiting - forum member and author of many ISO compatible code, including P5. He is the one that stimulated Florian to pursue full ISO compliance.
« Last Edit: March 19, 2023, 10:05:09 am by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Kays

  • Hero Member
  • *****
  • Posts: 575
  • Whasup!?
    • KaiBurghardt.de
Re: Set type parameter
« Reply #9 on: March 19, 2023, 12:00:30 pm »
As far as I know it is not a Borland extension but part of ISO 7185 Pascal:
Thaddy, you don’t know if you evidently haven’t read the standards. ISO 7185 level 1 defines “conformant array parameters”. They look like this:
Code: Pascal  [Select][+][-]
  1. procedure foo(bar: array[minimum..maximum: integer] of integer);
Unlike the GPC, the FPC does not disable “rudimentary” features/extensions. Hence the ISO-modes compile (or ought to compile) a superset of ISO Pascal.
But open arrays actually have a bit of a justification for their existance. […]
Conformant array parameters provide the same advantages you mentioned. The only justification that matters is the sacred “Delphi compatibility”.
Yours Sincerely
Kai Burghardt

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: Set type parameter
« Reply #10 on: March 19, 2023, 02:39:52 pm »
They look like this:
Code: Pascal  [Select][+][-]
  1. procedure foo(bar: array[minimum..maximum: integer] of integer);
That is actually a really cool syntax, sadly it is not used anymore

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: Set type parameter
« Reply #11 on: March 19, 2023, 08:03:20 pm »
Thanks a lot for your explanations. An open array is not a type. However, the notion of open array has always seemed a bit strange to me. Wouldn't it have been easier to treat this kind of situation as a dynamic array type parameter?

No, because open array parameters allow you to construct these arrays on the fly (which till recent Delphi and FPC versions was not possible with dynamic arrays):

Code: Pascal  [Select][+][-]
  1. SomeFunc([42, 21, 7])

Also open array parameters support that you pass a single value:

Code: Pascal  [Select][+][-]
  1. var
  2.   v: LongInt;
  3. begin
  4.   SomeFunc(v); // note the missing [...]
  5. end;

Internally in contrast to dynamic array types (which are data structures contained on the heap) open array parameters are simply a pointer to the first element and a hidden size parameter.

440bx

  • Hero Member
  • *****
  • Posts: 4031
Re: Set type parameter
« Reply #12 on: March 19, 2023, 10:30:41 pm »
...simply a pointer to the first element and a hidden size parameter.
size or element count ?... I was under the impression it was element count, correct me if I'm wrong.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: Set type parameter
« Reply #13 on: March 19, 2023, 11:46:29 pm »
The second parameter is count-1.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

440bx

  • Hero Member
  • *****
  • Posts: 4031
Re: Set type parameter
« Reply #14 on: March 20, 2023, 12:53:40 am »
The second parameter is count-1.
Yes, you're right.  Since it's zero based, it's not strictly a count.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018