X903%DMAFHT1.BITNET@CUNYVM.CUNY.EDU (Marc Wachowitz) (04/19/91)
Recently there were comments saying returning structures were difficult to implement or inefficient. I don't think this is the case. Just have the caller suplly the address where the result is expected. If it's a variable (i.e. the call was of the form variable := Func() ), the final code is the same as with VAR parameters, so it's obviously not particularly difficult or inefficient. If the call is part of an expression (which implies it's the argument of another procedure call), the caller just allocates the space for the argument on the call stack and passes its address to the structure-returning procedure. There is no temporary local variable in the callee, access goes through this address. So it's again the same as a VAR parameter. The only difference is that you don't need to supply variables explicitly, but they are implicitly allocated by the compiler on the call stack, which is probably not very expensive. Example, which also shows the usefulnes of structure returns, assuming there's a notation for structure values (meaning should be obvious): TYPE Complex = RECORD re, im: REAL END; PROCEDURE Sum(a, b: Complex): Complex; BEGIN RETURN Complex(a.re + b.re, a.im + b.im) END Sum; Similar definition for PROCEDURE Prod(a, b: Complex): Complex; Now you can write expressions like a := Sum(x, Prod(y, z)) similar to normal formulae (a := x + y * z). With VAR parameters only you had to write: PROCEDURE Add(VAR a: Complex; b: Complex); BEGIN a.re := a.re + b.re; a.im := a.im + b.im; END Sum; Similar for PROCEDURE Mul(VAR a: Complex; b: Complex); VAR temp: Complex; ... a := y; Mul(a, z); Add(a, x); Now imagine the expression were much more complex. You would end up playing the role for a FORmular TRANslator, instead of the compiler doing such simple things for you. Using pointers instead does provide for the same notation as the value passing method, but the performance penalty may be high if you must (read: cannot) cooperate with a traditional environment of library functions etc. This would only change if all variables were pointers (as in LISP systems), which would allow the application of generational incremental garbage collection. As far as I know, there's yet no implementation of this for "uncooperative" environments.