I have read the implementation of QuickSort algorithm in WL from Roman Maeder's Computer Science with Mathematica (2000).
The implementation is shown below.
SetAttributes[swap, {HoldFirst}]
swap[l_, i_, j_] := ({l[[i]], l[[j]]} = {l[[j]], l[[i]]}; l);
SetAttributes[QSort, HoldFirst]
QuickSort[list_] := Module[{l = list}, QSort[l, 1, Length[l]]; l];
QSort[l_, n0_, n1_] /; n0 >= n1 := l;
QSort[l_, n0_, n1_] :=
Module[{lm = l[[Floor[(n0 + n1)/2]]], i = n0, j = n1},
While[ True,
While[l[[i]] < lm, i++];
While[l[[j]] > lm, j--];
If[i >= j, Break[]];
swap[l, i, j];
i++; j--];
QSort[l , n0, i - 1];
QSort[l, j + 1, n1]
]
My question is why should we use HoldFirst
? Is it because we are modifying the argument l
and this is not allowed in the WL?
l
can be modified in place. This is implicit in the remarks already made but should be stated explicitly. Effectively theHold*
attributes, used in this way, provide a "call-by-reference" capability. $\endgroup$