> On May 28, 2022, at 6:39 PM, Michael Van Canneyt via fpc-pascal 
> <fpc-pascal@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

_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to