Skip to content

Draft: Feature: Scoped With

With the introduction of managed records, it is now possible to have autmatic lifetime management of complex datastructures. These datastructures might hold expensive resources, so their lifetime should be kept as small as possible. Consider the following file reader:

fl:=openfile(filename, fmWrite);
fl.write(42);

Because fl is a local variable, it's lifetime starts with the entrance of the function, and ends with the end of the function. This means the file is opened for writing, and therefore blocked from other processes to open it, during the whole lifetime of the function, which can be very long.

Pascal does not have scoped variables, so this is expected behavior, with one exception, the with statement. When the with statement is called with a function call, it creates a temporary object for the result of the function:

with openfile(filename, fmWrite) do
  write(42);
// Is the same as
tmp:=openfile(filename, fmWrite);
tmp.write(42);

But with the difference to normal local variables that the scope is clearly semantically limited to the with statement. But right now the way temporary objects are handled within the compiler, they are like local variables initialized at the beginning of the function entrance and finalized in the end, meaning their state lives much longer than the with statement.

This MR changes that, by tagging the temporary objects as manually managed and by explicitly adding initialize and finalization code. Basically the code above now compiles down to:

initialize(tmp);
tmp:=openfile(filename, fmWrite);
try
  tmp.write(42);
finally
  finalize(tmp);
end;

Thereby limiting the lifetime of the temporary variable semantically only to the with statement.


I also added a second commit, which allows for the following

with const fl = openfile(filename, fmWrite) do
  fl.Write(42);

But I'm not yet fully happy with it for a few reasons:

  1. fl right now just references the temp object, which makes it right now impossible to make it visible to the debugger
  2. fl shouldn't be assignable, but right now fl := ... works. It should also not be constant because it's members must be changeable (fixed)
  3. It can be used to macro other variables, while giving the impression to create a new variable (especially problematic with the non constness)

But feel free to give comments and suggestions on that change as well

Edited by Frederic Kehrein

Merge request reports

Loading