program Y; {$APPTYPE CONSOLE} uses SysUtils; type YCombinator = class sealed class function Fix (F: TFunc, TFunc>): TFunc; static; end; TRecursiveFuncWrapper = record // workaround required because of QC #101272 (http://qc.embarcadero.com/wc/qcmain.aspx?d=101272) type TRecursiveFunc = reference to function (R: TRecursiveFuncWrapper): TFunc; var O: TRecursiveFunc; end; class function YCombinator.Fix (F: TFunc, TFunc>): TFunc; var R: TRecursiveFuncWrapper; begin R.O := function (W: TRecursiveFuncWrapper): TFunc begin Result := F (function (I: T): T begin Result := W.O (W) (I); end); end; Result := R.O (R); end; type IntFunc = TFunc; function AlmostFac (F: IntFunc): IntFunc; begin Result := function (N: Integer): Integer begin if N <= 1 then Result := 1 else Result := N * F (N - 1); end; end; function AlmostFib (F: TFunc): TFunc; begin Result := function (N: Integer): Integer begin if N <= 2 then Result := 1 else Result := F (N - 1) + F (N - 2); end; end; var Fib, Fac: IntFunc; begin Fib := YCombinator.Fix (AlmostFib); Fac := YCombinator.Fix (AlmostFac); Writeln ('Fib(10) = ', Fib (10)); Writeln ('Fac(10) = ', Fac (10)); end.