Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!hp4nl!charon!dik From: dik@cwi.nl (Dik T. Winter) Newsgroups: comp.lang.misc Subject: Arrays in languages (was: Anyone want to design a language?) Message-ID: <8836@boring.cwi.nl> Date: 25 Feb 90 01:58:53 GMT References: <3528@tukki.jyu.fi> <14251@lambda.UUCP> Sender: news@cwi.nl (The Daily Dross) Organization: CWI, Amsterdam Lines: 115 In article <14251@lambda.UUCP> jlg@lambda.UUCP (Jim Giles) writes: > In fact, for programs of any really useful size, passing > array arguments is vital. In this respect, at least, C really _DOESN'T_ > have arrays. > But in this aspect Fortran (at least upto and including 77) does not have arrays either. Let's compare some languages (for a matrix-vector product routine*): Algol 68: .proc matvec = (.ref [,] .real m, .ref [] .real v) .ref [] .real: ( [1 .lwb m:1 .upb m] .real result; .co assert correct bounds .co .if 2 .lwb m < .lwb v .or 2 .upb m > .upb v .then .skip .co error detected! .co .fi .for i .from 1 .lwb m .to 1 .upb m .do .ref .real sum = result[i]; sum:= 0.0; .for j .from 2 .lwb m .to 2 .upb m .do sum += m[i,j] * v[j] .od .od; result ) Ada: with LA_PACK; -- defines types MATRIX, VECTOR etc. use LA_PACK; function MATVEC(M: MATRIX; V: VECTOR) return VECTOR is RESULT: VECTOR(M'FIRST(1) .. M'LAST(1)); SUM: FLOAT; begin -- assert correct bounds if M'FIRST(2) < V'FIRST or else M'LAST(2) > V'LAST then raise ARRAY_BOUNDS_ERROR; end if; for I in M'RANGE(1) loop SUM = 0.0; for J in M'RANGE(2) loop SUM = M(I,J) * V(J) + SUM; end loop; RESULT(I) = SUM; end loop; return RESULT; end MATVEC; Fortran: SUBROUTINE MATVEC(M, V, W, L1M, U1M, L2M, U2M) C NO FUNCTION, FORTRAN CANNOT RETURN ARRAYS INTEGER L1M, U1M, L2M, U2M, I, J REAL M(L1M:U1M,L2M:U2M), V(L2M:U2M), W(L1M:U1M), SUM C NO BOUND CHECKING POSSIBLE DO 20 I = L1M, U1M SUM = 0.0 DO 10 J = L2M, U2M SUM = M(I,J) * V(J) + SUM 10 CONTINUE W(I) = SUM 20 CONTINUE RETURN END C (Fortran style (you can write Fortran in any language!)): void matvec(m, v, w, l1m, u1m, l2m, u2m) /* No function, C cannot return arrays. It can return pointers, but then we need malloc, and how to free the stuff? (Garbage collection of course!) */ int l1m, u1m, l2m, u2m; float *m, *v, *w; #define M(i,j) m[(u2m - l2m + 1) * i + j] #define V(i) v[i] #define W(i) w[i] { int i, j; float sum; /* No bound checking possible. */ for(i = l1m; i <= u1m; i++) { sum = 0.0; for(j = l2m; j <= u2m; j++) { sum += M(i,j) * V(j); } W(i) = sum; } } You can write it in C in C style of course; it looks a bit different. Anyhow, I think I made my point. C and Fortran are not very different with respect to arrays. Except of course that Fortran disallows aliasing, while C does not (hence the Fortran compiler can vectorize the above text, while a C compiler can not). Clearly Algol 68 and Ada, that supports arrays in their fulll glory, are superior with the possibility of array bound checking etc.. Both in Fortran and C a routine receives an address and defines its own indexing function, so both in Fortran and C it is possible to give the array a different shape in the callee when compared to the caller. This is impossible in languages that have complete support for arrays. (And note that one of the most important packages in Fortran, the BLAS, makes much use of it!) But I do not think that is a feature, it looks more like a bug. You might argue that the C define for M(i,j) is complicated. I would agree, Fortran has a simple syntactic description for (essentially) the same definition. If you continue to say that in Fortran it is more clear to the compiler that rows of a matrix are accessed, I am going to scream. Everybody will agree that a good optimizing C compiler will compile the C source to essentially the same code as a good optimizing Fortran compiler does with the Fortran source (everybody, except Piercarlo Grandi of course). -- (*) Yes, I know, this is not the best (vectorizing) code for a matrix- vector product. -- dik t. winter, cwi, amsterdam, nederland dik@cwi.nl