Merge PR #308 from basil-conto/blc/variadic

Closes: #72, #306.
master
Basil L. Contovounesios 5 years ago
commit 350b4c3867
No known key found for this signature in database
GPG Key ID: 205AB54A5D5D8CFF
  1. 4
      NEWS.md
  2. 113
      README.md
  3. 126
      dash.el
  4. 138
      dash.texi
  5. 159
      dev/examples.el

@ -18,6 +18,10 @@ See the end of the file for license conditions.
#### New features
- The combinators `-on`, `-flip`, `-not`, `-andfn`, and `-orfn` now
return variadic functions that take any number of arguments (#308).
- New combinator `-rotate-args` similar to `-flip`, but for arbitrary
arglist rotations (suggested by @vapniks, #72).
- New function `-every` and its anaphoric macro counterpart `--every`.
They are like the existing `-every-p` and `--every-p`, respectively,
but return the last non-`nil` result instead of just `t`.

@ -373,8 +373,9 @@ Functions that manipulate and compose other functions.
* [`-juxt`](#-juxt-rest-fns) `(&rest fns)`
* [`-compose`](#-compose-rest-fns) `(&rest fns)`
* [`-applify`](#-applify-fn) `(fn)`
* [`-on`](#-on-operator-transformer) `(operator transformer)`
* [`-flip`](#-flip-func) `(func)`
* [`-on`](#-on-op-trans) `(op trans)`
* [`-flip`](#-flip-fn) `(fn)`
* [`-rotate-args`](#-rotate-args-n-fn) `(n fn)`
* [`-const`](#-const-c) `(c)`
* [`-cut`](#-cut-rest-params) `(&rest params)`
* [`-not`](#-not-pred) `(pred)`
@ -1193,7 +1194,7 @@ Return the smallest value from `list` of numbers or markers.
Take a comparison function `comparator` and a `list` and return
the least element of the list by the comparison function.
See also combinator [`-on`](#-on-operator-transformer) which can transform the values before
See also combinator [`-on`](#-on-op-trans) which can transform the values before
comparing them.
```el
@ -1217,7 +1218,7 @@ Return the largest value from `list` of numbers or markers.
Take a comparison function `comparator` and a `list` and return
the greatest element of the list by the comparison function.
See also combinator [`-on`](#-on-operator-transformer) which can transform the values before
See also combinator [`-on`](#-on-op-trans) which can transform the values before
comparing them.
```el
@ -2892,30 +2893,56 @@ taking 1 argument which is a list of `n` arguments.
(funcall (-applify #'<) '(3 6)) ;; => t
```
#### -on `(operator transformer)`
#### -on `(op trans)`
Return a function of two arguments that first applies
`transformer` to each of them and then applies `operator` on the
results (in the same order).
Return a function that calls `trans` on each arg and `op` on the results.
The returned function takes a variable number of arguments, calls
the function `trans` on each one in turn, and then passes those
results as the list of arguments to `op`, in the same order.
In types: (b -> b -> c) -> (a -> b) -> a -> a -> c
For example, the following pairs of expressions are morally
equivalent:
(funcall (-on #'+ #'1+) 1 2 3) = (+ (1+ 1) (1+ 2) (1+ 3))
(funcall (-on #'+ #'1+)) = (+)
```el
(-sort (-on '< 'length) '((1 2 3) (1) (1 2))) ;; => ((1) (1 2) (1 2 3))
(-min-by (-on '> 'length) '((1 2 3) (4) (1 2))) ;; => (4)
(-min-by (-on 'string-lessp 'number-to-string) '(2 100 22)) ;; => 22
(-sort (-on #'< #'length) '((1 2 3) (1) (1 2))) ;; => ((1) (1 2) (1 2 3))
(funcall (-on #'min #'string-to-number) "22" "2" "1" "12") ;; => 1
(-min-by (-on #'> #'length) '((1 2 3) (4) (1 2))) ;; => (4)
```
#### -flip `(func)`
#### -flip `(fn)`
Return a function that calls `fn` with its arguments reversed.
The returned function takes the same number of arguments as `fn`.
For example, the following two expressions are morally
equivalent:
Swap the order of arguments for binary function `func`.
(funcall (-flip #'-) 1 2) = (- 2 1)
In types: (a -> b -> c) -> b -> a -> c
See also: [`-rotate-args`](#-rotate-args-n-fn).
```el
(funcall (-flip '<) 2 1) ;; => t
(funcall (-flip '-) 3 8) ;; => 5
(-sort (-flip '<) '(4 3 6 1)) ;; => (6 4 3 1)
(-sort (-flip #'<) '(4 3 6 1)) ;; => (6 4 3 1)
(funcall (-flip #'-) 3 2 1 10) ;; => 4
(funcall (-flip #'1+) 1) ;; => 2
```
#### -rotate-args `(n fn)`
Return a function that calls `fn` with args rotated `n` places to the right.
The returned function takes the same number of arguments as `fn`,
rotates the list of arguments `n` places to the right (left if `n` is
negative) just like [`-rotate`](#-rotate-n-list), and applies `fn` to the result.
See also: [`-flip`](#-flip-fn).
```el
(funcall (-rotate-args -1 #'list) 1 2 3 4) ;; => (2 3 4 1)
(funcall (-rotate-args 1 #'-) 1 10 100) ;; => 89
(funcall (-rotate-args 2 #'list) 3 4 5 1 2) ;; => (1 2 3 4 5)
```
#### -const `(c)`
@ -2926,8 +2953,8 @@ In types: a -> b -> a
```el
(funcall (-const 2) 1 3 "foo") ;; => 2
(-map (-const 1) '("a" "b" "c" "d")) ;; => (1 1 1 1)
(-sum (-map (-const 1) '("a" "b" "c" "d"))) ;; => 4
(mapcar (-const 1) '("a" "b" "c" "d")) ;; => (1 1 1 1)
(-sum (mapcar (-const 1) '("a" "b" "c" "d"))) ;; => 4
```
#### -cut `(&rest params)`
@ -2945,40 +2972,50 @@ See `srfi-26` for detailed description.
#### -not `(pred)`
Take a unary predicate `pred` and return a unary predicate
that returns t if `pred` returns nil and nil if `pred` returns
non-nil.
Return a predicate that negates the result of `pred`.
The returned predicate passes its arguments to `pred`. If `pred`
returns nil, the result is non-nil; otherwise the result is nil.
See also: [`-andfn`](#-andfn-rest-preds) and [`-orfn`](#-orfn-rest-preds).
```el
(funcall (-not 'even?) 5) ;; => t
(-filter (-not (-partial '< 4)) '(1 2 3 4 5 6 7 8)) ;; => (1 2 3 4)
(funcall (-not #'numberp) "5") ;; => t
(-sort (-not #'<) '(5 2 1 0 6)) ;; => (6 5 2 1 0)
(-filter (-not (-partial #'< 4)) '(1 2 3 4 5 6 7 8)) ;; => (1 2 3 4)
```
#### -orfn `(&rest preds)`
Take list of unary predicates `preds` and return a unary
predicate with argument x that returns non-nil if at least one of
the `preds` returns non-nil on x.
Return a predicate that returns the first non-nil result of `preds`.
The returned predicate takes a variable number of arguments,
passes them to each predicate in `preds` in turn until one of them
returns non-nil, and returns that non-nil result without calling
the remaining `preds`. If all `preds` return nil, or if no `preds` are
given, the returned predicate returns nil.
In types: [a -> Bool] -> a -> Bool
See also: [`-andfn`](#-andfn-rest-preds) and [`-not`](#-not-pred).
```el
(-filter (-orfn 'even? (-partial (-flip '<) 5)) '(1 2 3 4 5 6 7 8 9 10)) ;; => (1 2 3 4 6 8 10)
(funcall (-orfn 'stringp 'even?) "foo") ;; => t
(-filter (-orfn #'natnump #'booleanp) '(1 nil "a" -4 b c t)) ;; => (1 nil t)
(funcall (-orfn #'symbolp (-cut string-match-p "x" <>)) "axe") ;; => 1
(funcall (-orfn #'= #'+) 1 1) ;; => t
```
#### -andfn `(&rest preds)`
Take list of unary predicates `preds` and return a unary
predicate with argument x that returns non-nil if all of the
`preds` returns non-nil on x.
Return a predicate that returns non-nil if all `preds` do so.
The returned predicate `p` takes a variable number of arguments and
passes them to each predicate in `preds` in turn. If any one of
`preds` returns nil, `p` also returns nil without calling the
remaining `preds`. If all `preds` return non-nil, `p` returns the last
such value. If no `preds` are given, `p` always returns non-nil.
In types: [a -> Bool] -> a -> Bool
See also: [`-orfn`](#-orfn-rest-preds) and [`-not`](#-not-pred).
```el
(funcall (-andfn (-cut < <> 10) 'even?) 6) ;; => t
(funcall (-andfn (-cut < <> 10) 'even?) 12) ;; => nil
(-filter (-andfn (-not 'even?) (-cut >= 5 <>)) '(1 2 3 4 5 6 7 8 9 10)) ;; => (1 3 5)
(-filter (-andfn #'numberp (-cut < <> 5)) '(a 1 b 6 c 2)) ;; => (1 2)
(mapcar (-andfn #'numberp #'1+) '(a 1 b 6)) ;; => (nil 2 nil 7)
(funcall (-andfn #'= #'+) 1 1) ;; => 2
```
#### -iteratefn `(fn n)`

@ -3113,24 +3113,73 @@ taking 1 argument which is a list of N arguments."
(declare (pure t) (side-effect-free t))
(lambda (args) (apply fn args)))
(defun -on (operator transformer)
"Return a function of two arguments that first applies
TRANSFORMER to each of them and then applies OPERATOR on the
results (in the same order).
(defun -on (op trans)
"Return a function that calls TRANS on each arg and OP on the results.
The returned function takes a variable number of arguments, calls
the function TRANS on each one in turn, and then passes those
results as the list of arguments to OP, in the same order.
In types: (b -> b -> c) -> (a -> b) -> a -> a -> c"
(lambda (x y) (funcall operator (funcall transformer x) (funcall transformer y))))
For example, the following pairs of expressions are morally
equivalent:
(defun -flip (func)
"Swap the order of arguments for binary function FUNC.
In types: (a -> b -> c) -> b -> a -> c"
(lambda (x y) (funcall func y x)))
(funcall (-on #\\='+ #\\='1+) 1 2 3) = (+ (1+ 1) (1+ 2) (1+ 3))
(funcall (-on #\\='+ #\\='1+)) = (+)"
(declare (pure t) (side-effect-free t))
(lambda (&rest args)
;; This unrolling seems to be a relatively cheap way to keep the
;; overhead of `mapcar' + `apply' in check.
(cond ((cddr args)
(apply op (mapcar trans args)))
((cdr args)
(funcall op (funcall trans (car args)) (funcall trans (cadr args))))
(args
(funcall op (funcall trans (car args))))
((funcall op)))))
(defun -flip (fn)
"Return a function that calls FN with its arguments reversed.
The returned function takes the same number of arguments as FN.
For example, the following two expressions are morally
equivalent:
(funcall (-flip #\\='-) 1 2) = (- 2 1)
See also: `-rotate-args'."
(declare (pure t) (side-effect-free t))
(lambda (&rest args) ;; Open-code for speed.
(cond ((cddr args) (apply fn (nreverse args)))
((cdr args) (funcall fn (cadr args) (car args)))
(args (funcall fn (car args)))
((funcall fn)))))
(defun -rotate-args (n fn)
"Return a function that calls FN with args rotated N places to the right.
The returned function takes the same number of arguments as FN,
rotates the list of arguments N places to the right (left if N is
negative) just like `-rotate', and applies FN to the result.
See also: `-flip'."
(declare (pure t) (side-effect-free t))
(if (zerop n)
fn
(let ((even (= (% n 2) 0)))
(lambda (&rest args)
(cond ((cddr args) ;; Open-code for speed.
(apply fn (-rotate n args)))
((cdr args)
(let ((fst (car args))
(snd (cadr args)))
(funcall fn (if even fst snd) (if even snd fst))))
(args
(funcall fn (car args)))
((funcall fn)))))))
(defun -const (c)
"Return a function that returns C ignoring any additional arguments.
In types: a -> b -> a"
(declare (pure t) (side-effect-free t))
(lambda (&rest _) c))
(defmacro -cut (&rest params)
@ -3147,30 +3196,51 @@ See SRFI-26 for detailed description."
`(lambda ,args
,(let ((body (--map (if (eq it '<>) (pop args) it) params)))
(if (eq (car params) '<>)
(cons 'funcall body)
(cons #'funcall body)
body)))))
(defun -not (pred)
"Take a unary predicate PRED and return a unary predicate
that returns t if PRED returns nil and nil if PRED returns
non-nil."
(lambda (x) (not (funcall pred x))))
"Return a predicate that negates the result of PRED.
The returned predicate passes its arguments to PRED. If PRED
returns nil, the result is non-nil; otherwise the result is nil.
(defun -orfn (&rest preds)
"Take list of unary predicates PREDS and return a unary
predicate with argument x that returns non-nil if at least one of
the PREDS returns non-nil on x.
See also: `-andfn' and `-orfn'."
(declare (pure t) (side-effect-free t))
(lambda (&rest args) (not (apply pred args))))
In types: [a -> Bool] -> a -> Bool"
(lambda (x) (-any? (-cut funcall <> x) preds)))
(defun -orfn (&rest preds)
"Return a predicate that returns the first non-nil result of PREDS.
The returned predicate takes a variable number of arguments,
passes them to each predicate in PREDS in turn until one of them
returns non-nil, and returns that non-nil result without calling
the remaining PREDS. If all PREDS return nil, or if no PREDS are
given, the returned predicate returns nil.
See also: `-andfn' and `-not'."
(declare (pure t) (side-effect-free t))
;; Open-code for speed.
(cond ((cdr preds) (lambda (&rest args) (--some (apply it args) preds)))
(preds (car preds))
(#'ignore)))
(defun -andfn (&rest preds)
"Take list of unary predicates PREDS and return a unary
predicate with argument x that returns non-nil if all of the
PREDS returns non-nil on x.
In types: [a -> Bool] -> a -> Bool"
(lambda (x) (-all? (-cut funcall <> x) preds)))
"Return a predicate that returns non-nil if all PREDS do so.
The returned predicate P takes a variable number of arguments and
passes them to each predicate in PREDS in turn. If any one of
PREDS returns nil, P also returns nil without calling the
remaining PREDS. If all PREDS return non-nil, P returns the last
such value. If no PREDS are given, P always returns non-nil.
See also: `-orfn' and `-not'."
(declare (pure t) (side-effect-free t))
;; Open-code for speed.
(cond ((cdr preds) (lambda (&rest args) (--every (apply it args) preds)))
(preds (car preds))
;; As a `pure' function, this runtime check may generate
;; backward-incompatible bytecode for `(-andfn)' at compile-time,
;; but I doubt that's a problem in practice (famous last words).
((fboundp 'always) #'always)
((lambda (&rest _) t))))
(defun -iteratefn (fn n)
"Return a function FN composed N times with itself.

@ -4357,47 +4357,83 @@ taking 1 argument which is a list of @var{n} arguments.
@end defun
@anchor{-on}
@defun -on (operator transformer)
Return a function of two arguments that first applies
@var{transformer} to each of them and then applies @var{operator} on the
results (in the same order).
@defun -on (op trans)
Return a function that calls @var{trans} on each arg and @var{op} on the results.
The returned function takes a variable number of arguments, calls
the function @var{trans} on each one in turn, and then passes those
results as the list of arguments to @var{op}, in the same order.
In types: (b -> b -> c) -> (a -> b) -> a -> a -> c
For example, the following pairs of expressions are morally
equivalent:
(funcall (-on #'+ #'1+) 1 2 3) = (+ (1+ 1) (1+ 2) (1+ 3))
(funcall (-on #'+ #'1+)) = (+)
@example
@group
(-sort (-on '< 'length) '((1 2 3) (1) (1 2)))
(-sort (-on #'< #'length) '((1 2 3) (1) (1 2)))
@result{} ((1) (1 2) (1 2 3))
@end group
@group
(-min-by (-on '> 'length) '((1 2 3) (4) (1 2)))
@result{} (4)
(funcall (-on #'min #'string-to-number) "22" "2" "1" "12")
@result{} 1
@end group
@group
(-min-by (-on 'string-lessp 'number-to-string) '(2 100 22))
@result{} 22
(-min-by (-on #'> #'length) '((1 2 3) (4) (1 2)))
@result{} (4)
@end group
@end example
@end defun
@anchor{-flip}
@defun -flip (func)
Swap the order of arguments for binary function @var{func}.
@defun -flip (fn)
Return a function that calls @var{fn} with its arguments reversed.
The returned function takes the same number of arguments as @var{fn}.
For example, the following two expressions are morally
equivalent:
In types: (a -> b -> c) -> b -> a -> c
(funcall (-flip #'-) 1 2) = (- 2 1)
See also: @code{-rotate-args} (@pxref{-rotate-args}).
@example
@group
(funcall (-flip '<) 2 1)
@result{} t
(-sort (-flip #'<) '(4 3 6 1))
@result{} (6 4 3 1)
@end group
@group
(funcall (-flip '-) 3 8)
@result{} 5
(funcall (-flip #'-) 3 2 1 10)
@result{} 4
@end group
@group
(-sort (-flip '<) '(4 3 6 1))
@result{} (6 4 3 1)
(funcall (-flip #'1+) 1)
@result{} 2
@end group
@end example
@end defun
@anchor{-rotate-args}
@defun -rotate-args (n fn)
Return a function that calls @var{fn} with args rotated @var{n} places to the right.
The returned function takes the same number of arguments as @var{fn},
rotates the list of arguments @var{n} places to the right (left if @var{n} is
negative) just like @code{-rotate} (@pxref{-rotate}), and applies @var{fn} to the result.
See also: @code{-flip} (@pxref{-flip}).
@example
@group
(funcall (-rotate-args -1 #'list) 1 2 3 4)
@result{} (2 3 4 1)
@end group
@group
(funcall (-rotate-args 1 #'-) 1 10 100)
@result{} 89
@end group
@group
(funcall (-rotate-args 2 #'list) 3 4 5 1 2)
@result{} (1 2 3 4 5)
@end group
@end example
@end defun
@ -4414,11 +4450,11 @@ In types: a -> b -> a
@result{} 2
@end group
@group
(-map (-const 1) '("a" "b" "c" "d"))
(mapcar (-const 1) '("a" "b" "c" "d"))
@result{} (1 1 1 1)
@end group
@group
(-sum (-map (-const 1) '("a" "b" "c" "d")))
(-sum (mapcar (-const 1) '("a" "b" "c" "d")))
@result{} 4
@end group
@end example
@ -4449,17 +4485,23 @@ See @var{srfi-26} for detailed description.
@anchor{-not}
@defun -not (pred)
Take a unary predicate @var{pred} and return a unary predicate
that returns t if @var{pred} returns nil and nil if @var{pred} returns
non-nil.
Return a predicate that negates the result of @var{pred}.
The returned predicate passes its arguments to @var{pred}. If @var{pred}
returns nil, the result is non-nil; otherwise the result is nil.
See also: @code{-andfn} (@pxref{-andfn}) and @code{-orfn} (@pxref{-orfn}).
@example
@group
(funcall (-not 'even?) 5)
(funcall (-not #'numberp) "5")
@result{} t
@end group
@group
(-filter (-not (-partial '< 4)) '(1 2 3 4 5 6 7 8))
(-sort (-not #'<) '(5 2 1 0 6))
@result{} (6 5 2 1 0)
@end group
@group
(-filter (-not (-partial #'< 4)) '(1 2 3 4 5 6 7 8))
@result{} (1 2 3 4)
@end group
@end example
@ -4467,19 +4509,26 @@ non-nil.
@anchor{-orfn}
@defun -orfn (&rest preds)
Take list of unary predicates @var{preds} and return a unary
predicate with argument x that returns non-nil if at least one of
the @var{preds} returns non-nil on x.
Return a predicate that returns the first non-nil result of @var{preds}.
The returned predicate takes a variable number of arguments,
passes them to each predicate in @var{preds} in turn until one of them
returns non-nil, and returns that non-nil result without calling
the remaining @var{preds}. If all @var{preds} return nil, or if no @var{preds} are
given, the returned predicate returns nil.
In types: [a -> Bool] -> a -> Bool
See also: @code{-andfn} (@pxref{-andfn}) and @code{-not} (@pxref{-not}).
@example
@group
(-filter (-orfn 'even? (-partial (-flip '<) 5)) '(1 2 3 4 5 6 7 8 9 10))
@result{} (1 2 3 4 6 8 10)
(-filter (-orfn #'natnump #'booleanp) '(1 nil "a" -4 b c t))
@result{} (1 nil t)
@end group
@group
(funcall (-orfn #'symbolp (-cut string-match-p "x" <>)) "axe")
@result{} 1
@end group
@group
(funcall (-orfn 'stringp 'even?) "foo")
(funcall (-orfn #'= #'+) 1 1)
@result{} t
@end group
@end example
@ -4487,24 +4536,27 @@ In types: [a -> Bool] -> a -> Bool
@anchor{-andfn}
@defun -andfn (&rest preds)
Take list of unary predicates @var{preds} and return a unary
predicate with argument x that returns non-nil if all of the
@var{preds} returns non-nil on x.
Return a predicate that returns non-nil if all @var{preds} do so.
The returned predicate @var{p} takes a variable number of arguments and
passes them to each predicate in @var{preds} in turn. If any one of
@var{preds} returns nil, @var{p} also returns nil without calling the
remaining @var{preds}. If all @var{preds} return non-nil, @var{p} returns the last
such value. If no @var{preds} are given, @var{p} always returns non-nil.
In types: [a -> Bool] -> a -> Bool
See also: @code{-orfn} (@pxref{-orfn}) and @code{-not} (@pxref{-not}).
@example
@group
(funcall (-andfn (-cut < <> 10) 'even?) 6)
@result{} t
(-filter (-andfn #'numberp (-cut < <> 5)) '(a 1 b 6 c 2))
@result{} (1 2)
@end group
@group
(funcall (-andfn (-cut < <> 10) 'even?) 12)
@result{} nil
(mapcar (-andfn #'numberp #'1+) '(a 1 b 6))
@result{} (nil 2 nil 7)
@end group
@group
(-filter (-andfn (-not 'even?) (-cut >= 5 <>)) '(1 2 3 4 5 6 7 8 9 10))
@result{} (1 3 5)
(funcall (-andfn #'= #'+) 1 1)
@result{} 2
@end group
@end example
@end defun

@ -871,15 +871,15 @@ value rather than consuming a list to produce a single value."
(-partition-after-pred #'booleanp '(t)) => '((t))
(-partition-after-pred #'booleanp '(0 t)) => '((0 t))
(--partition-after-pred (= (% it 2) 0) '()) => '()
(--partition-after-pred (= (% it 2) 1) '()) => '()
(--partition-after-pred (= (mod it 2) 1) '()) => '()
(--partition-after-pred (= (% it 2) 0) '(0)) => '((0))
(--partition-after-pred (= (% it 2) 1) '(0)) => '((0))
(--partition-after-pred (= (mod it 2) 1) '(0)) => '((0))
(--partition-after-pred (= (% it 2) 0) '(0 1)) => '((0) (1))
(--partition-after-pred (= (% it 2) 1) '(0 1)) => '((0 1))
(--partition-after-pred (= (mod it 2) 1) '(0 1)) => '((0 1))
(--partition-after-pred (= (% it 2) 0) '(0 1 2)) => '((0) (1 2))
(--partition-after-pred (= (% it 2) 1) '(0 1 2)) => '((0 1) (2))
(--partition-after-pred (= (mod it 2) 1) '(0 1 2)) => '((0 1) (2))
(--partition-after-pred (= (% it 2) 0) '(0 1 2 3)) => '((0) (1 2) (3))
(--partition-after-pred (= (% it 2) 1) '(0 1 2 3)) => '((0 1) (2 3))
(--partition-after-pred (= (mod it 2) 1) '(0 1 2 3)) => '((0 1) (2 3))
(--partition-after-pred t '()) => ()
(--partition-after-pred t '(0)) => '((0))
(--partition-after-pred t '(0 1)) => '((0) (1))
@ -1055,7 +1055,9 @@ related predicates."
(-cons*) => ()
(-cons* ()) => ()
(-cons* 1 ()) => '(1)
(-cons* 1 '(2)) => '(1 2))
(-cons* 1 '(2)) => '(1 2)
;; Assert that &rest conses a fresh list in case that ever changes.
(let ((l (list 1 2))) (apply #'-cons* l) l) => '(1 2))
(defexamples -snoc
(-snoc '(1 2 3) 4) => '(1 2 3 4)
@ -1769,30 +1771,83 @@ or readability."
=> '((1 (1)) (1 (2)) (5 (5))))
(defexamples -on
(-sort (-on '< 'length) '((1 2 3) (1) (1 2))) => '((1) (1 2) (1 2 3))
(-min-by (-on '> 'length) '((1 2 3) (4) (1 2))) => '(4)
(-min-by (-on 'string-lessp 'number-to-string) '(2 100 22)) => 22
(-max-by (-on '> 'car) '((2 2 3) (3) (1 2))) => '(3)
(-sort (-on 'string-lessp 'number-to-string) '(10 12 1 2 22)) => '(1 10 12 2 22)
(funcall (-on '+ '1+) 1 2) => 5
(funcall (-on '+ 'identity) 1 2) => 3
(funcall (-on '* 'length) '(1 2 3) '(4 5)) => 6
(funcall (-on (-on '+ 'length) 'cdr) '(1 2 3) '(4 5)) => 3
(funcall (-on '+ (lambda (x) (length (cdr x)))) '(1 2 3) '(4 5)) => 3
(-sort (-on '< 'car) '((3 2 5) (2) (1 2))) => '((1 2) (2) (3 2 5))
(-sort (-on '< (lambda (x) (length x))) '((1 2 3) (1) (1 2))) => '((1) (1 2) (1 2 3))
(-sort (-on (-on '< 'car) 'cdr) '((0 3) (2 1) (4 2 8))) => '((2 1) (4 2 8) (0 3))
(-sort (-on '< 'cadr) '((0 3) (2 1) (4 2 8))) => '((2 1) (4 2 8) (0 3)))
(-sort (-on #'< #'length) '((1 2 3) (1) (1 2))) => '((1) (1 2) (1 2 3))
(funcall (-on #'min #'string-to-number) "22" "2" "1" "12") => 1
(-min-by (-on #'> #'length) '((1 2 3) (4) (1 2))) => '(4)
(-min-by (-on #'string< #'number-to-string) '(2 100 22)) => 22
(-max-by (-on #'> #'car) '((2 2 3) (3) (1 2))) => '(3)
(-sort (-on #'string< #'number-to-string) '(12 1 2 22)) => '(1 12 2 22)
(funcall (-on #'+ #'1+) 1 2) => 5
(funcall (-on #'+ #'identity) 1 2) => 3
(funcall (-on #'* #'length) '(1 2 3) '(4 5)) => 6
(funcall (-on (-on #'+ #'length) #'cdr) '(1 2 3) '(4 5)) => 3
(funcall (-on #'+ (lambda (x) (length (cdr x)))) '(1 2 3) '(4 5)) => 3
(-sort (-on #'< #'car) '((3 2 5) (2) (1 2))) => '((1 2) (2) (3 2 5))
(-sort (-on #'< (lambda (x) (length x))) '((1 2 3) (1) (1 2)))
=> '((1) (1 2) (1 2 3))
(-sort (-on (-on #'< #'car) #'cdr) '((0 3) (2 1) (4 2 8)))
=> '((2 1) (4 2 8) (0 3))
(-sort (-on #'< #'cadr) '((0 3) (2 1) (4 2 8))) => '((2 1) (4 2 8) (0 3))
(funcall (-on #'not #'not) nil) => nil
(funcall (-on #'+ #'1+) 1 10 100 1000) => 1115
(funcall (-on #'+ #'1+) 1 10 100) => 114
(funcall (-on #'+ #'1+) 1 10) => 13
(funcall (-on #'+ #'1+) 1) => 2
(funcall (-on #'+ #'1+)) => 0
(funcall (-on #'1+ #'1+) 0) => 2
(funcall (-on #'+ #'*)) => 0
(funcall (-on #'* #'+)) => 1)
(defexamples -flip
(funcall (-flip '<) 2 1) => t
(funcall (-flip '-) 3 8) => 5
(-sort (-flip '<) '(4 3 6 1)) => '(6 4 3 1))
(-sort (-flip #'<) '(4 3 6 1)) => '(6 4 3 1)
(funcall (-flip #'-) 3 2 1 10) => 4
(funcall (-flip #'1+) 1) => 2
(funcall (-flip #'<) 2 1) => t
(funcall (-flip #'list) 1 2 3) => '(3 2 1)
(funcall (-flip #'list) 1 2) => '(2 1)
(funcall (-flip #'list) 1) => '(1)
(funcall (-flip #'list)) => '()
;; Assert that &rest conses a fresh list in case that ever changes.
(let ((a (list 1 2 3 4))) (apply (-flip #'-) a) a) => '(1 2 3 4))
(defexamples -rotate-args
(funcall (-rotate-args -1 #'list) 1 2 3 4) => '(2 3 4 1)
(funcall (-rotate-args 1 #'-) 1 10 100) => 89
(funcall (-rotate-args 2 #'list) 3 4 5 1 2) => '(1 2 3 4 5)
(funcall (-rotate-args -2 #'list) 1 2 3 4) => '(3 4 1 2)
(funcall (-rotate-args 0 #'list) 1 2 3 4) => '(1 2 3 4)
(funcall (-rotate-args 1 #'list) 1 2 3 4) => '(4 1 2 3)
(funcall (-rotate-args 2 #'list) 1 2 3 4) => '(3 4 1 2)
(funcall (-rotate-args -2 #'list) 1 2 3) => '(3 1 2)
(funcall (-rotate-args -1 #'list) 1 2 3) => '(2 3 1)
(funcall (-rotate-args 0 #'list) 1 2 3) => '(1 2 3)
(funcall (-rotate-args 1 #'list) 1 2 3) => '(3 1 2)
(funcall (-rotate-args 2 #'list) 1 2 3) => '(2 3 1)
(funcall (-rotate-args -2 #'list) 1 2) => '(1 2)
(funcall (-rotate-args -1 #'list) 1 2) => '(2 1)
(funcall (-rotate-args 0 #'list) 1 2) => '(1 2)
(funcall (-rotate-args 1 #'list) 1 2) => '(2 1)
(funcall (-rotate-args 2 #'list) 1 2) => '(1 2)
(funcall (-rotate-args -2 #'list) 1) => '(1)
(funcall (-rotate-args -1 #'list) 1) => '(1)
(funcall (-rotate-args 0 #'list) 1) => '(1)
(funcall (-rotate-args 1 #'list) 1) => '(1)
(funcall (-rotate-args 2 #'list) 1) => '(1)
(funcall (-rotate-args -2 #'list)) => '()
(funcall (-rotate-args -1 #'list)) => '()
(funcall (-rotate-args 0 #'list)) => '()
(funcall (-rotate-args 1 #'list)) => '()
(funcall (-rotate-args 2 #'list)) => '()
(let ((a (list 1 2 3))) (apply (-rotate-args 2 #'-) a) a) => '(1 2 3))
(defexamples -const
(funcall (-const 2) 1 3 "foo") => 2
(-map (-const 1) '("a" "b" "c" "d")) => '(1 1 1 1)
(-sum (-map (-const 1) '("a" "b" "c" "d"))) => 4)
(mapcar (-const 1) '("a" "b" "c" "d")) => '(1 1 1 1)
(-sum (mapcar (-const 1) '("a" "b" "c" "d"))) => 4
(funcall (-const t)) => t
(funcall (-const nil)) => nil
(funcall (-const t) nil) => t
(funcall (-const nil) nil) => nil)
(defexamples -cut
(funcall (-cut list 1 <> 3 <> 5) 2 4) => '(1 2 3 4 5)
@ -1801,17 +1856,57 @@ or readability."
(-filter (-cut < <> 5) '(1 3 5 7 9)) => '(1 3))
(defexamples -not
(funcall (-not 'even?) 5) => t
(-filter (-not (-partial '< 4)) '(1 2 3 4 5 6 7 8)) => '(1 2 3 4))
(funcall (-not #'numberp) "5") => t
(-sort (-not #'<) '(5 2 1 0 6)) => '(6 5 2 1 0)
(-filter (-not (-partial #'< 4)) '(1 2 3 4 5 6 7 8)) => '(1 2 3 4)
;; Variadic `<' was introduced in Emacs 24.4.
(funcall (-not (lambda (a b c) (and (< a b) (< b c)))) 1 2 3) => nil
(funcall (-not (lambda (a b c) (and (< a b) (< b c)))) 3 2 1) => t
(funcall (-not #'<) 1 2) => nil
(funcall (-not #'<) 2 1) => t
(funcall (-not #'+) 1) => nil
(funcall (-not #'+)) => nil)
(defexamples -orfn
(-filter (-orfn 'even? (-partial (-flip '<) 5)) '(1 2 3 4 5 6 7 8 9 10)) => '(1 2 3 4 6 8 10)
(funcall (-orfn 'stringp 'even?) "foo") => t)
(-filter (-orfn #'natnump #'booleanp) '(1 nil "a" -4 b c t)) => '(1 nil t)
(funcall (-orfn #'symbolp (-cut string-match-p "x" <>)) "axe") => 1
(funcall (-orfn #'= #'+) 1 1) => t
(funcall (-orfn #'+ #'null)) => 0
(funcall (-orfn #'+ #'null) 1) => 1
(funcall (-orfn #'+ #'null) 1 2) => 3
(funcall (-orfn #'+ #'null) 1 2 3) => 6
(funcall (-orfn #'ignore #'+)) => 0
(funcall (-orfn #'ignore #'+) 1) => 1
(funcall (-orfn #'ignore #'+) 1 2) => 3
(funcall (-orfn #'ignore #'+) 1 2 3) => 6
(-filter (-orfn #'symbolp) '(a b 1 nil t 2)) => '(a b nil t)
(-filter (-orfn #'null) '(a b 1 nil t 2)) => '(nil)
(-filter (-orfn) '(nil t)) => '()
(-orfn #'null) => #'null
(-orfn) => #'ignore)
(defexamples -andfn
(funcall (-andfn (-cut < <> 10) 'even?) 6) => t
(funcall (-andfn (-cut < <> 10) 'even?) 12) => nil
(-filter (-andfn (-not 'even?) (-cut >= 5 <>)) '(1 2 3 4 5 6 7 8 9 10)) => '(1 3 5))
(-filter (-andfn #'numberp (-cut < <> 5)) '(a 1 b 6 c 2)) => '(1 2)
(mapcar (-andfn #'numberp #'1+) '(a 1 b 6)) => '(nil 2 nil 7)
(funcall (-andfn #'= #'+) 1 1) => 2
(funcall (-andfn #'ignore #'+)) => nil
(funcall (-andfn #'ignore #'+) 1) => nil
(funcall (-andfn #'ignore #'+) 1 2) => nil
(funcall (-andfn #'+ #'ignore)) => nil
(funcall (-andfn #'+ #'ignore) 1) => nil
(funcall (-andfn #'+ #'ignore) 1 2) => nil
(funcall (-andfn #'+ #'list)) => '()
(funcall (-andfn #'+ #'list) 1) => '(1)
(funcall (-andfn #'+ #'list) 1 2) => '(1 2)
(funcall (-andfn #'list #'+)) => nil
(funcall (-andfn #'list #'+) 1) => 1
(funcall (-andfn #'list #'+) 1 2) => 3
(funcall (-andfn #'* #'+)) => 0
(funcall (-andfn #'+ #'*)) => 1
(-andfn #'null) => #'null
(funcall (-andfn)) => t
(funcall (-andfn) nil) => t
(funcall (-andfn) t) => t)
(defexamples -iteratefn
(funcall (-iteratefn (lambda (x) (* x x)) 3) 2) => 256

Loading…
Cancel
Save