Delphi Mode - Reference
This article provides a detailed breakdown of all the Tusk
features disabled by Delphi Mode.
In Delphi Mode, date/time literals
are not allowed.
Instead, use traditional Delphi functions such as
StrToDate and StrToDateTime.
For example, instead of this…
var Start := #(1/1/2000 4pm);
In Delphi Mode, do this…
var Start := StrToDateTime('1/1/2000 4pm');
In Delphi Mode, decimal literals
are not allowed.
Instead, leverage the implicit cast to
Decimal from
Integer, Double, or string.
For example, instead of this…
var Amount := 4.23m;
In Delphi Mode, do this…
var Amount: Decimal := '4.23';
In Delphi Mode,
JavaScript-style string literals
are not allowed.
Instead, use traditional Delphi-style string literals.
For example, instead of this…
var Prompt := "Press ENTER to delete C:\\Temp";
In Delphi Mode, do this…
var Prompt := 'Press ENTER to delete C:\Temp';
In Delphi Mode,
IPropBag literals
are not allowed.
Instead, use NewPropBag
or BuildPropBag.
For example, instead of this…
var Bag := { a: 1, b: True, c: 3.5 };
In Delphi Mode, do this…
var Bag := BuildPropBag
.Prop('a', 1)
.Prop('b', True)
.Prop('c', 3.5)
;
In Delphi Mode, the
exponentiation operator
is not allowed.
Instead, use traditional Delphi functions
such as Power
or IntPower.
For example, instead of this…
var XCubed := x ** 3;
In Delphi Mode, do this…
var XCubed := IntPower(x, 3);
In Delphi Mode, the
topmost operator
is not allowed.
Instead, either avoid hiding names from outer scopes,
or provide aliases.
For example, instead of this…
function Demo: Double;
const
pi = Unicode.SmallPi;
begin
Result := /Pi;
Writeln(pi, ' = ', Result);
end;
In Delphi Mode, avoid hiding Pi…
function Demo: Double;
const
SmallPi = Unicode.SmallPi;
begin
Result := Pi;
Writeln(SmallPi, ' = ', Result);
end;
…or provide an alias…
function Demo: Double;
const
SysPi = Pi;
pi = Unicode.SmallPi;
begin
Result := SysPi;
Writeln(pi, ' = ', Result);
end;
In Delphi Mode, the
{$Hide} directive
is not allowed.
In Delphi Mode, the
from…use
statement is not allowed.
In Delphi Mode,
trailing punctuation
is not allowed.
Instead, format the code as you would in Delphi.
In Delphi Mode,
one-line routines
are not allowed.
Instead, supply a begin / end block
as you would in Delphi.
For example, instead of this…
function GetCount = Length(GetUserName) ** 2;
In Delphi Mode, do this…
function GetCount: Double;
begin
Result := Length(GetUserName) ** 2;
end;
In Delphi Mode,
optional declarations
are not allowed.
In Delphi Mode, initializers
in local var blocks are not allowed.
In Delphi Mode,
indexed for loops
are not allowed.
Instead, define and manage a separate index variable
as you would in Delphi.
For example, instead of this…
for var v at var i in ls do
Writeln('ls[', i, '] = ', v);
In Delphi Mode, do this…
var i := 0;
for var v in List do begin
Writeln('List[', i, '] = ', v);
Inc(i);
end;
Just be careful when using Continue in such loops:
you need to increment i with each iteration.
In Delphi Mode,
strict case statements
are not allowed.
Instead, as you would in Delphi,
raise an exception at runtime using the else keyword.
For example, instead of this…
var Status: TYesNo;
case:strict Status of
ynUnknown: Writeln('Uncertain');
ynNo: Writeln('No');
ynYes: Writeln('Yes');
end;
In Delphi Mode, do this…
var Status: TYesNo;
case Status of
ynUnknown: Writeln('Uncertain');
ynNo: Writeln('No');
ynYes: Writeln('Yes');
else InternalError;
end;
In Delphi Mode, the
call suppression operator
is not allowed.
Instead, use casts or explicit types
to prevent unwanted function calls.
For example, instead of this…
function GetCount: Double;
begin
Result := Length(GetUserName) ** 2;
end;
// Make an alias to GetCount...
var f := @@GetCount;
In Delphi Mode, use an explicit type…
function GetCount: Double;
begin
Result := Length(GetUserName) ** 2;
end;
type DoubleFunc = function: Double;
// Make an alias to GetCount...
var f: DoubleFunc := GetCount;
Or use a typecast…
function GetCount: Double;
begin
Result := Length(GetUserName) ** 2;
end;
type DoubleFunc = function: Double;
// Make an alias to GetCount...
var f := DoubleFunc(GetCount);
Tusk only adds an implicit function call if doing so
does not create a type mismatch.
In both examples above, Tusk knows that the desired type
is a function returning Double, so it concludes that calling
GetCount leads to a conflict between Double and a function
returning Double.
In Delphi Mode, the
Any and
NoCall types are not allowed.
Instead, use the Variant type and avoid implicit function
calls with a typecast.
For example, instead of this…
function GetCount: Double;
begin
Result := Length(GetUserName) * 2.5;
end;
procedure MyShow(const v: Object);
begin
Write('Data...', Inspect(v));
end;
MyShow(GetCount);
In Delphi Mode, do this…
type DoubleFunc = function: Double;
function GetCount: Double;
begin
Result := Length(GetUserName) * 2.5;
end;
procedure MyShow(const v: Variant);
begin
Write('Data...', Inspect(v));
end;
MyShow(DoubleFunc(GetCount));
In Delphi Mode, the
IDotBag
type behaves identically to IAssociation.
For example, instead of this…
var Bag: IDotBag := BuildPropBag
.Prop('x', 1)
.Prop('y', 2)
.Prop('z', 3)
;
Writeln(Bag.x + Bag.y + Bag.z);
In Delphi Mode, do this…
var Bag := BuildPropBag
.Prop('x', 1)
.Prop('y', 2)
.Prop('z', 3)
;
Writeln(Bag['x'] + Bag['y'] + Bag['z']);
In Delphi Mode, Tusk does not allow
interface properties as reference expressions,
including taking their address or passing them by reference.
In Delphi Mode, constants with an explicit type are
read-only variables, not true parse-time constants.
This matches Delphi's behavior.
For example…
const N: Integer = 5;
var j: Integer;
case j of
2: Writeln('two');
N: Writeln('N');
else Writeln('something else');
end;
Above, assuming Delphi Mode is off, N is a true constant,
usable as a case label.
However, in Delphi Mode, N is a read-only variable,
because it is defined with a specific data type…
const N1: Integer = 5; // a read-only variable
const N2 = 6; // a true constant
var j: Integer;
case j of
2: Writeln('two');
N1: Writeln('N1'); // this is not legal
N2: Writeln('N2'); // this is fine
else Writeln('something else');
end;
In Delphi Mode, Tusk does not offer
improved is and as operators.
Instead, you should use functions like
TType.Supports for interfaces
and VarType for Variant expressions.
In Delphi Mode, Tusk is more strict about
default parameter types
and requires them to be
parse-time constants.
In Delphi Mode, Tusk emulates Delphi's handling of out
parameters: only managed types are initialized.
When Delphi Mode is off, Tusk
initializes all out params,
regardless of type.
In Delphi Mode, Tusk limits the number of
pure functions
to match Delphi's behavior.
For example, regardless of Delphi Mode,
Abs and Pred are pure when their arguments are frozen.
However, in Delphi Mode, StrToInt and Pos are not pure
even when their arguments are frozen.
Similarly, in Delphi Mode, operator overloads are not pure.
In Delphi Mode, Tusk does not offer
relaxed function type compatibility.
In Delphi Mode, Tusk does not allow
implicit conversions
from anonymous methods to IInterface.
In Delphi Mode, Tusk is looser about
TDateTime / numeric conversions,
more closely matching Delphi's behavior.
In Delphi Mode, Tusk does not expose routines defined
in the
Tusk_RTL unit.
⏱ Last Modified: 2/15 10:06:11 am