Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2024-12

Procedural parameters

20 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Adriaan van Os

Macpascal and Iso pascal have procedural parameters, e.g.

	function A( function B: double): double;

Is there a $modeswitch to allow this ? I searched "procedure parameter" and "procedural parameter" in the Language Reference, but could not find anything.

Also, I wonder if "ISOPROGRAMPARAS" in the Programmer's Guide is spelled correctly.

Regards,

Adriaan van Os

Reply by email

Michael Van Canneyt
to Adriaan van Os
Adriaan van Os wrote 8 lines
Macpascal and Iso pascal have procedural parameters, e.g. function A( function B: double): double; Is there a $modeswitch to allow this ? I searched "procedure parameter" and "procedural parameter" in the Language Reference, but could not find anything.

As far as I know, the above is not allowed. you must declare the callback type explicitly.

TMyFunc = function : double;
function A(B : TMyFunc): double;

This is in line with 'declare before use':
procedure parameter lists cannot be used to declare types.

Similarly, you also cannot write:
function A(B : (one,two,three)) : double;
Also, I wonder if "ISOPROGRAMPARAS" in the Programmer's Guide is spelled correctly.

It is, as that is what is used in the compiler: globtype.pas:736

Michael.

Reply by email

Adriaan van Os
to Michael Van Canneyt
Michael Van Canneyt wrote 15 lines
On Sat, 14 Dec 2024, Adriaan van Os via fpc-pascal wrote: > > Macpascal and Iso pascal have procedural parameters, e.g. > > function A( function B: double): double; > > Is there a $modeswitch to allow this ? I searched "procedure > parameter" and "procedural parameter" in the Language Reference, but > could not find anything. As far as I know, the above is not allowed. you must declare the callback type explicitly.

It can in iso and macpascal mode. Read the Pascal standard.

Show quoted text 10 lines
As far as I know, the above is not allowed. you must declare the callback type explicitly. TMyFunc = function : double; function A(B : TMyFunc): double; This is in line with 'declare before use': procedure parameter lists cannot be used to declare types. Similarly, you also cannot write: function A(B : (one,two,three)) : double;

Not really. The function type declaration is a Borland invention, not original Pascal.

Regards,

Adriaan van Os

Reply by email

Hairy Pixels
to Adriaan van Os

On Dec 15, 2024 at 1:22:25 AM, Adriaan van Os via fpc-pascal <

Show quoted text 11 lines
wrote: Similarly, you also cannot write: function A(B : (one,two,three)) : double; Not really. The function type declaration is a Borland invention, not original Pascal. Regards, Adriaan van Os

You mean the original pascal only allowed function declarations to be parameter types?

Forcing function types and pointers to be type declaration only is now a limitation for generic procedures and should be reversed. No reason to be following what some Borland engineer was doing in the 80’s when it’s 2024.

procedure DoThis<T>(param: ^T);
procedure DoThis<T>(param: function(a, b: T): Boolean);

Regards,
Ryan Joseph

Reply by email

Adriaan van Os
to Hairy Pixels
Hairy Pixels wrote 16 lines
On Dec 15, 2024 at 1:22:25 AM, Adriaan van Os via fpc-pascal < > wrote: > Similarly, you also cannot write: > function A(B : (one,two,three)) : double; > > Not really. The function type declaration is a Borland invention, not > original Pascal. > > Regards, > > Adriaan van Os You mean the original pascal only allowed function declarations to be parameter types?

Yes. And it is still true in the ISO 7185 Pascal standard.

Regards,

Adriaan van Os

Reply by email

Hairy Pixels
to Adriaan van Os

On Dec 15, 2024 at 12:21:29 PM, Adriaan van Os via fpc-pascal <

Show quoted text 7 lines
wrote: You mean the original pascal only allowed function declarations to be parameter types? Yes. And it is still true in the ISO 7185 Pascal standard.

That doesn’t make any more sense than only allowing them as type declarations. I guess you couldn’t stored function pointers on variables or record fields then? Seems strange they would not support that.

Regards,
Ryan Joseph

Reply by email

Adriaan van Os
to Hairy Pixels
Hairy Pixels wrote 12 lines
On Dec 15, 2024 at 12:21:29 PM, Adriaan van Os via fpc-pascal < > wrote: > You mean the original pascal only allowed function declarations to be > parameter types? > > Yes. And it is still true in the ISO 7185 Pascal standard. That doesn’t make any more sense than only allowing them as type declarations. I guess you couldn’t stored function pointers on variables or record fields then? Seems strange they would not support that.

Storing function pointers on variables or record fields is a Turbo Pascal invention too.

Regards,

Adriaan van Os

Reply by email

Adriaan van Os
to Michael Van Canneyt: As far as I know, the above is not allowed. you must declare the callback type explicitly.
Michael Van Canneyt wrote
> Also, I wonder if "ISOPROGRAMPARAS" in the Programmer's Guide is > spelled correctly. It is, as that is what is used in the compiler: globtype.pas:736

I don't mind, but it is rather weird/amusing

Webster's dictionary

para
noun

A piece of Turkish money, usually copper, the fortieth part of a piaster, or about one ninth of a cent. Formerly, a subunit of currency in several countries in the Ottoman/Turkish and Yugoslav regions.

A woman who has had a certain number of pregnancies, indicated by the number prepended to this word.

plural paras or para

Regards,

Adriaan van Os

Reply by email

Michael Van Canneyt
to Adriaan van Os: It can in iso and macpascal mode. Read the Pascal standard. Not really. The function type…
Adriaan van Os wrote 18 lines
Michael Van Canneyt via fpc-pascal wrote: > > > On Sat, 14 Dec 2024, Adriaan van Os via fpc-pascal wrote: > >> >> Macpascal and Iso pascal have procedural parameters, e.g. >> >> function A( function B: double): double; >> >> Is there a $modeswitch to allow this ? I searched "procedure parameter" >> and "procedural parameter" in the Language Reference, but could not find >> anything. > > As far as I know, the above is not allowed. you must declare the callback > type explicitly. It can in iso and macpascal mode. Read the Pascal standard.

It's not because something is in the pascal standard, that FPC has it.

But if so, I was unaware and in that case I will document it.

Why they would put something as unreadable as that in the standard is a mystery to me.

Michael.

Reply by email

Jonas Maebe
to Hairy Pixels: On Dec 15, 2024 at 12:21:29 PM, Adriaan van Os via fpc-pascal < That doesn’t make any…
Hairy Pixels wrote 10 lines
On Dec 15, 2024 at 12:21:29 PM, Adriaan van Os via fpc-pascal < > wrote: > You mean the original pascal only allowed function declarations to be > parameter types? > > Yes. And it is still true in the ISO 7185 Pascal standard. That doesn’t make any more sense than only allowing them as type declarations.

It's because unlike in Borland Pascal, procvars in ISO Pascal captured the stack frame and allowed you to access local variables of the caller. By only allowing the declaration in the procedure header, this ensured the captured context could never escape the scope in which it was valid: after the scope in which it was valid was exited, the declaration would not longer exist either.

FPC does allow you to capture these outside the scope where they are valid (using "is nested" procvar declarations), but the result is also that you can call them once they are no longer valid.

Jonas

Reply by email

Hairy Pixels
to Jonas Maebe

On Dec 15, 2024 at 5:15:33 PM, Jonas Maebe via fpc-pascal <

Show quoted text 13 lines
wrote: It's because unlike in Borland Pascal, procvars in ISO Pascal captured the stack frame and allowed you to access local variables of the caller. By only allowing the declaration in the procedure header, this ensured the captured context could never escape the scope in which it was valid: after the scope in which it was valid was exited, the declaration would not longer exist either. FPC does allow you to capture these outside the scope where they are valid (using "is nested" procvar declarations), but the result is also that you can call them once they are no longer valid.

Ok that makes sense now. That’s interesting they crossed paths and never joined the two designs in any of the compilers.

My opinion currently is that anonymous procedure types in parameters are ugly/less readable but are better than the alternative of declaring types that are only ever intended for a single procedure anyways. I find it makes lots of types like “TMyProcedureCallback”which are single use and just introduce extra names so I side with the ISO standard over Borland here.

Also noteworthy is ISO standard can accommodate generics which Borland’s design can not. Did ISO standard allow pointer types in parameters too? It seems like an arbitrary choice to allow pointer types on fields but not parameters (same for procedures). Maybe another Borland idea?

Regards,
Ryan Joseph

Reply by email

Hairy Pixels
to Hairy Pixels
Hairy Pixels wrote
Also noteworthy is ISO standard can accommodate generics which Borland’s design can not.

Wait, I’m wrong on this, you can use generic proc types. The problem with generics are pointers to T. For example that below is not possible.

type
  generic TFindNodeComparator<T> = function(item: ^T): Boolean;
generic function FindNode<T>(func: specialize TFindNodeComparator<T>): ^T;

Regards,
Ryan Joseph

Reply by email

Adriaan van Os
to Michael Van Canneyt: It's not because something is in the pascal standard, that FPC has it. But if so, I was…
Michael Van Canneyt wrote 5 lines
On Sat, 14 Dec 2024, Adriaan van Os via fpc-pascal wrote: It's not because something is in the pascal standard, that FPC has it.

It is. Appendix D6 of the Programmer's Reference says

"This mode is selected by the $MODE ISO switch. On the command line, this mode is selected by the -Miso switch. In this mode, the compiler complies with the requirements of level 0 and level 1 of ISO/IEC 7185."

Regards,

Adriaan van Os

Reply by email

Sven Barth
to Hairy Pixels: On Dec 15, 2024 at 1:22:25 AM, Adriaan van Os via fpc-pascal < You mean the original…
Hairy Pixels wrote 7 lines
Forcing function types and pointers to be type declaration only is now a limitation for generic procedures and should be reversed. No reason to be following what some Borland engineer was doing in the 80’s when it’s 2024. procedure DoThis<T>(param: ^T); procedure DoThis<T>(param: function(a, b: T): Boolean);

The point is that Object Pascal defines that function parameters and result types can only be named types. A use of type definitions would mean that the declaration in the interface section would be different from the one in the implementation section, because that is how Object Pascal works.

Not to mention that changing this would lead to conflicts with the syntax for open arrays and dynamic arrays.

Regards,
Sven

Reply by email

Sven Barth
to Hairy Pixels: Wait, I’m wrong on this, you can use generic proc types. The problem with generics are…
Hairy Pixels wrote 11 lines
On Dec 15, 2024 at 6:28:25 PM, Hairy Pixels wrote: > Also noteworthy is ISO standard can accommodate generics which > Borland’s design can not. Wait, I’m wrong on this, you can use generic proc types. The problem with generics are pointers to T.  For example that below is not possible. type   generic TFindNodeComparator<T> = function(item: ^T): Boolean; generic function FindNode<T>(func: specialize TFindNodeComparator<T>): ^T;

It's not as if it is impossible to workaround this limitation:

=== code begin ===

program tpointerrec;
{$mode objfpc}
{$modeswitch advancedrecords}
type
   generic TPointer<T> = record
   type
     PT = ^T;
   end;
   generic TFindNodeComparator<T> = function(item: specialize
TPointer<T>.PT): Boolean;
generic function FindNode<T>(func: specialize TFindNodeComparator<T>):
specialize TPointer<T>.PT;
begin
end;
function Compare(item: specialize TPointer<LongInt>.PT): Boolean;
begin
end;
begin
   specialize FindNode<LongInt>(@Compare);
end.

=== code end ===

Regards,
Sven

Reply by email

Michael Van Canneyt
to Adriaan van Os: It is. Appendix D6 of the Programmer's Reference says "This mode is selected by the $MODE…
Adriaan van Os wrote 14 lines
Michael Van Canneyt via fpc-pascal wrote: > > > On Sat, 14 Dec 2024, Adriaan van Os via fpc-pascal wrote: > > It's not because something is in the pascal standard, that FPC has it. It is. Appendix D6 of the Programmer's Reference says "This mode is selected by the $MODE ISO switch. On the command line, this mode is selected by the -Miso switch. In this mode, the compiler complies with the requirements of level 0 and level 1 of ISO/IEC 7185."

Let's examine that statement for a second.

In my copy of the standard, section "6.1.3 Identifiers" starts with: "Identifiers can be of any length."

This is not implemented in FPC: identifiers are max 255 chars.

Section "6.1.4 Directives" states:
"The only directive shall be the required directive 'forward'"

But you can also pefectly compile in ISO mode

procedure a; cdecl; forward;

One can use semantic tricks and say that 'cdecl' is a modifier, unfortunately then still the above violates the syntax diagram in section 6.6.2, which leaves no room for 'modifiers'.

But either FPC follows the standard to the letter (that is why it is a standard), or it does not.

Both examples show that in the strict sense, FPC does not follow the standard, even in ISO mode. Probably more examples can be found.

For the quoted text to be painstakingly correct, the manual text should better be phrased as "The compiler tries to comply with..."

The alternative is that we're a little more flexible in our interpretation of standards and manuals or messages on this list, and then we accept that there may be extra or missing things in either standard and/or implementation.

Which I paraphrased loosely as:
"It's not because something is in the pascal standard, that FPC has it."

Michael.

Reply by email

Sven Barth
to Michael Van Canneyt

Michael Van Canneyt via fpc-pascal
schrieb am So., 15. Dez. 2024, 18:25:

Show quoted text 59 lines
On Sun, 15 Dec 2024, Adriaan van Os via fpc-pascal wrote: > Michael Van Canneyt via fpc-pascal wrote: >> >> >> On Sat, 14 Dec 2024, Adriaan van Os via fpc-pascal wrote: >> >> It's not because something is in the pascal standard, that FPC has it. > > It is. Appendix D6 of the Programmer's Reference says > > "This mode is selected by the $MODE ISO switch. On the command line, > this mode is selected by > the -Miso switch. In this mode, the compiler complies with the requirements > of level 0 and level 1 > of ISO/IEC 7185." Let's examine that statement for a second. In my copy of the standard, section "6.1.3 Identifiers" starts with: "Identifiers can be of any length." This is not implemented in FPC: identifiers are max 255 chars. Section "6.1.4 Directives" states: "The only directive shall be the required directive 'forward'" But you can also pefectly compile in ISO mode procedure a; cdecl; forward; One can use semantic tricks and say that 'cdecl' is a modifier, unfortunately then still the above violates the syntax diagram in section 6.6.2, which leaves no room for 'modifiers'. But either FPC follows the standard to the letter (that is why it is a standard), or it does not. Both examples show that in the strict sense, FPC does not follow the standard, even in ISO mode. Probably more examples can be found. For the quoted text to be painstakingly correct, the manual text should better be phrased as "The compiler tries to comply with..." The alternative is that we're a little more flexible in our interpretation of standards and manuals or messages on this list, and then we accept that there may be extra or missing things in either standard and/or implementation. Which I paraphrased loosely as: "It's not because something is in the pascal standard, that FPC has it."

As with any of the language dialect compatibility modes the point is that FPC can compile code in that dialect, but *not* that code that compiles in that dialect mode in FPC does also compile in another compiler that supports that dialect.

For example FPC allows global generic functions in mode Delphi while Delphi itself does not support them.

Regards,
Sven

Reply by email

Hairy Pixels
to Sven Barth: It's not as if it is impossible to workaround this limitation: === code begin === program…
Sven Barth wrote 19 lines
It's not as if it is impossible to workaround this limitation: === code begin === program tpointerrec; {$mode objfpc} {$modeswitch advancedrecords} type generic TPointer<T> = record type PT = ^T; end; generic TFindNodeComparator<T> = function(item: specialize TPointer<T>.PT): Boolean;

Yeah this works but look at this code now. I wasn’t there but I’m pretty sure the convention of “single names” for parameter types was for readability. There were no generics back then or even types in records so none of that would have been possible under their guidelines.

That function header violates the entire their concept of readability also and is a worse offender than ^T and possibly even the inline proc type could be considered worse.

generic function FindNode<T>(func: specialize TFindNodeComparator<T>):
specialize TPointer<T>.PT;

So the options are bad and worse, pick your poison.

Regards,
Ryan Joseph

Reply by email

Michael Van Canneyt
to Sven Barth: Michael Van Canneyt via fpc-pascal schrieb am So., 15. Dez. 2024, 18:25: As with any of…
Sven Barth wrote 12 lines
> > Which I paraphrased loosely as: > "It's not because something is in the pascal standard, that FPC has it." > As with any of the language dialect compatibility modes the point is that FPC can compile code in that dialect, but *not* that code that compiles in that dialect mode in FPC does also compile in another compiler that supports that dialect. For example FPC allows global generic functions in mode Delphi while Delphi itself does not support them.

I am aware. The point of my message was not to criticize the implementation.

The point of the message was that some flexibility in judgment is needed, and that this works in both directions: both more or less than what is in a standard can be expected. I gave examples of both situations.

Michael.

Reply by email