@ (4)
Did you miss out on the math unit ::)
1) Is it possible to use generics to define min() and max() for arbitrary types for which comparison operators exist, i.e. scalars rather than just classes etc.?
2) What range of compiler versions support this?
3) Can this be inlined efficiently?
4) Can this be generalised efficiently to support e.g. max([a, b, c]); ?
4) Can this be generalised efficiently to support e.g. max([a, b, c]); ?
As long as the types have builtin operators you should be able to do this with an open array parameter ("aVals: array of T").
Please note that FPC does not yet support implicit specializations (there exists a patch for it, but I've yet to review it), thus you need to specialize explicitly: specialize Max<Longint>([a, b, c]) or for mode Delphi: Max<LongInt>([a, b, c]) (though there might be situations where FPC does not yet parse an expression correctly as mode Delphi allows overloads of symbols (please report such ;) )).
OK. Must admit that I was thinking of reducing via recursion, i.e. Max([a, b, c]) becomes Max(a, Max([b, c])) and so on. Not sure that plays nicely with generics.
It shouldn't pose any problem; you can do it with a normal function, why wouln't you be able inside a generic (or class/record method, or type helper or whatever)? Provided the compiler can resolve the expression unambiguosly, all should be dandy :)
If you look at the generated assembly you can see it generating a jump instruction instead of a call. ;)
average := (REDUCE + arrayOfSomething) / Length(arrayOfSomething);
I remember that one minor problem was that there wasn't a predefined identity for each of the operators, and no obvious way of specifying one when an operator was redefined which impacts on applying e.g. REDUCE + to an empty array... arguably, it should be mandatory that e.g. the additive identity is redefined whenever the + operator is defined for a new type. Similar considerations apply to min and max values of types when the comparison operators are redefined.