Coming from Delphi

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.

1. Automatic Reference Counting (ARC)

The most significant difference is memory management. DWScript uses ARC (Automatic Reference Counting) for all objects.

  • Delphi: You typically create an object and must explicitly Free it (unless it's an interface or you are using FreeAndNil).
  • DWScript: You create an object, and it is automatically destroyed when the last reference to it goes out of scope.
// 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.

2. Dynamic Arrays vs. TList

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.

  • Addition: Use .Add() or the += operator.
  • Removal: Use .Delete(), .Remove(), or .Pop().
  • Search: Use .IndexOf() or the in operator.
  • Manipulation: Use .Map(), .Filter(), and .Sort().

3. Associative Arrays vs. TDictionary

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']);
Result
Paris

This built-in syntax is more expressive, faster, and avoids the verbosity of generics.

4. Strings & Helpers

Strings in DWScript are more capable and reduce the need for external helper functions.

  • Multiline Strings: You can use double-quoted strings "..." for standard multiline strings, or raw strings #'...' (heredocs) for multiline strings that automatically strip common indentation, keeping your code readable and well indented.
  • Helpers: Standard helpers are built-in, making legacy string functions mostly redundant. There is a full suite of helpers to slice, extract, delete left/right and manipulate strings expressively without needing manual index computations.

5. JSON Support

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!
Result
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));
Result
{"from":"Alice","text":"Hello!"}

6. Guaranteed Initialization

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.

  • Integers, Floats -> 0
  • Booleans -> False
  • Strings -> ''
  • Objects/Arrays -> nil

You can also provide a default value inline:

var count : Integer := 10; // Initialized to 10
var total : Integer;       // Guaranteed to be 0

7. Generalized Case Statements

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;
Result
Greeting

8. Case Sensitivity Hints

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.

9. Type Inference

DWScript encourages the use of := for variable declaration with type inference.

// Explicit
var x : Integer = 10;

// Inferred
var y := 10;

10. Constant Expressions

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).

On this page