[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