Pass-by-reference

All parameters (mutable or immutable, primitive or composite) are passed by-reference. In other words, the formal parameter in the callee is an alias of the actual parameter in the caller.

In some cases, for example, in the case of an immutable scalar, pass-by-value yields the same behavior as pass-by-reference. In such cases, the compiler might choose to optimize the code by internally implementing pass-by-value, since there is no observable difference to the user.
Note: The pass-by-reference semantics of parameters stands in contrast to the deep-copy semantics of assignments. For more information, see Value semantics.
Function parameters have by-reference semantics (like T &v in C++) because copying large data into a function would be inefficient when it is operating on only a small part of that data. The following example illustrates SPL's parameter passing semantics:
 void callee(mutable list<int32> x, mutable list<int32> y) {
   x[0] = 1;
   y = [3,4];
 }
 void caller() {
   mutable list<int32> a = [0,0], b = [0,0,0];
   callee(a, b);
 }

The assignment x[0]=1 in the callee yields a[0]==1 in the caller. And the assignment y=[3,4] in the callee yields b==[3,4] in the caller. If the caller passes a computed value that does not have a storage location, then the callee stores it in a temporary, but modifications have no side effect on the caller. If you prefer by-value semantics for parameters, you can easily emulate them by copying the by-reference parameters into local variables.