--- a/DOCUMENTATION.markdown Sun May 07 23:41:20 2017 +0000
+++ b/DOCUMENTATION.markdown Thu Jun 22 18:39:52 2017 +0000
@@ -422,32 +422,6 @@
-### `RECURSIVELY` (macro)
-
- (RECURSIVELY BINDINGS
- &BODY
- BODY)
-
-Execute `body` recursively, like Clojure's `loop`/`recur`.
-
- `bindings` should contain a list of symbols and (optional) starting values.
-
- In `body` the symbol `recur` will be bound to the function for recurring.
-
- This macro doesn't perform an explicit tail-recursion check like Clojure's
- `loop`. You know what you're doing, right?
-
- Example:
-
- (defun length (some-list)
- (recursively ((list some-list)
- (n 0))
- (if (null list)
- n
- (recur (cdr list) (1+ n)))))
-
-
-
### `WHEN-FOUND` (macro)
(WHEN-FOUND VAR
@@ -563,6 +537,12 @@
+### `GIMME` (macro)
+
+ (GIMME N
+ &BODY
+ BODY)
+
### `PHT` (function)
(PHT HASH-TABLE &OPTIONAL (STREAM T))
@@ -662,7 +642,7 @@
### `START-PROFILING` (function)
- (START-PROFILING &OPTIONAL CALL-COUNT-PACKAGES)
+ (START-PROFILING &KEY CALL-COUNT-PACKAGES (MODE :CPU))
Start profiling performance. SBCL only.
@@ -829,8 +809,8 @@
(SIZE-X 1200) (SIZE-Y 800) (LABEL-X) (LABEL-Y)
(LINE-TITLE 'DATA) (LINE-WIDTH 4) (SMOOTH NIL) (AXIS-X NIL)
(AXIS-Y NIL) (MIN-X NIL) (MAX-X NIL) (MIN-Y NIL) (MAX-Y NIL)
- (GRAPH-TITLE) (LOGSCALE-X NIL) (LOGSCALE-Y NIL)
- &ALLOW-OTHER-KEYS)
+ (TICS-X NIL) (GRAPH-TITLE) (LOGSCALE-X NIL) (LOGSCALE-Y NIL)
+ (BOX-WIDTH NIL) &ALLOW-OTHER-KEYS)
Return the formatted command line arguments for the given gnuplot arguments.
@@ -862,6 +842,18 @@
+### `GNUPLOT-HISTOGRAM` (function)
+
+ (GNUPLOT-HISTOGRAM DATA &KEY (BIN-WIDTH 1))
+
+Plot `data` as a histogram with gnuplot.
+
+ `bin-width` should be the desired width of the bins. The bins will be
+ centered on multiples of this number, and data will be rounded to the nearest
+ bin.
+
+
+
## Package `LOSH.HASH-SETS`
Simple hash set implementation.
--- a/losh.lisp Sun May 07 23:41:20 2017 +0000
+++ b/losh.lisp Thu Jun 22 18:39:52 2017 +0000
@@ -1587,6 +1587,12 @@
(let ((kwd (if generate 'generate 'for)))
`(,kwd (,var) :in-hashtable (hash-set-storage ,hset))))
+(defmacro-driver (FOR var RECURSIVELY expr INITIALLY init)
+ (let ((kwd (if generate 'generate 'for)))
+ `(progn
+ (initially (setf ,var ,init))
+ (,kwd ,var = ,expr))))
+
;;;; Hash Tables --------------------------------------------------------------
(defun mutate-hash-values (function hash-table)
@@ -2053,7 +2059,7 @@
:min-percent 0.5)))
#+sbcl
-(defun start-profiling (&optional call-count-packages)
+(defun start-profiling (&key call-count-packages (mode :cpu))
"Start profiling performance. SBCL only.
`call-count-packages` should be a list of package designators. Functions in
@@ -2067,7 +2073,7 @@
(mapcar #'string-upcase <>)
(mapc #'sb-sprof::profile-call-counts <>))
(sb-sprof::start-profiling :max-samples 50000
- :mode :cpu
+ :mode mode
; :mode :time
:sample-interval 0.01
:threads :all))
@@ -2088,6 +2094,11 @@
(stop-profiling))))
+(defmacro gimme (n &body body)
+ `(iterate (repeat ,n)
+ (collect (progn ,@body))))
+
+
;;;; CLOS ---------------------------------------------------------------------
(defun build-slot-definition (conc-name slot-spec)
(destructuring-bind (name &key
@@ -2541,9 +2552,11 @@
(max-x nil)
(min-y nil)
(max-y nil)
+ (tics-x nil)
(graph-title)
(logscale-x nil)
(logscale-y nil)
+ (box-width nil)
&allow-other-keys)
"Return the formatted command line arguments for the given gnuplot arguments.
@@ -2564,7 +2577,9 @@
(f "set border linewidth 1")
(f "set style line 10 dashtype 2 linewidth 3 linecolor \"#666666\"")
(when axis-x (f "set xzeroaxis linestyle 10"))
+ (when tics-x (f "set xtics ~A" tics-x))
(when axis-y (f "set yzeroaxis linestyle 10"))
+ (when box-width (f "set boxwidth ~A" box-width))
(when graph-title (f "set title '~A'" (esc graph-title)))
(when label-x (f "set xlabel '~A'" (esc label-x)))
(when label-y (f "set ylabel '~A'" (esc label-y)))
@@ -2652,6 +2667,26 @@
,@args))
+(defun gnuplot-histogram (data &key (bin-width 1))
+ "Plot `data` as a histogram with gnuplot.
+
+ `bin-width` should be the desired width of the bins. The bins will be
+ centered on multiples of this number, and data will be rounded to the nearest
+ bin.
+
+ "
+ (-<> data
+ (mapcar (lambda (y)
+ (* bin-width (round y bin-width)))
+ <>)
+ frequencies
+ hash-table-alist
+ (gnuplot <> :style :boxes
+ :min-y 0
+ :line-width 1
+ :box-width (* bin-width 1.0))))
+
+
;;;; Licensing ----------------------------------------------------------------
;;; Original code from @dk_jackdaniel:
;;; http://paste.lisp.org/display/327154
--- a/package.lisp Sun May 07 23:41:20 2017 +0000
+++ b/package.lisp Thu Jun 22 18:39:52 2017 +0000
@@ -17,6 +17,10 @@
:collect `(:export ,@(external-symbols parent-package)))))
+(defpackage :losh.base
+ (:export :recursively))
+
+
(defpackage :losh.arrays
(:documentation "Utilities related to arrays.")
(:export
@@ -52,6 +56,7 @@
:defclass*))
(defpackage :losh.control-flow
+ (:use :losh.base)
(:documentation "Utilities for managing control flow.")
(:export
:-<>
@@ -77,6 +82,7 @@
:comment
:aesthetic-string
:structural-string
+ :gimme
#+sbcl :start-profiling
#+sbcl :stop-profiling
#+sbcl :profile
@@ -105,6 +111,7 @@
:gnuplot-args
:gnuplot-expr
:gnuplot-function
+ :gnuplot-histogram
:x))
(defpackage :losh.hash-sets
@@ -151,7 +158,7 @@
:read-all-from-string))
(defpackage :losh.iterate
- (:use :iterate) ; need this for iterate's `for` symbol fuckery
+ (:use :iterate :losh.base) ; need this for iterate's `for` symbol fuckery
(:documentation "Custom `iterate` drivers and clauses.")
(:export
@@ -168,6 +175,7 @@
:in-sequences
:in-whatever
:index-of-flat-array
+ :initially
:into
:macroexpand-iterate
:modulo
@@ -175,6 +183,7 @@
:pairs-of-list
:per-iteration-into
:real-time
+ :recursively
:run-time
:since-start-into
:skip-origin