If you are a Delphi developer, DWScript will feel immediately familiar. You can use standard Pascal syntax, the begin/end blocks, and the VCL/RTL class naming conventions you are used to. However, DWScript is a distinct language with its own runtime characteristics.
Here are the critical differences you need to know to write effective scripts.
The most significant difference is memory management. DWScript uses ARC (Automatic Reference Counting) for all objects.
Free it (unless it's an interface or you are using FreeAndNil).// Delphi Style (Do NOT do this in scripts usually)
// obj := TMyClass.Create;
// try ... finally obj.Free; end;
// DWScript Style
var obj := TMyClass.Create;
// use obj...
// obj is automatically freed here Because ARC is universal, there is no need for TInterfacedObject.
Because ARC is complemented by a GC, there is no need for Weak references.
DWScript's dynamic arrays are far more powerful than Delphi's. They are full-fledged objects with methods for adding, removing, sorting, and finding elements.
You do not need TList, TList<T>, or TStringList.
.Add() or the += operator..Delete(), .Remove(), or .Pop()..IndexOf() or the in operator..Map(), .Filter(), and .Sort().Instead of TDictionary<Key, Value>, DWScript provides built-in syntax for associative arrays (maps).
var capitals : array[String] of String;
capitals['France'] := 'Paris';
if 'France' in capitals then
PrintLn(capitals['France']); Paris
This built-in syntax is more expressive, faster, and avoids the verbosity of generics.
Strings in DWScript are more capable and reduce the need for external helper functions.
"..." for standard multiline strings, or raw strings #'...' (heredocs) for multiline strings that automatically strip common indentation, keeping your code readable and well indented.JSON is a first-class citizen. Unlike Delphi's verbose TJSONObject builders, DWScript provides the JSONVariant type (via JSON.Parse and JSON.NewObject).
It allows dynamic access to fields without constant type casting.
var data := JSON.Parse('{"user": "Alice", "id": 42}');
PrintLn(data.user); // "Alice" - No .GetValue('user').Value needed! Alice
Anonymous records support stringifying inline with type-safety and compile-time validation.
var msg := record
from := 'Alice';
text := 'Hello!';
end;
PrintLn(JSON.Stringify(msg)); {"from":"Alice","text":"Hello!"}In Delphi, local variables of ordinal types (Integer, Boolean, etc.) are uninitialized and contain garbage values unless explicitly set.
In DWScript, all variables are guaranteed to be initialized.
You can also provide a default value inline:
var count : Integer := 10; // Initialized to 10
var total : Integer; // Guaranteed to be 0 DWScript extends the case statement to support Strings and other non-ordinal types.
var s := 'hello';
case s of
'hello', 'hi': PrintLn('Greeting');
'bye': PrintLn('Farewell');
else
PrintLn('Unknown');
end; Greeting
While DWScript is case-insensitive (like Delphi), the compiler is stricter about consistency.
If you declare a variable as MyVariable but use it as myvariable, the compiler may emit a Hint. This enforces code cleanliness and consistency.
DWScript encourages the use of := for variable declaration with type inference.
// Explicit
var x : Integer = 10;
// Inferred
var y := 10; Constants can be evaluated at compile time from expressions, and can use pure functions (functions without side effects, whose result only depends on their parameters).