[fpc-pascal] Feature Announcement: Function References and Anonymous Functions

Hairy Pixels genericptr at gmail.com
Sat May 28 16:01:15 CEST 2022



> On May 28, 2022, at 6:39 PM, Michael Van Canneyt via fpc-pascal <fpc-pascal at lists.freepascal.org> wrote:
> 
> And I'm sure it finds these very understandable (live examples):
> 
> [s: string]: ((s: string, cb: (done: any) => void) => void) & ((cb: (done: any) => void) => void) & {only: any, skip: any};
> load: (url: string, onLoad: (object3D: THREE.Object3D) => void, onProgress?: (progress: ProgressEvent) => void, onError?: (event: ErrorEvent) => void) => void;
> function comp<A, B, C, D>(c: (c: C) => D, b: (b: B) => C, a: (a: A) => B): (a: A) => D;
> function comp<A, B, C, D, E>(d: (d: D) => E, c: (c: C) => D, b: (b: B) => C, a: (a: A) => B): (a: A) => E;
> singleton = _.memoize(<T>(classInstance: new () => T) => new classInstance());
> function cacheGetter(judgeFunc: () => boolean, returnCacheValueFunc: () => any, setCacheFunc: (returnVal: any) => void): (target: any, name: any, descriptor: any) => any;
> 

Yes I see your point here but this can happen to any language with closures and is something FPC needs to reckon with now. Having verbose function declarations could make these kind of nested closures even worse than this.

I’m not up to date on how languages like JavaScript are dealing with this problem in their inherently concurrent code but I think they’re moving away from callbacks and closures. See http://callbackhell.com.

My point has to do with the best case scenario where adding a function which mean the user needs to scroll up dozens of lines to see what the function does even though it may be only a single expression. This is very common for filter, map etc… container functions. Adding in a fat function declaration doesn’t help the programmer since they already know what the TList.Filter function does and the extra lines make it hard to see what the actual code does.

For example you want to filter out items from a list with a value of less than 10. The function is only a single expression so wrapping it up in a 3 extra lines of code is just obscuring the code in my opinion.

Swift even has a convention for if the last parameter is a function you can call it with something like this:

	list.Filter begin
			  result := $0 < 10;
		      end;

I really don’t see how the extra "function (item: integer): boolean” makes that easier to read or adds more information. Maybe if you started doing stupid nesting things it will make a difference?

list.Filter begin
              result := $0.PeformCheck begin
                                           result := $0 < 10;
                                         end;
            end;



list.Filter(function (item: integer): boolean
            begin
              result := item.PeformCheck(function: boolean
                                         begin
                                           result := self < 10;
                                         end);
            end);

They both look not great to me but I think this is more with the nesting aspect than the function declaration.

What about plain procedures with no parameters? 

timer.Finished(procedure
               begin
                 DoTheNextThing;
               end);

Or this:

timer.Finished(procedure begin DoTheNextThing end);

I’m just not seeing how it helps to write in the procedure keyword in these cases.

Anyways, it’s too early to know how this is going to work and I don’t do much concurrent code in Pascal so I likely won’t ever have a chance to write deeply nested functions but lets see what other people end of doing and how it looks.


Regards,
	Ryan Joseph



More information about the fpc-pascal mailing list