In Mathematica, I create singly linked lists like so:
toLinkedList[x_List] := Fold[pair[#2, #1] &, pair[], Reverse[x]];
fromLinkedList[ll_pair] := List
A disclaimer: the following is a speculation. This seems to be related to the search for UpValues. It looks like this has been optimized for global variables (so that the system skips this step when it can determine that it can do that), but not for Module - generated local variables. To test this, assign HoldAllComplete attribute to pair, and the effect disappears (since then, UpValues are not checked for current):
SetAttributes[pair, HoldAllComplete];
In[17]:= ll = toLinkedList@RandomInteger[100, 10000];
Max[Table[Timing[whileLength[ll]], {1000}][[All, 1]]]
Out[18]= 0.047
HTH