May I suggest "fluent interfaces" as an alternative to nested calls.
Instead of using a record like a dumb data store that is only manipulated from the outside, you can put the methods that fiddle with the record's contents directly into the record itself and thus keep the code and the data closely together. Also, this enables one to use a so-called "fluent interface".
Example:
This is an example of a record that contains just one integer member, "data". In real life, you can make the record as complex as you want.
type
pMyrecord=^tMyRecord;
tMyRecord=Record
data:integer;
Function Reset:pMyrecord;
Function Add (x:integer):pMyrecord;
Function Multiply (x:integer):pMyrecord;
Function Divide (x:integer):pMyrecord;
End;
As you can see, all the methods in this record return a pointer, which simply points to the record itself. That is the "secret sauce" one needs to implement fluent interfaces.
function tMyRecord.Add(x: integer): pMyrecord;
begin
data:=data+x;
result:=@self;
end;
function tMyRecord.Divide(x: integer): pMyrecord;
begin
data:=data div x;
result:=@self;
end;
function tMyRecord.Multiply(x: integer): pMyrecord;
begin
data:=data*x;
result:=@self;
end;
function tMyRecord.Reset: pMyrecord;
begin
data:=0;
result:=@self;
end;
Now the cool thing: All these methods can be concatenated and will be processed left-to-right. This produces very legible and compact code:
procedure Test;
var x:tmyrecord;
begin
x.reset.add(12).multiply(4).divide(2);
end;
(edit)
Note that I didn't do a single heap allocation here, never manually passed the record as a parameter and never did a nested call. The data lives on the stack.
If the record contains managed objects such as strings, these are disposed of automatically.