1use super::function_card::{ArgumentInfo, FunctionCard};
8
9pub const COLLECTION_CARDS: &[FunctionCard] = &[
11 FunctionCard {
13 identifier: "count",
14 signature: "count(array)",
15 brief: "Count elements in arrays and literals.",
16 description: "Returns the number of elements in an array, 1.0 for any literal value, \
17 or 0.0 for other types. This function is useful for determining the size \
18 of collections, checking if a value exists, or counting items in data \
19 processing pipelines.",
20 arguments: &[
21 &ArgumentInfo {
22 label: "array",
23 description: "Array to count elements in, or any value",
24 type_hint: "Any",
25 optional: false,
26 },
27 ],
28 returns: "Number of elements (f64)",
29 errors: "None - always succeeds",
30 categories: &["collection"],
31 examples: &[
32 r#"count((1, 2, 3, 4, 5)) => 5.0"#,
33 r#"count(("a", "b", "c")) => 3.0"#,
34 r#"count(42) => 1.0"#,
35 r#"count("hello") => 1.0"#,
36 ],
37 },
38
39 FunctionCard {
41 identifier: "len",
42 signature: "len(array)",
43 brief: "Get length of arrays or text.",
44 description: "Returns the number of elements in an array or the number of characters \
45 in a text string. For other literals, returns 1.0. For other types, \
46 returns 0.0. This function is commonly used for validation, iteration \
47 bounds checking, or determining data size.",
48 arguments: &[
49 &ArgumentInfo {
50 label: "array",
51 description: "Array or text to measure length of",
52 type_hint: "Any",
53 optional: false,
54 },
55 ],
56 returns: "Length of array or text (f64)",
57 errors: "None - always succeeds",
58 categories: &["collection"],
59 examples: &[
60 r#"len((1, 2, 3, 4)) => 4.0"#,
61 r#"len("hello world") => 11.0"#,
62 r#"len(("a", "b", "c")) => 3.0"#,
63 r#"len("") => 0.0"#,
64 ],
65 },
66
67 FunctionCard {
69 identifier: "find",
70 signature: "find(array, closure)",
71 brief: "Find first array element for which closure evaluates truthy.",
72 description: "Iterates through the array and returns the first element for which the \
73 closure returns true. If no element matches, returns Empty. This function \
74 is essential for searching collections, filtering data, or finding \
75 specific items based on custom criteria.",
76 arguments: &[
77 &ArgumentInfo {
78 label: "array",
79 description: "Array to search through",
80 type_hint: "Array",
81 optional: false,
82 },
83 &ArgumentInfo {
84 label: "closure",
85 description: "Function that returns true for matching elements",
86 type_hint: "Closure",
87 optional: false,
88 },
89 ],
90 returns: "First matching element or Empty",
91 errors: "Error if closure argument is not a function",
92 categories: &["collection", "functional"],
93 examples: &[
94 r#"find((1, 2, 3, 4, 5), x => x > 3) => 4"#,
95 r#"find(("apple", "banana", "cherry"), x => len(x) > 5) => "banana""#,
96 r#"find((1, 2, 3), x => x > 10) => Empty"#,
97 ],
98 },
99
100 FunctionCard {
102 identifier: "find_index",
103 signature: "find_index(array, closure)",
104 brief: "Find index of first array element for which closure evaluates truthy.",
105 description: "Iterates through the array and returns the zero-based index of the \
106 first element for which the closure returns true. If no element matches, \
107 returns -1.0. This function is useful for locating items in arrays, \
108 implementing search functionality, or finding positions for updates.",
109 arguments: &[
110 &ArgumentInfo {
111 label: "array",
112 description: "Array to search through",
113 type_hint: "Array",
114 optional: false,
115 },
116 &ArgumentInfo {
117 label: "closure",
118 description: "Function that returns true for matching elements",
119 type_hint: "Closure",
120 optional: false,
121 },
122 ],
123 returns: "Index of first matching element or -1.0 (f64)",
124 errors: "Error if closure argument is not a function",
125 categories: &["collection", "functional"],
126 examples: &[
127 r#"find_index((1, 2, 3, 4, 5), x => x > 3) => 3.0"#,
128 r#"find_index(("apple", "banana", "cherry"), x => len(x) > 5) => 1.0"#,
129 r#"find_index((1, 2, 3), x => x > 10) => -1.0"#,
130 ],
131 },
132
133 FunctionCard {
135 identifier: "flatten",
136 signature: "flatten(array)",
137 brief: "Flatten one level of nested arrays.",
138 description: "Removes one level of nesting from arrays. Nested arrays are expanded \
139 and their elements are added to the result at the same level. Non-array \
140 elements are copied as-is. This function is useful for simplifying \
141 nested data structures, preparing data for processing, or normalizing \
142 collection depths.",
143 arguments: &[
144 &ArgumentInfo {
145 label: "array",
146 description: "Array with nested arrays to flatten",
147 type_hint: "Array",
148 optional: false,
149 },
150 ],
151 returns: "Flattened array",
152 errors: "Error if first argument is not an array",
153 categories: &["collection"],
154 examples: &[
155 r#"flatten(((1, 2), (3, 4), (5))) => (1, 2, 3, 4, 5)"#,
156 r#"flatten((1, (2, 3), 4)) => (1, 2, 3, 4)"#,
157 r#"flatten((1, 2, 3)) => (1, 2, 3)"#,
158 ],
159 },
160
161 FunctionCard {
163 identifier: "unique",
164 signature: "unique(array)",
165 brief: "Remove duplicate elements from an array, preserving first occurrence order.",
166 description: "Creates a new array with duplicate elements removed. The first \
167 occurrence of each unique element is preserved, maintaining the \
168 original order. Uniqueness is determined by comparing string \
169 representations of values. This function is essential for data \
170 deduplication, set operations, or cleaning up collections.",
171 arguments: &[
172 &ArgumentInfo {
173 label: "array",
174 description: "Array to remove duplicates from",
175 type_hint: "Array",
176 optional: false,
177 },
178 ],
179 returns: "Array with duplicates removed",
180 errors: "Error if first argument is not an array",
181 categories: &["collection"],
182 examples: &[
183 r#"unique((1, 2, 2, 3, 3, 3)) => (1, 2, 3)"#,
184 r#"unique(("a", "b", "a", "c")) => ("a", "b", "c")"#,
185 r#"unique((1, 2, 3)) => (1, 2, 3)"#,
186 ],
187 },
188
189 FunctionCard {
191 identifier: "reverse",
192 signature: "reverse(array)",
193 brief: "Reverse array elements.",
194 description: "Creates a new array with elements in reverse order. The first element \
195 becomes the last, the second becomes the second-to-last, and so on. \
196 This function is useful for reversing iteration order, implementing \
197 stack-like behavior, or displaying data in reverse sequence.",
198 arguments: &[
199 &ArgumentInfo {
200 label: "array",
201 description: "Array to reverse",
202 type_hint: "Array",
203 optional: false,
204 },
205 ],
206 returns: "Reversed array",
207 errors: "Error if first argument is not an array",
208 categories: &["collection"],
209 examples: &[
210 r#"reverse((1, 2, 3, 4)) => (4, 3, 2, 1)"#,
211 r#"reverse(("a", "b", "c")) => ("c", "b", "a")"#,
212 r#"reverse(()) => ()"#,
213 ],
214 },
215
216 FunctionCard {
218 identifier: "take",
219 signature: "take(array, count)",
220 brief: "Take first N elements from an array.",
221 description: "Creates a new array containing only the first N elements from the \
222 input array. If N is greater than the array length, returns the \
223 entire array. If N is zero or negative, returns an empty array. \
224 This function is useful for pagination, sampling data, or limiting \
225 results.",
226 arguments: &[
227 &ArgumentInfo {
228 label: "array",
229 description: "Array to take elements from",
230 type_hint: "Array",
231 optional: false,
232 },
233 &ArgumentInfo {
234 label: "count",
235 description: "Number of elements to take from the beginning",
236 type_hint: "f64",
237 optional: false,
238 },
239 ],
240 returns: "Array with first N elements",
241 errors: "Error if count is not a number or array is not an array",
242 categories: &["collection"],
243 examples: &[
244 r#"take((1, 2, 3, 4, 5), 3) => (1, 2, 3)"#,
245 r#"take(("a", "b", "c"), 2) => ("a", "b")"#,
246 r#"take((1, 2, 3), 10) => (1, 2, 3)"#,
247 ],
248 },
249
250 FunctionCard {
252 identifier: "take_right",
253 signature: "take_right(array, count)",
254 brief: "Take last N elements from an array.",
255 description: "Creates a new array containing only the last N elements from the \
256 input array. If N is greater than the array length, returns the \
257 entire array. If N is zero or negative, returns an empty array. \
258 This function is useful for getting recent items, implementing \
259 sliding windows, or accessing tail data.",
260 arguments: &[
261 &ArgumentInfo {
262 label: "array",
263 description: "Array to take elements from",
264 type_hint: "Array",
265 optional: false,
266 },
267 &ArgumentInfo {
268 label: "count",
269 description: "Number of elements to take from the end",
270 type_hint: "f64",
271 optional: false,
272 },
273 ],
274 returns: "Array with last N elements",
275 errors: "Error if count is not a number or array is not an array",
276 categories: &["collection"],
277 examples: &[
278 r#"take_right((1, 2, 3, 4, 5), 3) => (3, 4, 5)"#,
279 r#"take_right(("a", "b", "c"), 2) => ("b", "c")"#,
280 r#"take_right((1, 2, 3), 10) => (1, 2, 3)"#,
281 ],
282 },
283
284 FunctionCard {
286 identifier: "skip",
287 signature: "skip(array, count)",
288 brief: "Skip first N elements of an array.",
289 description: "Creates a new array with the first N elements removed. If N is greater \
290 than or equal to the array length, returns an empty array. If N is zero \
291 or negative, returns the entire array. This function is useful for \
292 pagination, skipping headers, or ignoring initial data.",
293 arguments: &[
294 &ArgumentInfo {
295 label: "array",
296 description: "Array to skip elements from",
297 type_hint: "Array",
298 optional: false,
299 },
300 &ArgumentInfo {
301 label: "count",
302 description: "Number of elements to skip from the beginning",
303 type_hint: "f64",
304 optional: false,
305 },
306 ],
307 returns: "Array with first N elements removed",
308 errors: "Error if count is not a number or array is not an array",
309 categories: &["collection"],
310 examples: &[
311 r#"skip((1, 2, 3, 4, 5), 2) => (3, 4, 5)"#,
312 r#"skip(("a", "b", "c"), 1) => ("b", "c")"#,
313 r#"skip((1, 2, 3), 10) => ()"#,
314 ],
315 },
316
317 FunctionCard {
319 identifier: "skip_right",
320 signature: "skip_right(array, count)",
321 brief: "Skip last N elements of an array.",
322 description: "Creates a new array with the last N elements removed. If N is greater \
323 than or equal to the array length, returns an empty array. If N is zero \
324 or negative, returns the entire array. This function is useful for \
325 removing footers, skipping trailing data, or implementing reverse \
326 pagination.",
327 arguments: &[
328 &ArgumentInfo {
329 label: "array",
330 description: "Array to skip elements from",
331 type_hint: "Array",
332 optional: false,
333 },
334 &ArgumentInfo {
335 label: "count",
336 description: "Number of elements to skip from the end",
337 type_hint: "f64",
338 optional: false,
339 },
340 ],
341 returns: "Array with last N elements removed",
342 errors: "Error if count is not a number or array is not an array",
343 categories: &["collection"],
344 examples: &[
345 r#"skip_right((1, 2, 3, 4, 5), 2) => (1, 2, 3)"#,
346 r#"skip_right(("a", "b", "c"), 1) => ("a", "b")"#,
347 r#"skip_right((1, 2, 3), 10) => ()"#,
348 ],
349 },
350
351 FunctionCard {
353 identifier: "chunk",
354 signature: "chunk(array, size)",
355 brief: "Split array into chunks of fixed size.",
356 description: "Divides an array into smaller arrays (chunks) of the specified size. \
357 The last chunk may contain fewer elements if the array length is not \
358 evenly divisible by the chunk size. This function is useful for \
359 batch processing, pagination, or parallel processing of large datasets.",
360 arguments: &[
361 &ArgumentInfo {
362 label: "array",
363 description: "Array to split into chunks",
364 type_hint: "Array",
365 optional: false,
366 },
367 &ArgumentInfo {
368 label: "size",
369 description: "Size of each chunk (must be > 0)",
370 type_hint: "f64",
371 optional: false,
372 },
373 ],
374 returns: "Array of chunked arrays",
375 errors: "Error if size is zero, not a number, or array is not an array",
376 categories: &["collection"],
377 examples: &[
378 r#"chunk((1, 2, 3, 4, 5, 6), 2) => ((1, 2), (3, 4), (5, 6))"#,
379 r#"chunk(("a", "b", "c", "d"), 3) => (("a", "b", "c"), ("d",))"#,
380 r#"chunk((1, 2, 3), 5) => ((1, 2, 3),)"#,
381 ],
382 },
383
384 FunctionCard {
386 identifier: "group_by",
387 signature: "group_by(array, closure)",
388 brief: "Group array elements by key from closure.",
389 description: "Groups array elements by the result of applying the closure to each \
390 element. Returns an array of (key, group) pairs where each group is \
391 an array of elements that produced the same key. Keys are determined \
392 by the string representation of the closure result. This function is \
393 essential for data aggregation, categorization, or organizing data \
394 by common attributes.",
395 arguments: &[
396 &ArgumentInfo {
397 label: "array",
398 description: "Array to group elements from",
399 type_hint: "Array",
400 optional: false,
401 },
402 &ArgumentInfo {
403 label: "closure",
404 description: "Function that returns grouping key for each element",
405 type_hint: "Closure",
406 optional: false,
407 },
408 ],
409 returns: "Array of (key, group) pairs",
410 errors: "Error if closure argument is not a function",
411 categories: &["collection", "functional"],
412 examples: &[
413 r#"group_by((1, 2, 3, 4, 5), x => x % 2) => (("1.0", (1, 3, 5)), ("0.0", (2, 4)))"#,
414 r#"group_by(("apple", "banana", "cherry"), x => len(x)) => (("5.0", ("apple",)), ("6.0", ("banana", "cherry")))"#,
415 r#"group_by((1, 1, 2, 2, 3), x => x) => (("1.0", (1, 1)), ("2.0", (2, 2)), ("3.0", (3,)))"#,
416 ],
417 },
418
419 FunctionCard {
421 identifier: "partition",
422 signature: "partition(array, closure)",
423 brief: "Partition array into (true_items, false_items) using closure predicate.",
424 description: "Splits an array into two groups based on the result of the closure \
425 predicate. Elements for which the closure returns true are placed in \
426 the first group, and elements for which it returns false are placed \
427 in the second group. This function is useful for filtering data, \
428 separating items by criteria, or implementing conditional logic.",
429 arguments: &[
430 &ArgumentInfo {
431 label: "array",
432 description: "Array to partition",
433 type_hint: "Array",
434 optional: false,
435 },
436 &ArgumentInfo {
437 label: "closure",
438 description: "Predicate function that returns true or false for each element",
439 type_hint: "Closure",
440 optional: false,
441 },
442 ],
443 returns: "Array containing (true_items, false_items)",
444 errors: "Error if closure argument is not a function",
445 categories: &["collection", "functional"],
446 examples: &[
447 r#"partition((1, 2, 3, 4, 5), x => x % 2 == 0) => ((2, 4), (1, 3, 5))"#,
448 r#"partition(("apple", "banana", "cherry"), x => len(x) > 5) => (("banana", "cherry"), ("apple",))"#,
449 r#"partition((1, 2, 3), x => x > 10) => ((), (1, 2, 3))"#,
450 ],
451 },
452
453 FunctionCard {
455 identifier: "sort_by",
456 signature: "sort_by(array, closure)",
457 brief: "Sort array by key from closure.",
458 description: "Sorts array elements based on the keys produced by applying the closure \
459 to each element. Keys are compared using their string representations, \
460 which provides a consistent ordering for mixed types. This function is \
461 useful for custom sorting, organizing data by computed values, or \
462 implementing complex ordering logic.",
463 arguments: &[
464 &ArgumentInfo {
465 label: "array",
466 description: "Array to sort",
467 type_hint: "Array",
468 optional: false,
469 },
470 &ArgumentInfo {
471 label: "closure",
472 description: "Function that returns sort key for each element",
473 type_hint: "Closure",
474 optional: false,
475 },
476 ],
477 returns: "Sorted array",
478 errors: "Error if closure argument is not a function",
479 categories: &["collection", "functional"],
480 examples: &[
481 r#"sort_by((3, 1, 4, 1, 5), x => x) => (1, 1, 3, 4, 5)"#,
482 r#"sort_by(("cherry", "apple", "banana"), x => len(x)) => ("apple", "banana", "cherry")"#,
483 r#"sort_by((("b", 2), ("a", 1), ("c", 3)), x => x[1]) => (("a", 1), ("b", 2), ("c", 3))"#,
484 ],
485 },
486
487 FunctionCard {
489 identifier: "all_unique",
490 signature: "all_unique(array)",
491 brief: "True if all elements are unique.",
492 description: "Checks whether all elements in the array are unique. Returns true if \
493 no duplicates exist, false otherwise. For empty arrays, returns false. \
494 Uniqueness is determined by comparing string representations of values. \
495 This function is useful for data validation, checking for duplicates, \
496 or ensuring set-like properties.",
497 arguments: &[
498 &ArgumentInfo {
499 label: "array",
500 description: "Array to check for uniqueness",
501 type_hint: "Array",
502 optional: false,
503 },
504 ],
505 returns: "Boolean indicating if all elements are unique",
506 errors: "Error if first argument is not an array",
507 categories: &["collection"],
508 examples: &[
509 r#"all_unique((1, 2, 3, 4)) => true"#,
510 r#"all_unique((1, 2, 2, 3)) => false"#,
511 r#"all_unique(("a", "b", "c")) => true"#,
512 r#"all_unique(()) => false"#,
513 ],
514 },
515
516 FunctionCard {
518 identifier: "take_while",
519 signature: "take_while(array, closure)",
520 brief: "Take elements while closure predicate is truthy.",
521 description: "Creates a new array containing elements from the beginning of the input \
522 array while the closure returns true for each element. As soon as the \
523 closure returns false for an element, processing stops and no further \
524 elements are included. This function is useful for taking prefixes of \
525 data, implementing conditional extraction, or processing data until \
526 a condition changes.",
527 arguments: &[
528 &ArgumentInfo {
529 label: "array",
530 description: "Array to take elements from",
531 type_hint: "Array",
532 optional: false,
533 },
534 &ArgumentInfo {
535 label: "closure",
536 description: "Predicate function that determines when to stop taking elements",
537 type_hint: "Closure",
538 optional: false,
539 },
540 ],
541 returns: "Array with elements taken while predicate is true",
542 errors: "Error if closure argument is not a function",
543 categories: &["collection", "functional"],
544 examples: &[
545 r#"take_while((1, 2, 3, 4, 5), x => x < 4) => (1, 2, 3)"#,
546 r#"take_while(("a", "bb", "ccc", "dd"), x => len(x) <= 2) => ("a", "bb")"#,
547 r#"take_while((1, 2, 3), x => x > 10) => ()"#,
548 ],
549 },
550
551 FunctionCard {
553 identifier: "skip_while",
554 signature: "skip_while(array, closure)",
555 brief: "Skip elements while closure predicate is truthy.",
556 description: "Creates a new array with elements from the input array, starting from \
557 the first element for which the closure returns false. All elements \
558 before this point (where closure returns true) are skipped. This \
559 function is useful for skipping headers, ignoring initial data that \
560 meets certain criteria, or finding the first element that doesn't \
561 match a condition.",
562 arguments: &[
563 &ArgumentInfo {
564 label: "array",
565 description: "Array to skip elements from",
566 type_hint: "Array",
567 optional: false,
568 },
569 &ArgumentInfo {
570 label: "closure",
571 description: "Predicate function that determines when to stop skipping elements",
572 type_hint: "Closure",
573 optional: false,
574 },
575 ],
576 returns: "Array with elements after predicate becomes false",
577 errors: "Error if closure argument is not a function",
578 categories: &["collection", "functional"],
579 examples: &[
580 r#"skip_while((1, 2, 3, 4, 5), x => x < 4) => (4, 5)"#,
581 r#"skip_while(("a", "bb", "ccc", "dd"), x => len(x) <= 2) => ("ccc", "dd")"#,
582 r#"skip_while((1, 2, 3), x => x > 10) => (1, 2, 3)"#,
583 ],
584 },
585
586 FunctionCard {
588 identifier: "zip",
589 signature: "zip(array1, array2)",
590 brief: "Zip two arrays into array of 2-element arrays.",
591 description: "Combines two arrays by pairing elements at corresponding positions. \
592 The resulting array contains pairs where the first element comes from \
593 the first array and the second element comes from the second array. \
594 The length of the result is the minimum of the two input arrays. This \
595 function is useful for combining related data, creating coordinate \
596 pairs, or processing parallel arrays.",
597 arguments: &[
598 &ArgumentInfo {
599 label: "array1",
600 description: "First array to zip",
601 type_hint: "Array",
602 optional: false,
603 },
604 &ArgumentInfo {
605 label: "array2",
606 description: "Second array to zip",
607 type_hint: "Array",
608 optional: false,
609 },
610 ],
611 returns: "Array of paired elements",
612 errors: "Error if either argument is not an array",
613 categories: &["collection"],
614 examples: &[
615 r#"zip((1, 2, 3), ("a", "b", "c")) => ((1, "a"), (2, "b"), (3, "c"))"#,
616 r#"zip((1, 2), ("x", "y", "z")) => ((1, "x"), (2, "y"))"#,
617 r#"zip((), ("a", "b")) => ()"#,
618 ],
619 },
620
621 FunctionCard {
623 identifier: "unzip",
624 signature: "unzip(array)",
625 brief: "Unzip array of 2-element arrays into (first_items, second_items).",
626 description: "Reverses the zip operation by separating an array of pairs into two \
627 separate arrays. The first resulting array contains all the first \
628 elements from each pair, and the second resulting array contains all \
629 the second elements. This function is useful for decomposing paired \
630 data, separating coordinates, or undoing zip operations.",
631 arguments: &[
632 &ArgumentInfo {
633 label: "array",
634 description: "Array of 2-element arrays to unzip",
635 type_hint: "Array",
636 optional: false,
637 },
638 ],
639 returns: "Array containing (first_items, second_items)",
640 errors: "Error if input is not an array or contains non-pair elements",
641 categories: &["collection"],
642 examples: &[
643 r#"unzip(((1, "a"), (2, "b"), (3, "c"))) => ((1, 2, 3), ("a", "b", "c"))"#,
644 r#"unzip(((1, 2), (3, 4))) => ((1, 3), (2, 4))"#,
645 r#"unzip(()) => ((), ())"#,
646 ],
647 },
648];