On Sat, Jan 26, 2013 at 5:17 AM, Sven Barth <pascaldra...@googlemail.com> wrote: > One 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. > map.Iterate(procedure(const aKey: String; const aValue: TObject) > begin > Writeln(aKey, ' => ', aValue.ClassName); > end; > ); 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; -- Alexander S. Klenin _______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel