emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/dash 5326ed8 2/3: Improve -rpartial, -juxt, and -compos


From: ELPA Syncer
Subject: [elpa] externals/dash 5326ed8 2/3: Improve -rpartial, -juxt, and -compose
Date: Mon, 8 Mar 2021 16:57:08 -0500 (EST)

branch: externals/dash
commit 5326ed8c9f1787d6dc08cf3594f42bcd58cebb24
Author: Basil L. Contovounesios <contovob@tcd.ie>
Commit: Basil L. Contovounesios <contovob@tcd.ie>

    Improve -rpartial, -juxt, and -compose
    
    * dash.el (-rpartial, -juxt): Mark as pure and side-effect-free.
    Fix docstrings.
    (-compose): Ditto.  Optimize for speed.
    * dev/examples.el (-rpartial, -juxt, -compose): Extend tests.
    
    * README.md:
    * dash.texi: Regenerate docs.
---
 README.md       | 44 +++++++++++++++++++++++-------------------
 dash.el         | 42 +++++++++++++++++++++++++---------------
 dash.texi       | 60 +++++++++++++++++++++++++++++++++------------------------
 dev/examples.el | 45 +++++++++++++++++++++++++++++--------------
 4 files changed, 116 insertions(+), 75 deletions(-)

diff --git a/README.md b/README.md
index 4947b6d..a52493c 100644
--- a/README.md
+++ b/README.md
@@ -2811,40 +2811,44 @@ was called.
 
 #### -rpartial `(fn &rest args)`
 
-Takes a function `fn` and fewer than the normal arguments to `fn`,
-and returns a fn that takes a variable number of additional `args`.
-When called, the returned function calls `fn` with the additional
-args first and then `args`.
+Return a function that is a partial application of `fn` to `args`.
+`args` is a list of the last `n` arguments to pass to `fn`.  The result
+is a new function which does the same as `fn`, except that the last
+`n` arguments are fixed at the values with which this function was
+called.  This is like [`-partial`](#-partial-fun-rest-args), except the 
arguments are fixed
+starting from the right rather than the left.
 
 ```el
-(funcall (-rpartial '- 5) 8) ;; => 3
-(funcall (-rpartial '- 5 2) 10) ;; => 3
+(funcall (-rpartial #'- 5)) ;; => -5
+(funcall (-rpartial #'- 5) 8) ;; => 3
+(funcall (-rpartial #'- 5 2) 10) ;; => 3
 ```
 
 #### -juxt `(&rest fns)`
 
-Takes a list of functions and returns a fn that is the
-juxtaposition of those fns. The returned fn takes a variable
-number of args, and returns a list containing the result of
-applying each fn to the args (left-to-right).
+Return a function that is the juxtaposition of `fns`.
+The returned function takes a variable number of `args`, applies
+each of `fns` in turn to `args`, and returns the list of results.
 
 ```el
-(funcall (-juxt '+ '-) 3 5) ;; => (8 -2)
-(-map (-juxt 'identity 'square) '(1 2 3)) ;; => ((1 1) (2 4) (3 9))
+(funcall (-juxt) 1 2) ;; => ()
+(funcall (-juxt #'+ #'- #'* #'/) 7 5) ;; => (12 2 35 1)
+(mapcar (-juxt #'number-to-string #'1+) '(1 2)) ;; => (("1" 2) ("2" 3))
 ```
 
 #### -compose `(&rest fns)`
 
-Takes a list of functions and returns a fn that is the
-composition of those fns. The returned fn takes a variable
-number of arguments, and returns the result of applying
-each fn to the result of applying the previous fn to
-the arguments (right-to-left).
+Compose `fns` into a single composite function.
+Return a function that takes a variable number of `args`, applies
+the last function in `fns` to `args`, and returns the result of
+calling each remaining function on the result of the previous
+function, right-to-left.  If no `fns` are given, return a variadic
+`identity` function.
 
 ```el
-(funcall (-compose 'square '+) 2 3) ;; => (square (+ 2 3))
-(funcall (-compose 'identity 'square) 3) ;; => (square 3)
-(funcall (-compose 'square 'identity) 3) ;; => (square 3)
+(funcall (-compose #'- #'1+ #'+) 1 2 3) ;; => -7
+(funcall (-compose #'identity #'1+) 3) ;; => 4
+(mapcar (-compose #'not #'stringp) '(nil "")) ;; => (t nil)
 ```
 
 #### -applify `(fn)`
diff --git a/dash.el b/dash.el
index ffcf55f..499a883 100644
--- a/dash.el
+++ b/dash.el
@@ -3002,28 +3002,38 @@ structure such as plist or alist."
 (defalias '-partial #'apply-partially)
 
 (defun -rpartial (fn &rest args)
-  "Takes a function FN and fewer than the normal arguments to FN,
-and returns a fn that takes a variable number of additional ARGS.
-When called, the returned function calls FN with the additional
-args first and then ARGS."
+  "Return a function that is a partial application of FN to ARGS.
+ARGS is a list of the last N arguments to pass to FN.  The result
+is a new function which does the same as FN, except that the last
+N arguments are fixed at the values with which this function was
+called.  This is like `-partial', except the arguments are fixed
+starting from the right rather than the left."
+  (declare (pure t) (side-effect-free t))
   (lambda (&rest args-before) (apply fn (append args-before args))))
 
 (defun -juxt (&rest fns)
-  "Takes a list of functions and returns a fn that is the
-juxtaposition of those fns. The returned fn takes a variable
-number of args, and returns a list containing the result of
-applying each fn to the args (left-to-right)."
+  "Return a function that is the juxtaposition of FNS.
+The returned function takes a variable number of ARGS, applies
+each of FNS in turn to ARGS, and returns the list of results."
+  (declare (pure t) (side-effect-free t))
   (lambda (&rest args) (mapcar (lambda (x) (apply x args)) fns)))
 
 (defun -compose (&rest fns)
-  "Takes a list of functions and returns a fn that is the
-composition of those fns. The returned fn takes a variable
-number of arguments, and returns the result of applying
-each fn to the result of applying the previous fn to
-the arguments (right-to-left)."
-  (lambda (&rest args)
-    (car (-reduce-r-from (lambda (fn xs) (list (apply fn xs)))
-                         args fns))))
+  "Compose FNS into a single composite function.
+Return a function that takes a variable number of ARGS, applies
+the last function in FNS to ARGS, and returns the result of
+calling each remaining function on the result of the previous
+function, right-to-left.  If no FNS are given, return a variadic
+`identity' function."
+  (declare (pure t) (side-effect-free t))
+  (let* ((fns (nreverse fns))
+         (head (car fns))
+         (tail (cdr fns)))
+    (cond (tail
+           (lambda (&rest args)
+             (--reduce-from (funcall it acc) (apply head args) tail)))
+          (fns head)
+          ((lambda (&optional arg &rest _) arg)))))
 
 (defun -applify (fn)
   "Return a function that applies FN to a single list of args.
diff --git a/dash.texi b/dash.texi
index dcfbe0d..60aabb4 100644
--- a/dash.texi
+++ b/dash.texi
@@ -4226,18 +4226,24 @@ was called.
 
 @anchor{-rpartial}
 @defun -rpartial (fn &rest args)
-Takes a function @var{fn} and fewer than the normal arguments to @var{fn},
-and returns a fn that takes a variable number of additional @var{args}.
-When called, the returned function calls @var{fn} with the additional
-args first and then @var{args}.
+Return a function that is a partial application of @var{fn} to @var{args}.
+@var{args} is a list of the last @var{n} arguments to pass to @var{fn}.  The 
result
+is a new function which does the same as @var{fn}, except that the last
+@var{n} arguments are fixed at the values with which this function was
+called.  This is like @code{-partial} (@pxref{-partial}), except the arguments 
are fixed
+starting from the right rather than the left.
 
 @example
 @group
-(funcall (-rpartial '- 5) 8)
+(funcall (-rpartial #'- 5))
+    @result{} -5
+@end group
+@group
+(funcall (-rpartial #'- 5) 8)
     @result{} 3
 @end group
 @group
-(funcall (-rpartial '- 5 2) 10)
+(funcall (-rpartial #'- 5 2) 10)
     @result{} 3
 @end group
 @end example
@@ -4245,43 +4251,47 @@ args first and then @var{args}.
 
 @anchor{-juxt}
 @defun -juxt (&rest fns)
-Takes a list of functions and returns a fn that is the
-juxtaposition of those fns. The returned fn takes a variable
-number of args, and returns a list containing the result of
-applying each fn to the args (left-to-right).
+Return a function that is the juxtaposition of @var{fns}.
+The returned function takes a variable number of @var{args}, applies
+each of @var{fns} in turn to @var{args}, and returns the list of results.
 
 @example
 @group
-(funcall (-juxt '+ '-) 3 5)
-    @result{} (8 -2)
+(funcall (-juxt) 1 2)
+    @result{} ()
+@end group
+@group
+(funcall (-juxt #'+ #'- #'* #'/) 7 5)
+    @result{} (12 2 35 1)
 @end group
 @group
-(-map (-juxt 'identity 'square) '(1 2 3))
-    @result{} ((1 1) (2 4) (3 9))
+(mapcar (-juxt #'number-to-string #'1+) '(1 2))
+    @result{} (("1" 2) ("2" 3))
 @end group
 @end example
 @end defun
 
 @anchor{-compose}
 @defun -compose (&rest fns)
-Takes a list of functions and returns a fn that is the
-composition of those fns. The returned fn takes a variable
-number of arguments, and returns the result of applying
-each fn to the result of applying the previous fn to
-the arguments (right-to-left).
+Compose @var{fns} into a single composite function.
+Return a function that takes a variable number of @var{args}, applies
+the last function in @var{fns} to @var{args}, and returns the result of
+calling each remaining function on the result of the previous
+function, right-to-left.  If no @var{fns} are given, return a variadic
+@code{identity} function.
 
 @example
 @group
-(funcall (-compose 'square '+) 2 3)
-    @result{} (square (+ 2 3))
+(funcall (-compose #'- #'1+ #'+) 1 2 3)
+    @result{} -7
 @end group
 @group
-(funcall (-compose 'identity 'square) 3)
-    @result{} (square 3)
+(funcall (-compose #'identity #'1+) 3)
+    @result{} 4
 @end group
 @group
-(funcall (-compose 'square 'identity) 3)
-    @result{} (square 3)
+(mapcar (-compose #'not #'stringp) '(nil ""))
+    @result{} (t nil)
 @end group
 @end example
 @end defun
diff --git a/dev/examples.el b/dev/examples.el
index 35acfd4..e281702 100644
--- a/dev/examples.el
+++ b/dev/examples.el
@@ -1640,20 +1640,37 @@ or readability."
     (funcall (-partial #'+) 5) => 5
     (apply (-partial #'+ 5) 10 '(1 2)) => 18)
 
-  (unless (version< emacs-version "24")
-    (defexamples -rpartial
-      (funcall (-rpartial '- 5) 8) => 3
-      (funcall (-rpartial '- 5 2) 10) => 3)
-
-    (defexamples -juxt
-      (funcall (-juxt '+ '-) 3 5) => '(8 -2)
-      (-map (-juxt 'identity 'square) '(1 2 3)) => '((1 1) (2 4) (3 9)))
-
-    (defexamples -compose
-      (funcall (-compose 'square '+) 2 3) => (square (+ 2 3))
-      (funcall (-compose 'identity 'square) 3) => (square 3)
-      (funcall (-compose 'square 'identity) 3) => (square 3)
-      (funcall (-compose (-compose 'not 'even?) 'square) 3) => (funcall 
(-compose 'not (-compose 'even? 'square)) 3)))
+  (defexamples -rpartial
+    (funcall (-rpartial #'- 5)) => -5
+    (funcall (-rpartial #'- 5) 8) => 3
+    (funcall (-rpartial #'- 5 2) 10) => 3
+    (funcall (-rpartial #'-)) => 0
+    (apply (-rpartial #'- 1) 2 '(20 3)) => -22)
+
+  (defexamples -juxt
+    (funcall (-juxt) 1 2) => '()
+    (funcall (-juxt #'+ #'- #'* #'/) 7 5) => '(12 2 35 1)
+    (mapcar (-juxt #'number-to-string #'1+) '(1 2)) => '(("1" 2) ("2" 3))
+    (funcall (-juxt #'+ #'-)) => '(0 0)
+    (funcall (-juxt)) => '())
+
+  (defexamples -compose
+    (funcall (-compose #'- #'1+ #'+) 1 2 3) => -7
+    (funcall (-compose #'identity #'1+) 3) => 4
+    (mapcar (-compose #'not #'stringp) '(nil "")) => '(t nil)
+    (funcall (-compose #'1+ #'identity) 3) => 4
+    (mapcar (lambda (fn)
+              (list (funcall fn 0) (funcall fn 1)))
+            (list (-compose (-compose #'natnump #'1+) #'lognot)
+                  (-compose #'natnump (-compose #'1+ #'lognot))
+                  (-compose #'natnump #'1+ #'lognot)))
+    => '((t nil) (t nil) (t nil))
+    (funcall (-compose)) => nil
+    (funcall (-compose) nil) => nil
+    (funcall (-compose) nil 1) => nil
+    (funcall (-compose) 1) => 1
+    (funcall (-compose) 1 2) => 1
+    (-compose #'+) => #'+)
 
   (defexamples -applify
     (funcall (-applify #'+) ()) => 0



reply via email to

[Prev in Thread] Current Thread [Next in Thread]