The title is probably a bit misleading. I’m not going to talk about the “future of Delphi” rather about the concept of “future evaluation” in Delphi. You might have heard about the Delphi Prism product that Embarcadero/CodeGear is going to push into the market — it’s a new .NET language with pascal-ish syntax. It’s not related to the Delphi we’re all used to but rather a completely new language that was specifically designed to work on top of .NET framework. Prism has some very interesting language features (most being just syntax wrappers around .NET stuff) — you can read more about them here.
One of those features is the “future” concept. It is supposed to ease the development of multi-threaded programs quite a bit — splitting the workload on multiple CPUs. It’s an interesting idea and it took me a few minutes to come with a unit which provides basically the same functionality (thanks for anonymous methods and generics in Delphi 2009!) in Delphi/Win32. Take this example for instance:
var x, y : TFuture<Integer>; begin x := TFuture<Integer>.Create(function : Integer begin Sleep(2000); Exit(2); end); y := TFuture<Integer>.Create(function : Integer begin Sleep(3000); Exit(3); end); WriteLn('More code here ... executing on main thread.'); WriteLn('The value of x + y is: ', x.Value + y.Value); WriteLn('The value of x + y is (scnd): ', x.Value + y.Value); ReadLn; end.
The code simulates some lengthy operations, one taking 2 seconds and another taking 3 seconds. Both x, and y values are being computed asynchronously on 2 separate threads while the main thread will not be interrupted until the actual value of x and y is required (x.Value and y.Value). If the values of these “futures” is not yet available the main thread will block and wait for them. All subsequent calls to x.Value or y.Value will not block anymore because the values are now available as normal variables.
A few remarks about the code:
- There’s no syntax sugar like in Prism that can make writing this stuff easier, and maybe there shouldn’t be any — I am all for keeping the language clean.
- The code may be a bit slow because I start a new thread for each Future object created. This may be optimized by using a thread pool or a similar concept.
- I don’t know when and how does prism throw the exceptions that could appear on the asynchronous threads, but I assumed that exceptions should be thrown any time x.Value is being called (seems more logical to do so).
The unit code can be found here:
[download#36]