@@ -7,7 +7,7 @@ AIScript treats functions as first-class citizens, enabling powerful functional
77A closure is a function that captures and remembers the environment in which it was created. This means it can access variables from its enclosing scope, even after that scope has completed execution.
88
99``` js
10- fn create_counter (start: int) - > fn () - > int {
10+ fn create_counter (start : int ) {
1111 let count = start;
1212
1313 fn increment () - > int {
@@ -53,10 +53,6 @@ print(squared); // [1, 4, 9, 16, 25]
5353// Filter example
5454let even_numbers = filter (numbers, | n| n % 2 == 0 );
5555print (even_numbers); // [2, 4]
56-
57- // Reduce example
58- let sum = reduce (numbers, | acc, n| acc + n, 0 );
59- print (sum); // 15
6056```
6157
6258## Capturing Variables
@@ -87,7 +83,7 @@ print(increment()); // 2
8783print (counter); // 2 (affected by the closure)
8884```
8985
90- ### 3. Multiple Captures
86+ <!-- ### 3. Multiple Captures
9187
9288Closures can capture multiple variables from different scopes:
9389
@@ -106,9 +102,9 @@ let math = create_math_functions(10);
106102print(math.add(5)); // 15
107103print(math.multiply(5)); // 10
108104print(math.combined(5)); // 30
109- ```
105+ ``` -->
110106
111- ## Partial Application
107+ <!-- ## Partial Application
112108
113109Use closures to create partially applied functions:
114110
@@ -126,7 +122,7 @@ let goodbye = partial(greet, "Goodbye");
126122
127123print(hello("Alice")); // "Hello, Alice!"
128124print(goodbye("Bob")); // "Goodbye, Bob!"
129- ```
125+ ``` -->
130126
131127## Immediate Invocation
132128
@@ -142,39 +138,6 @@ let result = |x, y| {
142138print (result); // 19 (sum: 7, product: 12)
143139```
144140
145- ## Closures with Error Handling
146-
147- Closures can use AIScript's error handling mechanisms:
148-
149- ``` js
150- enum MathError! {
151- DivisionByZero,
152- Overflow,
153- }
154-
155- let safe_divide = | a, b| - > float | MathError! {
156- if b == 0 {
157- raise MathError! :: DivisionByZero;
158- }
159- return a / b;
160- };
161-
162- let result = safe_divide (10 , 2 ) | err| {
163- match err {
164- MathError! :: DivisionByZero => {
165- print (" Cannot divide by zero" );
166- return 0.0 ;
167- },
168- _ => {
169- print (" Unknown error" );
170- return 0.0 ;
171- }
172- }
173- };
174-
175- print (result); // 5.0
176- ```
177-
178141## Recursion with Closures
179142
180143Closures can call themselves recursively:
@@ -200,7 +163,7 @@ print(factorial(5)); // 120
200163Closures are ideal for event-driven or asynchronous programming:
201164
202165``` js
203- fn fetch_data (url: str, on_success: fn (data : str) , on_error: fn (error : str) ) {
166+ fn fetch_data (url : str , on_success , on_error ) {
204167 // Simulating an async operation
205168 if url .starts_with (" https" ) {
206169 on_success (" Data from {url}" );
@@ -216,6 +179,13 @@ fetch_data(
216179);
217180```
218181
182+ ::: danger
183+ AIScript current doesn't support ` fn ` as type annotation.
184+ ``` rs
185+ fn fetch_data (url : str , on_success : fn (data : str ), on_error : fn (error : str )) {}
186+ ```
187+ :::
188+
219189## Performance Considerations
220190
221191While closures provide powerful abstractions, they have memory implications since they maintain references to their captured environment. Consider these best practices:
@@ -224,69 +194,4 @@ While closures provide powerful abstractions, they have memory implications sinc
2241942 . ** Be mindful of memory** : Large closures with many captures may impact performance
2251953 . ** Consider alternatives** : For simple cases, regular functions might be more efficient
226196
227- ## Practical Examples
228-
229- ### Data Transformations
230-
231- ``` js
232- // Composing transformations
233- let process_data = | data| {
234- return data
235- | > map (| x| x * 2 )
236- | > filter (| x| x > 10 )
237- | > reduce (| acc, x| acc + x, 0 );
238- };
239-
240- print (process_data ([2 , 8 , 5 , 10 ])); // 36 (8*2 + 10*2 = 16 + 20)
241- ```
242-
243- ### Configuration Builder
244-
245- ``` js
246- fn create_config_builder () - > fn {
247- let config = {
248- host: " localhost" ,
249- port: 8080 ,
250- debug: false ,
251- timeout: 30 ,
252- };
253-
254- return | key, value| {
255- config[key] = value;
256- return config;
257- };
258- }
259-
260- let builder = create_config_builder ();
261- let config = builder (" host" , " example.com" )(" port" , 443 )(" debug" , true );
262- print (config); // {host: "example.com", port: 443, debug: true, timeout: 30}
263- ```
264-
265- ### Memoization
266-
267- ``` js
268- fn memoize (func) - > fn {
269- let cache = {};
270-
271- return | arg| {
272- if arg in cache {
273- return cache[arg];
274- }
275-
276- let result = func (arg);
277- cache[arg] = result;
278- return result;
279- };
280- }
281-
282- let fibonacci = memoize (| n| {
283- if n <= 1 {
284- return n;
285- }
286- return fibonacci (n - 1 ) + fibonacci (n - 2 );
287- });
288-
289- print (fibonacci (30 )); // Fast calculation due to memoization
290- ```
291-
292197Closures and lambdas are fundamental to many modern programming patterns, from functional programming to asynchronous workflows. By mastering these concepts in AIScript, you'll be able to write more concise, maintainable, and powerful code.
0 commit comments