# 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.
```pascal
type TMyClass = class end;
// 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).
```pascal
var capitals : array[String] of String;
capitals['France'] := 'Paris';
if 'France' in capitals then
PrintLn(capitals['France']);
// OUTPUT
// 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.
```pascal
var data := JSON.Parse('{"user": "Alice", "id": 42}');
PrintLn(data.user); // "Alice" - No .GetValue('user').Value needed!
// OUTPUT
// Alice
```
Anonymous records support stringifying inline with type-safety and compile-time validation.
```pascal
var msg := record
from := 'Alice';
text := 'Hello!';
end;
PrintLn(JSON.Stringify(msg));
// OUTPUT
// {"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:
```pascal
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.
```pascal
var s := 'hello';
case s of
'hello', 'hi': PrintLn('Greeting');
'bye': PrintLn('Farewell');
else
PrintLn('Unknown');
end;
// OUTPUT
// 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.
```pascal
// 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).
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.
type TMyClass =classend;// Delphi Style (Do NOT do this in scripts usually)// obj := TMyClass.Create;// try ... finally obj.Free; end;// DWScript Stylevar 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]ofString;
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 10var 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.
// Explicitvar x :Integer=10;// Inferredvar 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).