Sven Barth wroteOne could also do an alternative (though currently not with arrays, but with type helper support even that would be possible...):
Yes, this is certainly the most interesting alternative. Actually, anonymous procedures/closures
is the "real" task I wanted Vasily to perform, after the "warm-up" of for-in-index.
I am still of the opinion that "for-in-index" would be a good addition nevertheless,
because it is a simple and neat solution for 90% of the cases, so even if there exists
a general and complex solution for 100%, IMHO simple one is still worth having.
Nevertheless, I separated the thread to discuss anonymous procedures, hopefully with less flame, or at least, with flame of different colours :)
When comparing anonymous procedures with built-in for-in loop, it is important to consider the code speed.
I think that good support for inlining "Iterate" procedure *together with its argument*
is essential for anonymous procedures to be a competitive solution for the problem
of container iteration.
Show quoted text 5 lines
As you noted, this solution is conceptually good, but rather cumbersome to write
You have also proposed lambda-expressions:
map.Iterate(lambda TFPGMapLongInt.TIteratorProc(aKey, aData) as Writeln(aKey, ' => ', aData.ClassName));
I think that they are not optimal in the proposed form. Note that the longest part of the expression is actually a restatement of the Iterate parameter type.
I propose to allow omitting that:
map.Iterate(lambda begin
Writeln(aKey, ' => ', aData.ClassName);end;)
That is, basically, "lambda" means "use procedure definition from the parameter type".
Independently, I propose a general shorthand for functions containing a single expression
(and perhaps for procedures containing a single statement, but I am less certain here):
function f(a, b: Integer): Integer;
begin Result := a + b; end;
=>
function f(a, b: Integer): Integer as a + b;with both shortcuts combined, it becomes possible to write something like
sum := arr.Reduce(lambda as a + b;);
Even further, Ruby (or Objective C)-like extension may be introduced to allow
procedure arguments (or perhaps just the last one) to be separated by
some special character instead of parenthesis, for example:
procedure p(a, b: Integer);
p(3, 5); // Traditional syntax
p :3 :5; // Proposed extension
Then, then code will be
map.Iterate :lambda
Writeln(aKey, ' => ', aData.ClassName);
end;
sum := arr.Reduce :lambda as a + b;which is as good as it gets, IMHO.
And for a given array type and type helper support you can do the following:
While type helpers are a neat idea, I fear they introduce too much "action at a distance"
for so frequent usage.
A global generic functions (they are planned anyway, aren't they?) will be sufficient:
Iterate :map :lambda
Writeln(aKey, ' => ', aData.ClassName);
end;