# Lambdas & Closures
Lambdas (also known as anonymous methods) provide a concise way to create functions and procedures that can be passed as arguments or assigned to variables.
## Syntax Overview
DWScript supports both a modern arrow syntax for brief expressions and a more traditional block syntax for complex logic.
```pascal
// Function lambda
var sqr := lambda (x: Integer): Integer => x * x;
// Procedure lambda
var log := procedure (s: String)
begin
PrintLn('Log: ' + s);
end;
// Traditional function syntax
var add := function (a, b : Integer) : Integer
begin
Result := a + b;
end;
```
## Functional Programming
Lambdas are frequently used with standard library methods for filtering, mapping, and sorting data collections.
```pascal
var list : array of Integer = [1, 2, 3, 4, 5];
// Map: Transform elements
var doubled := list.Map(lambda (x: Integer) => x * 2);
// Filter: Keep elements matching a condition
var evens := list.Filter(lambda (x: Integer) => x mod 2 = 0);
PrintLn('Doubled: ' + doubled.Map(IntToStr).Join(','));
PrintLn('Evens: ' + evens.Map(IntToStr).Join(','));
// OUTPUT
// Doubled: 2,4,6,8,10
// Evens: 2,4
```
## Closures & Variable Capture
A **closure** is an anonymous method that "captures" variables from its surrounding local scope.
:::warning
**Platform Difference:** Variable capture (closures) is currently only supported when using the **JavaScript Transpiler**.
In **Native Script Mode**, lambdas cannot capture local variables from the outer scope. They must be self-contained or rely solely on their parameters.
:::
### Native Script Mode
In native mode, lambdas are excellent for pure functions, sorting logic, or any operation where the required data is passed in via parameters.
```pascal
// Self-contained lambda works perfectly in native mode
var list : array of Integer = [3, 1, 4, 2];
list.Sort(lambda (a, b: Integer) => a - b);
PrintLn(list.Map(IntToStr).Join(','));
// What DOES NOT work in native mode (uncommenting will cause error):
// var factor := 2;
// var doubled := list.Map(lambda (x: Integer) => x * factor); // 'factor' is external to lambda
// OUTPUT
// 1,2,3,4
```
## JavaScript Transpilation
For developers targeting the web, DWScript lambdas are a powerful feature. The JavaScript transpiler maps them directly to native **JavaScript closures** and **arrow functions**.
:::info
#### Full Closure Support in JS
When compiling to JavaScript, you can freely capture local variables. The transpiler ensures that the lexical scope is preserved, matching the behavior expected in modern web development.
```pascal
// Supported in JS Mode (Commented out for native compilation check)
/*
function MakeCounter(start : Integer) : function : Integer;
begin
var count := start;
Result := lambda => Inc(count); // 'count' is captured
end;
*/
```
:::
## Memory Management
* **Native Script Mode:** Uses a hybrid approach with **Reference Counting** for immediate release of resources and a **Garbage Collector** to handle circular references.
* **JavaScript Mode:** Relies entirely on the host JavaScript engine's garbage collector.
Lambdas & Closures
Lambdas (also known as anonymous methods) provide a concise way to create functions and procedures that can be passed as arguments or assigned to variables.
Syntax Overview
DWScript supports both a modern arrow syntax for brief expressions and a more traditional block syntax for complex logic.
// Function lambdavar sqr :=lambda(x:Integer):Integer=> x * x;// Procedure lambdavar log :=procedure(s:String)begin
PrintLn('Log: '+ s);end;// Traditional function syntaxvar add :=function(a, b :Integer):Integerbegin
Result := a + b;end;
Functional Programming
Lambdas are frequently used with standard library methods for filtering, mapping, and sorting data collections.
var list :arrayofInteger=[1,2,3,4,5];// Map: Transform elementsvar doubled := list.Map(lambda(x:Integer)=> x *2);// Filter: Keep elements matching a conditionvar evens := list.Filter(lambda(x:Integer)=> x mod2=0);
PrintLn('Doubled: '+ doubled.Map(IntToStr).Join(','));
PrintLn('Evens: '+ evens.Map(IntToStr).Join(','));
Result
Doubled: 2,4,6,8,10
Evens: 2,4
Closures & Variable Capture
A closure is an anonymous method that "captures" variables from its surrounding local scope.
Platform Difference: Variable capture (closures) is currently only supported when using the JavaScript Transpiler.
In Native Script Mode, lambdas cannot capture local variables from the outer scope. They must be self-contained or rely solely on their parameters.
Native Script Mode
In native mode, lambdas are excellent for pure functions, sorting logic, or any operation where the required data is passed in via parameters.
// Self-contained lambda works perfectly in native modevar list :arrayofInteger=[3,1,4,2];
list.Sort(lambda(a, b:Integer)=> a - b);
PrintLn(list.Map(IntToStr).Join(','));// What DOES NOT work in native mode (uncommenting will cause error):// var factor := 2;// var doubled := list.Map(lambda (x: Integer) => x * factor); // 'factor' is external to lambda
Result
1,2,3,4
JavaScript Transpilation
For developers targeting the web, DWScript lambdas are a powerful feature. The JavaScript transpiler maps them directly to native JavaScript closures and arrow functions.
Full Closure Support in JS
When compiling to JavaScript, you can freely capture local variables. The transpiler ensures that the lexical scope is preserved, matching the behavior expected in modern web development.
// Supported in JS Mode (Commented out for native compilation check)/*function MakeCounter(start :Integer):function:Integer;beginvar count := start;
Result :=lambda=> Inc(count);// 'count' is capturedend;*/
Memory Management
Native Script Mode: Uses a hybrid approach with Reference Counting for immediate release of resources and a Garbage Collector to handle circular references.
JavaScript Mode: Relies entirely on the host JavaScript engine's garbage collector.