|
Yes, but this example of matrix multiplication does weird stuff: {$MODE DELPHI}
{$modeswitch advancedrecords}
type
TMatrix<T, R, C> = record
fCoordinates: array[R, C] of Double;
end;
function mul<T, R, X, C>(A: TMatrix<T, R, X>; B: TMatrix<T, X, C>): TMatrix<T, R, C>;
var
i: R;
j: X;
k: C;
begin
Writeln('yep');
Writeln(High(R)); // 3
Writeln(High(X)); // 4
Writeln(High(C)); // 3
for i := Low(R) to High(R) do
for k := Low(C) to High(C) do begin
Result.fCoordinates[i, k] := 0;
for j := Low(X) to High(X) do
Result.fCoordinates[i, k] += A.fCoordinates[i, j] * B.fCoordinates[j, k]
end
end;
type
R1 = 1..3;
R2 = 1..4;
var
A: TMatrix<Double, R1, R2>;
B: TMatrix<Double, R1, R1>;
C: TMatrix<Double, R2, R1>;
begin
mul<Double, R1, R2, R1>(A,B); // should fail because B would have to have as many rows as A has columns--and it doesn't.
mul(A,C) // does not work even with a right-size C--even though it should
end.
|
The first bit is an interesting case and i wonder why it happens. It seems the root cause is that it considers the two type specializations equivalent as even ignoring the generic functions something like "A:=B" is allowed. I trimmed the code down to this:
This is clearly a bug and not intentional behavior as doing the specialization by hand shows an error as expected. Also it seems related to multidimensional arrays as with a single element it also shows an error. Note that the other way (B:=A) doesn't work, so my guess is that at some point the type compatibility comparison only checks if assigning one array would fit memory-wise into the other.I'll check against latest trunk later and if it happens i'll file a bug report.