- DelphiTools - https://www.delphitools.info -

Helpers added to DWScript

In the SVN version, DWScript now has experimental support for helpers. This is a generalization of Delphi’s class helpers, which can be applied to (almost) any type. You can also have multiple helpers per type.

The syntax is currently the following:

type
   TMyHelper = helper for some_type_here
      private
         ...private helper methods, class vars & class consts...
      public
         ...public helper methods, class vars & class consts...
   end;

You can have helpers for base types, classes, records, interfaces or arrays.

For instance if you write

type TFloatHelper = helper for Float
      const PI = 3.141592;
      function ToString : String;
   end;
...
function TFloatHelper.ToString : String;
begin
   Result := FloatToStr(Self);
end;

then it allows you to code things like ‘Float.Pi‘ or ‘myFloatVar.ToString‘.

The literal form is also accepted (‘TFloatHelper.Pi‘ and ‘TFloatHelper.ToString(myFloatVar)‘).

It’s possible to have class methods in helpers, for types with a meta-symbol, Self will be that meta-symbol (f.i. for a TObject helper, Self would be TClass), for others (like Float or records), Self will not be defined.

Current limitations of the experimental support:

The scope resolution when there are multiple-helpers introducing the same method is at the moment not fully defined, currently the compiler will pick the first one it finds in scope. Other options are under considerations: using the same resolution logic as overloads, allowing helpers to be “sub-classed” and then using class-like resolution logic… if you have good ideas pilfered from other languages, or bad approaches that should be avoided, now is the time to chime in!

The syntax will also probably be extended to encompass the Delphi syntax (“class helper”) so you can share code, and maybe others variations (“interface helper”, “type helper”…) though which/how remains to be determined.

Once all the syntax and scoping elements have been finalized, the compiler will get proper optimizations, but for now, it’s expected to be somewhat less efficient.

Helpers on functions pointers/delegates types aren’t yet allowed, mostly because of ambiguity, f.i. in

type
   TFunc = function : Integer;
   TFuncHelper = helper for TFunc
      function ToString : String;
   end;
   TIntegerHelper = helper for Integer
      function ToString : String;
   end;
...
var f : TFunc;
f.ToString;

the “f.ToString” could be understood as meaning “TFuncHelper.ToString(f)” or “TIntegerHelper.ToString(f())” if helpers on function pointers were allowed. If a good resolution is found, they could be “helped” too, but helpers may not be very relevant to function pointers (?).