summary refs log tree commit diff
diff options
context:
space:
mode:
authorArun Isaac2025-12-31 21:11:15 +0000
committerArun Isaac2025-12-31 21:11:15 +0000
commitcd57f867069c4e86a9c02682ddec27baa21152ac (patch)
treef52737022ba1b0da14b6f0da0c974cb94bc0ad5b
parent4f757fc0a4d4af067e0d22ad4020c1b18cc3fd24 (diff)
downloadccwl-0.5.0.tar.gz
ccwl-0.5.0.tar.lz
ccwl-0.5.0.zip
utils: Require arity for mapn. v0.5.0
With an empty list, mapn cannot know the number of values proc would
return. mapn therefore needs to know the arity of proc. To provide for
existing callers of mapn, we add a map2 function variant. Finally, we
add a test case testing mapn on an empty list.
-rw-r--r--ccwl/ccwl.scm2
-rw-r--r--ccwl/utils.scm28
-rw-r--r--tests/utils.scm14
3 files changed, 32 insertions, 12 deletions
diff --git a/ccwl/ccwl.scm b/ccwl/ccwl.scm
index 4480314..8f02b0c 100644
--- a/ccwl/ccwl.scm
+++ b/ccwl/ccwl.scm
@@ -743,7 +743,7 @@ represented by <step> objects."
             (list)))
     ;; tee
     ((tee expressions ...)
-     (let ((key-lists step-lists (mapn (cut collect-steps <> input-keys)
+     (let ((key-lists step-lists (map2 (cut collect-steps <> input-keys)
                                        #'(expressions ...))))
        (values
         ;; Global workflow input keys may be duplicated across the
diff --git a/ccwl/utils.scm b/ccwl/utils.scm
index 3c18efd..2abc404 100644
--- a/ccwl/utils.scm
+++ b/ccwl/utils.scm
@@ -1,5 +1,5 @@
 ;;; ccwl --- Concise Common Workflow Language
-;;; Copyright © 2021, 2022, 2023 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2021, 2022, 2023, 2025 Arun Isaac <arunisaac@systemreboot.net>
 ;;;
 ;;; This file is part of ccwl.
 ;;;
@@ -39,6 +39,7 @@
             lambda**
             syntax-lambda**
             mapn
+            map2
             foldn
             filter-mapi))
 
@@ -311,22 +312,31 @@ element. For example,
               lst
               (iota (length lst))))
 
-(define (mapn proc lst)
+(define (mapn proc lst n)
   "Map the procedure PROC over list LST and return a list containing
-the results. PROC can return multiple values, in which case, an equal
-number of lists are returned. For example,
+the results. PROC must return N values, in which case, N lists are
+returned. For example,
 
 (mapn (lambda (n)
         (values (expt n 2)
                 (expt n 3)))
-      (iota 5))
+      (iota 5)
+      2)
 => (0 1 4 9 16)
 => (0 1 8 27 64)"
   (apply values
-         (apply zip
-                (map (lambda (x)
-                       (call-with-values (cut proc x) list))
-                     lst))))
+         (match lst
+           ;; With an empty list, we cannot know the number of values
+           ;; proc would return. Hence this special case.
+           (() (make-list n '()))
+           (_
+            (apply zip
+                   (map (lambda (x)
+                          (call-with-values (cut proc x) list))
+                        lst))))))
+
+(define map2
+  (cut mapn <> <> 2))
 
 (define (foldn proc lst . inits)
   "Apply PROC to the elements of LST to build a result, and return
diff --git a/tests/utils.scm b/tests/utils.scm
index 50c3396..d786d02 100644
--- a/tests/utils.scm
+++ b/tests/utils.scm
@@ -1,5 +1,5 @@
 ;;; ccwl --- Concise Common Workflow Language
-;;; Copyright © 2021, 2022, 2023 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2021, 2022, 2023, 2025 Arun Isaac <arunisaac@systemreboot.net>
 ;;;
 ;;; This file is part of ccwl.
 ;;;
@@ -194,7 +194,17 @@
   (let ((squares cubes (mapn (lambda (n)
                                (values (expt n 2)
                                        (expt n 3)))
-                             (iota 5))))
+                             (iota 5)
+                             2)))
+    (list squares cubes)))
+
+(test-equal "mapn on an empty list"
+  '(() ())
+  (let ((squares cubes (mapn (lambda (n)
+                               (values (expt n 2)
+                                       (expt n 3)))
+                             '()
+                             2)))
     (list squares cubes)))
 
 (test-equal "foldn"