# HG changeset patch # User Steve Losh # Date 1484920751 0 # Node ID d25b6f52fad15f77d5f5c9819d4ab8af57f6db1c # Parent 5dd997c404247dee64556b99c6f5d69ffde26d12 Add `enumerate`, expose `-<>`, add gnuplot terms diff -r 5dd997c40424 -r d25b6f52fad1 DOCUMENTATION.markdown --- a/DOCUMENTATION.markdown Thu Jan 19 17:05:14 2017 +0000 +++ b/DOCUMENTATION.markdown Fri Jan 20 13:59:11 2017 +0000 @@ -294,6 +294,12 @@ Utilities for managing control flow. +### `-<>` (macro) + + (-<> &REST FORMS) + +Thread the given forms, with `<>` as a placeholder. + ### `GATHERING` (macro) (GATHERING @@ -750,10 +756,11 @@ ### `GNUPLOT-ARGS` (function) - (GNUPLOT-ARGS &KEY (FILENAME plot.png) (STYLE :LINES) (SIZE-X 1200) - (SIZE-Y 800) (LABEL-X) (LABEL-Y) (LINE-TITLE 'DATA) - (LINE-WIDTH 4) (AXIS-X NIL) (AXIS-Y NIL) (GRAPH-TITLE) - (LOGSCALE-X NIL) (LOGSCALE-Y NIL) &ALLOW-OTHER-KEYS) + (GNUPLOT-ARGS &KEY (OUTPUT :QT) (FILENAME plot.png) (STYLE :LINES) + (SIZE-X 1200) (SIZE-Y 800) (LABEL-X) (LABEL-Y) + (LINE-TITLE 'DATA) (LINE-WIDTH 4) (AXIS-X NIL) (AXIS-Y NIL) + (GRAPH-TITLE) (LOGSCALE-X NIL) (LOGSCALE-Y NIL) + &ALLOW-OTHER-KEYS) Return the formatted command line arguments for the given gnuplot arguments. @@ -1403,11 +1410,33 @@ +### `ENUMERATE` (function) + + (ENUMERATE SEQUENCE &KEY (START 0) (STEP 1) KEY) + +Return an alist of `(n . element)` for each element of `sequence`. + + `start` and `step` control the values generated for `n`, NOT which elements of + the sequence are enumerated. + + Examples: + + (enumerate '(a b c)) + ; => ((0 . A) (1 . B) (2 . C)) + + (enumerate '(a b c) :start 1) + ; => ((1 . A) (2 . B) (3 . C)) + + (enumerate '(a b c) :key #'ensure-keyword) + ; => ((0 . :A) (1 . :B) (2 . :C)) + + + ### `EXTREMA` (function) (EXTREMA PREDICATE SEQUENCE) -Return the smallest and largest elements of `sequence` according to `predicate` +Return the smallest and largest elements of `sequence` according to `predicate`. `predicate` should be a strict ordering predicate (e.g. `<`). diff -r 5dd997c40424 -r d25b6f52fad1 losh.lisp --- a/losh.lisp Thu Jan 19 17:05:14 2017 +0000 +++ b/losh.lisp Fri Jan 20 13:59:11 2017 +0000 @@ -2,13 +2,17 @@ ;;;; Sanity ------------------------------------------------------------------- (defmacro -<> (&rest forms) + "Thread the given forms, with `<>` as a placeholder." ;; I am going to lose my fucking mind if I have to program lisp without ;; a threading macro, but I don't want to add another dep to this library, so ;; here we are. (if (null forms) '<> - `(let ((<> ,(first forms))) - (-<> ,@(rest forms))))) + (destructuring-bind (form . remaining) forms + `(let ((<> ,(if (symbolp form) + `(,form <>) + form))) + (-<> ,@remaining))))) ;;;; Types -------------------------------------------------------------------- @@ -1677,7 +1681,7 @@ (defun extrema (predicate sequence) - "Return the smallest and largest elements of `sequence` according to `predicate` + "Return the smallest and largest elements of `sequence` according to `predicate`. `predicate` should be a strict ordering predicate (e.g. `<`). @@ -1693,6 +1697,31 @@ (finally (return (values min max))))) +(defun enumerate (sequence &key (start 0) (step 1) key) + "Return an alist of `(n . element)` for each element of `sequence`. + + `start` and `step` control the values generated for `n`, NOT which elements of + the sequence are enumerated. + + Examples: + + (enumerate '(a b c)) + ; => ((0 . A) (1 . B) (2 . C)) + + (enumerate '(a b c) :start 1) + ; => ((1 . A) (2 . B) (3 . C)) + + (enumerate '(a b c) :key #'ensure-keyword) + ; => ((0 . :A) (1 . :B) (2 . :C)) + + " + (iterate (for el :in-whatever sequence) + (for n :from start :by step) + (collect (cons n (if key + (funcall key el) + el))))) + + ;;;; Debugging & Logging ------------------------------------------------------ (defun pr (&rest args) "Print `args` readably, separated by spaces and followed by a newline. @@ -2216,6 +2245,7 @@ (remove nil args))) (defun gnuplot-args (&key + (output :qt) (filename "plot.png") (style :lines) (size-x 1200) @@ -2239,9 +2269,13 @@ (flet ((esc (string) (remove #\' (aesthetic-string string))) (f (&rest args) (apply #'format nil args))) (gnuplot-args% - (f "set terminal pngcairo dashed size ~D,~D font \"Lucida Grande,20\"" - size-x size-y) - (f "set output '~A'" (esc filename)) + (ecase output + ((:x :x11) (f "set terminal x11 persist")) + (:qt (f "set terminal qt persist")) + (:png + (f "set terminal pngcairo dashed size ~D,~D font \"Lucida Grande,20\"" + size-x size-y) + (f "set output '~A'" (esc filename)))) (f "set border linewidth 1") (f "set style line 10 dashtype 2 linewidth 3 linecolor \"#666666\"") (when axis-x (f "set xzeroaxis linestyle 10")) diff -r 5dd997c40424 -r d25b6f52fad1 package.lisp --- a/package.lisp Thu Jan 19 17:05:14 2017 +0000 +++ b/package.lisp Fri Jan 20 13:59:11 2017 +0000 @@ -54,6 +54,8 @@ (defpackage :losh.control-flow (:documentation "Utilities for managing control flow.") (:export + :-<> + :<> :recursively :recur :when-found @@ -242,6 +244,7 @@ (:documentation "Utilities for operating on sequences.") (:export :extrema + :enumerate :prefix-sums :frequencies :proportions