# HG changeset patch # User Steve Losh # Date 1512236903 18000 # Node ID 8cf0978477a82e6165560e818346d84ae398a832 # Parent 1e90139a06b110eb5b8e7e86d2a89ef212cab6bb Add some more useful functions diff -r 1e90139a06b1 -r 8cf0978477a8 DOCUMENTATION.markdown --- a/DOCUMENTATION.markdown Fri Oct 13 01:32:30 2017 -0400 +++ b/DOCUMENTATION.markdown Sat Dec 02 12:48:23 2017 -0500 @@ -1344,6 +1344,20 @@ +## Package `LOSH.LISTS` + +Utilities for operating on lists. + +### `SOMELIST` (function) + + (SOMELIST PREDICATE LIST) + +Call `predicate` on successive sublists of `list`, returning the first true result. + + `somelist` is to `some` as `maplist` is to `mapcar`. + + + ## Package `LOSH.MATH` Utilities related to math and numbers. @@ -1409,6 +1423,10 @@ Return whether `n` is evenly divisible by `divisor`. + The value returned will be the quotient when true, `nil` otherwise. + + + ### `IN-RANGE-P` (function) (IN-RANGE-P LOW VALUE HIGH) @@ -1903,6 +1921,28 @@ +### `PRODUCT` (function) + + (PRODUCT SEQUENCE &KEY KEY) + +Return the product of all elements of `sequence`. + + If `key` is given, it will be called on each element to compute the + multiplicand. + + Examples: + + (product #(1 2 3)) + ; => 6 + + (product '("1" "2" "3") :key #'parse-integer) + ; => 6 + + (product '("1" "2" "3") :key #'length) + ; => 1 + + + ### `PROPORTIONS` (function) (PROPORTIONS SEQUENCE &KEY (TEST 'EQL) (FLOAT T)) @@ -1926,6 +1966,30 @@ +### `SUMMATION` (function) + + (SUMMATION SEQUENCE &KEY KEY) + +Return the sum of all elements of `sequence`. + + If `key` is given, it will be called on each element to compute the addend. + + This function's ugly name was chosen so it wouldn't clash with iterate's `sum` + symbol. Sorry. + + Examples: + + (sum #(1 2 3)) + ; => 6 + + (sum '("1" "2" "3") :key #'parse-integer) + ; => 6 + + (sum '("1" "2" "3") :key #'length) + ; => 3 + + + ### `TAKE` (function) (TAKE N SEQ) diff -r 1e90139a06b1 -r 8cf0978477a8 losh.lisp --- a/losh.lisp Fri Oct 13 01:32:30 2017 -0400 +++ b/losh.lisp Sat Dec 02 12:48:23 2017 -0500 @@ -118,8 +118,14 @@ (* x x)) (defun-inline dividesp (n divisor) - "Return whether `n` is evenly divisible by `divisor`." - (zerop (mod n divisor))) + "Return whether `n` is evenly divisible by `divisor`. + + The value returned will be the quotient when true, `nil` otherwise. + + " + (multiple-value-bind (quotient remainder) (floor n divisor) + (when (zerop remainder) + quotient))) (declaim (ftype (function (real real real) @@ -2146,6 +2152,68 @@ el))))) +(defun-inlineable summation (sequence &key key) + "Return the sum of all elements of `sequence`. + + If `key` is given, it will be called on each element to compute the addend. + + This function's ugly name was chosen so it wouldn't clash with iterate's `sum` + symbol. Sorry. + + Examples: + + (sum #(1 2 3)) + ; => 6 + + (sum '(\"1\" \"2\" \"3\") :key #'parse-integer) + ; => 6 + + (sum '(\"1\" \"2\" \"3\") :key #'length) + ; => 3 + + " + (if key + (iterate (for n :in-whatever sequence) + (sum (funcall key n))) + (iterate (for n :in-whatever sequence) + (sum n)))) + +(defun-inlineable product (sequence &key key) + "Return the product of all elements of `sequence`. + + If `key` is given, it will be called on each element to compute the + multiplicand. + + Examples: + + (product #(1 2 3)) + ; => 6 + + (product '(\"1\" \"2\" \"3\") :key #'parse-integer) + ; => 6 + + (product '(\"1\" \"2\" \"3\") :key #'length) + ; => 1 + + " + (if key + (iterate (for n :in-whatever sequence) + (multiplying (funcall key n))) + (iterate (for n :in-whatever sequence) + (multiplying n)))) + + +;;;; Lists -------------------------------------------------------------------- +(defun somelist (predicate list) + "Call `predicate` on successive sublists of `list`, returning the first true result. + + `somelist` is to `some` as `maplist` is to `mapcar`. + + " + (iterate (for l :on list) + (thereis (funcall predicate l)))) + + ;;;; Debugging & Logging ------------------------------------------------------ (defun pr (&rest args) "Print `args` readably, separated by spaces and followed by a newline. diff -r 1e90139a06b1 -r 8cf0978477a8 make-docs.lisp --- a/make-docs.lisp Fri Oct 13 01:32:30 2017 -0400 +++ b/make-docs.lisp Sat Dec 02 12:48:23 2017 -0500 @@ -17,6 +17,7 @@ "LOSH.IO" "LOSH.ITERATE" "LOSH.LICENSING" + "LOSH.LISTS" "LOSH.MATH" "LOSH.MUTATION" "LOSH.PRIORITY-QUEUES" diff -r 1e90139a06b1 -r 8cf0978477a8 package.lisp --- a/package.lisp Fri Oct 13 01:32:30 2017 -0400 +++ b/package.lisp Sat Dec 02 12:48:23 2017 -0500 @@ -302,7 +302,14 @@ :take :take-while :drop - :drop-while)) + :drop-while + :summation + :product)) + +(defpackage :losh.lists + (:documentation "Utilities for operating on lists.") + (:export + :somelist)) (defpackage :losh.weightlists (:documentation @@ -332,6 +339,7 @@ :losh.io :losh.iterate :losh.licensing + :losh.lists :losh.math :losh.mutation :losh.priority-queues