Sign in Join

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

Mailing lists / fpc-devel / 2005-07

Function variables and overload

11 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

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

Marcel Martin

Hello,

Let's say there is a function

  function ICmp(A,B: PBigInt): SInt32;

and a TBigIntList class having the following method that can sort the list according to Cmp

  procedure TBigIntList.Sort(Cmp: TBigIntCompareFunc);

with, of course,

  type TBigIntCompareFunc = function(A,B: PBigInt): SInt32;

Now, if ICmp is not overloaded, there is no problem, the call

  L.Sort(@ICmp);

works. But, of course, it doesn't work if ICmp is overloaded. In fact, we cannot have both overloaded functions _and_ the the possibility to use them as variables. Yes, there are ways to fix the problem (no overload or embedding the overloaded functions in local functions) but none is really satisfying.

Would it be possible to get something like

  L.Sort(@ICmp(PBigInt,PBigInt));

in case ICmp is overloaded? If we could add the parameter types, there would be no more ambiguity, the compiler would exactly know which overloaded function it has to use.

When I ask 'would it be possible', I mean 'would it be possible without having to rewite all the compiler' ;-)

mm

Reply by email

Peter Vreman
to Marcel Martin
Show quoted text 33 lines
Hello, Let's say there is a function function ICmp(A,B: PBigInt): SInt32; and a TBigIntList class having the following method that can sort the list according to Cmp procedure TBigIntList.Sort(Cmp: TBigIntCompareFunc); with, of course, type TBigIntCompareFunc = function(A,B: PBigInt): SInt32; Now, if ICmp is not overloaded, there is no problem, the call L.Sort(@ICmp); works. But, of course, it doesn't work if ICmp is overloaded. In fact, we cannot have both overloaded functions _and_ the the possibility to use them as variables. Yes, there are ways to fix the problem (no overload or embedding the overloaded functions in local functions) but none is really satisfying. Would it be possible to get something like L.Sort(@ICmp(PBigInt,PBigInt)); in case ICmp is overloaded? If we could add the parameter types, there would be no more ambiguity, the compiler would

There is ambiguity with a normal call to the function. The compiler sees the ( and thinks it is parsing a call to Icmp().

Reply by email

peter green
to Peter Vreman
Show quoted text 11 lines
> > Would it be possible to get something like > > L.Sort(@ICmp(PBigInt,PBigInt)); > > in case ICmp is overloaded? If we could add the parameter > types, there would be no more ambiguity, the compiler would There is ambiguity with a normal call to the function. The compiler sees the ( and thinks it is parsing a call to Icmp().

and then sees a type identifier in a syntax thats not a typecast which makes it totally clear that this can't be a call.

i dunno how much complexity supporting this syntax would add to the parser though.

Reply by email

Florian Klaempfl
to peter green
peter green wrote 13 lines
>>Would it be possible to get something like >> >> L.Sort(@ICmp(PBigInt,PBigInt)); >> >>in case ICmp is overloaded? If we could add the parameter >>types, there would be no more ambiguity, the compiler would > >There is ambiguity with a normal call to the function. The compiler sees >the ( and thinks it is parsing a call to Icmp(). > and then sees a type identifier in a syntax thats not a typecast which makes it totally clear that this can't be a call.

Really ;)?

What about @ICmp(TObject) ?

Show quoted text 8 lines
i dunno how much complexity supporting this syntax would add to the parser though. _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Bram Kuijvenhoven
to Peter Vreman: There is ambiguity with a normal call to the function. The compiler sees the ( and thinks…
Peter Vreman wrote 9 lines
>Would it be possible to get something like > > L.Sort(@ICmp(PBigInt,PBigInt)); > >in case ICmp is overloaded? If we could add the parameter >types, there would be no more ambiguity, the compiler would There is ambiguity with a normal call to the function. The compiler sees the ( and thinks it is parsing a call to Icmp().

So, perhaps it would be nice if there was a way to declare an alias for overloaded functions? E.g.

type
  TNoParamFunc = function:boolean;
  TIntParamFunc = function(i:integer):boolean;
function MyOverloadedFunc:boolean; alias MyOverLoadedFuncNoParams;
function MyOverloadedFunc(i:integer):boolean; alias MyOverLoadedFuncInt;
procedure MyProc(f:TNoParamFunc);
procedure MyProc(f:TIntParamFunc); // so MyProc is also overloaded

...

MyProc(@MyOverLoadedFuncNoParams);
MyProc(@MyOverLoadedFuncInt);

This example also demonstrates exactly why we can't use the list of possible parameter types of MyProc in order to determine which overloaded function to pass.

One might argue this 'alias' construction takes away the purpose of overloading functions (which, simply put, is convenience for the programmer I think), but that is not neccessarily true because you only need to use the 'long' alias in relatively rare cases such as MyProc(@MyOverloadedFunc).

Another note is that the 'alias' keyword might already be in use for some other purpose (I don't exactly remember which), so we might need another keyword or construction to give alias names.

Regards,

Bram

Reply by email

Marcel Martin
to Peter Vreman: There is ambiguity with a normal call to the function. The compiler sees the ( and thinks…
Peter Vreman wrote 37 lines
>Hello, > >Let's say there is a function > > function ICmp(A,B: PBigInt): SInt32; > >and a TBigIntList class having the following method that can >sort the list according to Cmp > > procedure TBigIntList.Sort(Cmp: TBigIntCompareFunc); > >with, of course, > > type TBigIntCompareFunc = function(A,B: PBigInt): SInt32; > > >Now, if ICmp is not overloaded, there is no problem, the call > > L.Sort(@ICmp); > >works. But, of course, it doesn't work if ICmp is overloaded. >In fact, we cannot have both overloaded functions _and_ the >the possibility to use them as variables. Yes, there are >ways to fix the problem (no overload or embedding the >overloaded functions in local functions) but none is really >satisfying. > >Would it be possible to get something like > > L.Sort(@ICmp(PBigInt,PBigInt)); > >in case ICmp is overloaded? If we could add the parameter >types, there would be no more ambiguity, the compiler would There is ambiguity with a normal call to the function. The compiler sees the ( and thinks it is parsing a call to Icmp().

Yes. I already encountered this problem when using a function variable.
Ok. And this way

    L.Sort(@ICmp:PBigInt:PBigInt);

and if ever ICmp was overloaded but had no parameter

    L.Sort(@ICmp);

Well, of course, I don't know the compiler enough to propose something clean and not ambiguous but the problem is not to find a way to tell the compiler "Use this routine and not an other one", I am sure it is not too much difficult. No, the problem is "Is it easy to modify the parser in order to implement it?".

It would really be nice to be able to use overloaded routines as non overloaded ones. At the moment, in order not to lose the possibility to transmit routines to lists, like

   procedure TBigIntList.ForEach(Proc: TBigIntBinaryOperator;
     A: PBigInt; Test: TBigIntTestFunc=nil);
   // add A to all even integers of the list
   L.ForEach(@IAdd,A,@IIsEven);
   which is much faster than
   for i := 0 to L.Count-1 do
     if IIsEven(L[i]) then IAdd(L[i],A);

I suppressed most overloaded routines by adding suffixes: IAddUI32, IAddSI32, IAddUI64, etc. It works but that's rather ugly :-)

To conclude, if you cannot add such a feature to FPC, you cannot. Don't worry, FPC is already very good as it is.

mm

Reply by email

Hans-Peter Diettrich
to Bram Kuijvenhoven: So, perhaps it would be nice if there was a way to declare an alias for overloaded…
Bram Kuijvenhoven wrote
function MyOverloadedFunc:boolean; alias MyOverLoadedFuncNoParams; function MyOverloadedFunc(i:integer):boolean; alias MyOverLoadedFuncInt; Another note is that the 'alias' keyword might already be in use for some other purpose (I don't exactly remember which), so we might need another keyword or construction to give alias names.

I'd prefer the import syntax, using "name" instead of "alias".

DoDi

Reply by email

Gerhard Scholz
to Hans-Peter Diettrich

...

Show quoted text 6 lines
Bram Kuijvenhoven wrote: > function MyOverloadedFunc:boolean; alias MyOverLoadedFuncNoParams; > function MyOverloadedFunc(i:integer):boolean; alias MyOverLoadedFuncInt; > Another note is that the 'alias' keyword might already be in use for some

other purpose (I don't exactly remember which), so we might need another keyword or construction to give alias names.

I'd prefer the import syntax, using "name" instead of "alias". DoDi

ALIAS is already in use for giving a proc another external name, but in the form

    procedure ping ; alias : 'pang' ;

(remark the colon followed by string)

so, the form

    procedure ping; alias pong ;

should be parsable by the compiler. Still conbinations would be valid:

    procedure ping ; alias pong ; alias : 'pang'

I think this looks better than using the NAME keyword.

IMHO the really worst solution would be to introduce a new keyword. This inflation of keywords is a similar horror as inflation of money, and forces me from time to time to change sources.

Gerhard

Reply by email

Peter Vreman
to Bram Kuijvenhoven: So, perhaps it would be nice if there was a way to declare an alias for overloaded…
you wrote 20 lines
Peter Vreman wrote: >>Would it be possible to get something like >> >> L.Sort(@ICmp(PBigInt,PBigInt)); >> >>in case ICmp is overloaded? If we could add the parameter >>types, there would be no more ambiguity, the compiler would >There is ambiguity with a normal call to the function. The compiler sees >the ( and thinks it is parsing a call to Icmp(). So, perhaps it would be nice if there was a way to declare an alias for overloaded functions? E.g. type TNoParamFunc = function:boolean; TIntParamFunc = function(i:integer):boolean; function MyOverloadedFunc:boolean; alias MyOverLoadedFuncNoParams; function MyOverloadedFunc(i:integer):boolean; alias MyOverLoadedFuncInt;

You can already do this, only with some extra typing:

function MyOverloadedFunc:boolean; public name 'MyOverLoadedFuncNoParams';
function MyOverloadedFunc(i:integer):boolean; public name
'MyOverLoadedFuncInt';
function MyOverLoadedFuncNoParams:boolean; external name
'MyOverLoadedFuncNoParams';
function MyOverLoadedFuncInt(i:integer):boolean; external name
'MyOverLoadedFuncInt';

Peter

Reply by email

Bram Kuijvenhoven
to Peter Vreman
Peter Vreman wrote 15 lines
At 22:45 1-7-2005, you wrote: > function MyOverloadedFunc:boolean; alias MyOverLoadedFuncNoParams; > function MyOverloadedFunc(i:integer):boolean; alias MyOverLoadedFuncInt; You can already do this, only with some extra typing: function MyOverloadedFunc:boolean; public name 'MyOverLoadedFuncNoParams'; function MyOverloadedFunc(i:integer):boolean; public name 'MyOverLoadedFuncInt'; function MyOverLoadedFuncNoParams:boolean; external name 'MyOverLoadedFuncNoParams'; function MyOverLoadedFuncInt(i:integer):boolean; external name 'MyOverLoadedFuncInt';

This trick indeed works :)

Considering again why Marcel Martin actually asked for a feature to distinguish overloaded functions, maybe the aliases have limited use.

The function ICmp is mostly used in the context of passing it to sort functions or perhaps a container like a redblack tree or a heap (which need to know how to sort the items they store). In all these cases, it might be required to identify which ICmp function to use. A syntaxis like @ICmp:integer:integer or @ICmp(integer,integer) is more typing that ICmpII or some other short 'alias'. The only difference is that for ICmpII one needs to explictly declare the alias (using the trick you mentioned).

If ICmp was also called directly many times, then having the short form ICmp(myvar,myothervar) is easier to use than ICmpII(myvar,myothervar). In this case, the alias is useful.

A larger improvement would be reached by examining the context where the @ICmp is assigned to, e.g. the parameter type of the function you are passing @ICmp to, or perhaps the type of MyCmpProc in This however can be ambiguous in case the you are passing @ICmp to an overloaded function (as I mentioned shortly before). In that case the programmer might need to explicitly identify which overloaded function of ICmp to pass. Anyway, the feature of deriving the meaning of @ICmp from the context could save more typing and ease changing the type of variables more than when using only aliases (using the public name/external name trick or a new feature).

However, the 'context' feature sounds like 'not easy to implement' and 'dangerous because of unclear side effects' to me. So what is 'possible', as Marcel Martin said: When I ask 'would it be possible', I mean 'would it be possible without having to rewite all the compiler'?

Personally I think maybe other features have more priority at the moment - I hope to see generics one day (these definitely help a lot in the area of type-safe containers) - but of course that is up to the developers to decide :)

Regards,

Bram

Reply by email

Marco van de Voort
to peter green: and then sees a type identifier in a syntax thats not a typecast which makes it totally…
peter green wrote 13 lines
> > > > Would it be possible to get something like > > > > L.Sort(@ICmp(PBigInt,PBigInt)); > > > > in case ICmp is overloaded? If we could add the parameter > > types, there would be no more ambiguity, the compiler would > > There is ambiguity with a normal call to the function. The compiler sees > the ( and thinks it is parsing a call to Icmp(). > and then sees a type identifier in a syntax thats not a typecast which makes it totally clear that this can't be a call.

Types can be parameters to

procedure x ( a : tclass);

..
..

x(tobject);

Reply by email