# Program Structure
Understanding how to organize your code into units and use them is fundamental to building scalable applications in DWScript.
## Scripts vs Units
DWScript code can be organized as standalone scripts or reusable units.
* **Scripts:** A linear sequence of instructions, typically used for main entry points or simple tasks.
* **Units:** Collections of types, variables, and functions that can be imported by other scripts or units.
## Unit Syntax
A unit consists of an `interface` section (public API) and an `implementation` section (internal logic).
```pascal
unit MyMath;
interface
// Public declarations
function Add(a, b : Integer) : Integer;
implementation
// Internal implementation
function Add(a, b : Integer) : Integer;
begin
Result := a + b;
end;
end.
```
## Unit Lifecycle
Units can optionally include `initialization` and `finalization` blocks:
* **initialization:** Runs once when the unit is first loaded, before the main script starts. Used for setting up global state or caches.
* **finalization:** Runs when the script execution ends. Used for cleaning up resources.
## Uses Clause
To use code from another unit, you must include it in the `uses` clause.
In **Program Mode** (starting with the `program` keyword), you typically have a single `uses` clause at the top. However, in **Script Mode** (the default for `.dws` files), you can have multiple `uses` clauses interspersed throughout your code.
```pascal
// Import the 'System.Crypto' unit
uses System.Crypto;
var hash := HashSHA256.HashData('DWScript');
PrintLn(hash);
// OUTPUT
// f7eb27e6c33bb7ac799b8bc5bef374362297160952d322c9a5a1115d293283d5
```
### Multiple Uses Clauses
In Script Mode, you can include units only when they are needed, interspersing them with your logic.
```pascal
// Initial logic using built-in features
var name := 'DWScript';
// First inclusion when crypto is needed
uses System.Crypto;
var token := HashSHA256.HashData(name);
// ... more logic ...
// Second inclusion when web response control is needed
uses System.WebServer;
WebResponse.Header['X-Token'] := token;
PrintLn('Process complete.');
// OUTPUT
// Process complete.
```
## Unit Namespaces
While DWScript supports dotted unit names for organization, it also features a unique `unit namespace` construct. This allows you to aggregate multiple existing units into a single identifier, making it easier to manage large libraries.
### Creating a Namespace
A namespace unit uses the `unit namespace` keywords and a `uses` clause to list the units it aggregates.
```pascal
// NO_COMPILE
unit namespace MyLibrary;
uses
MyLibrary.Core,
MyLibrary.Utils;
// OUTPUT NONE
```
### Using a Namespace
When a script `uses` the namespace unit, all public symbols from the aggregated units become available directly.
```pascal
// NO_COMPILE
uses MyLibrary;
// Symbols from Core and Utils are now available
// without needing to import them individually.
var result := Process(FetchData);
// OUTPUT NONE
```
Program Structure
Understanding how to organize your code into units and use them is fundamental to building scalable applications in DWScript.
Scripts vs Units
DWScript code can be organized as standalone scripts or reusable units.
Scripts: A linear sequence of instructions, typically used for main entry points or simple tasks.
Units: Collections of types, variables, and functions that can be imported by other scripts or units.
Unit Syntax
A unit consists of an interface section (public API) and an implementation section (internal logic).
unit MyMath;interface// Public declarationsfunction Add(a, b :Integer):Integer;implementation// Internal implementationfunction Add(a, b :Integer):Integer;begin
Result := a + b;end;end.
Unit Lifecycle
Units can optionally include initialization and finalization blocks:
initialization: Runs once when the unit is first loaded, before the main script starts. Used for setting up global state or caches.
finalization: Runs when the script execution ends. Used for cleaning up resources.
Uses Clause
To use code from another unit, you must include it in the uses clause.
In Program Mode (starting with the program keyword), you typically have a single uses clause at the top. However, in Script Mode (the default for .dws files), you can have multiple uses clauses interspersed throughout your code.
// Import the 'System.Crypto' unituses System.Crypto;var hash := HashSHA256.HashData('DWScript');
PrintLn(hash);
In Script Mode, you can include units only when they are needed, interspersing them with your logic.
// Initial logic using built-in featuresvar name :='DWScript';// First inclusion when crypto is neededuses System.Crypto;var token := HashSHA256.HashData(name);// ... more logic ...// Second inclusion when web response control is neededuses System.WebServer;
WebResponse.Header['X-Token']:= token;
PrintLn('Process complete.');
Result
Process complete.
Unit Namespaces
While DWScript supports dotted unit names for organization, it also features a unique unit namespace construct. This allows you to aggregate multiple existing units into a single identifier, making it easier to manage large libraries.
Creating a Namespace
A namespace unit uses the unit namespace keywords and a uses clause to list the units it aggregates.