--- a/losh.asd Sun Jun 09 11:26:44 2019 -0400
+++ b/losh.asd Thu Oct 03 10:38:04 2019 -0400
@@ -22,45 +22,51 @@
(:module "src"
:components (
+ ;; 0 ---------------------------------------------------------
(:file "chili-dogs")
(:file "clos")
(:file "eldritch-horrors")
(:file "functions")
(:file "hash-sets")
(:file "io")
- (:file "iterate-pre")
(:file "lists")
(:file "mutation")
+ ;; 1 ---------------------------------------------------------
(:file "arrays" :depends-on ("chili-dogs"))
(:file "bits" :depends-on ("chili-dogs"))
(:file "queues" :depends-on ("chili-dogs"))
(:file "priority-queues" :depends-on ("mutation"))
+ ;; 2 ---------------------------------------------------------
(:file "control-flow" :depends-on ("queues"))
+ ;; 3 ---------------------------------------------------------
+ (:file "iterate" :depends-on ("control-flow"
+ "hash-sets"))
(:file "math" :depends-on ("control-flow"
"chili-dogs"))
(:file "hash-tables" :depends-on ("control-flow"))
+
+ ;; 4 ---------------------------------------------------------
(:file "random" :depends-on ("math"
"chili-dogs"))
(:file "sequences" :depends-on ("chili-dogs"
"hash-tables"
"functions"
+ "iterate"
"mutation"))
(:file "debugging" :depends-on ("control-flow"
"math"
"hash-tables"))
- (:file "iterate" :depends-on ("control-flow"
- "sequences"
- "iterate-pre"
- "hash-sets"))
+ ;; 5 ---------------------------------------------------------
+ (:file "weightlists" :depends-on ("sequences"))
(:file "gnuplot" :depends-on ("control-flow"
+ "iterate"
"debugging"
"sequences"))
- (:file "weightlists" :depends-on ("sequences"))
))))
--- a/package.lisp Sun Jun 09 11:26:44 2019 -0400
+++ b/package.lisp Thu Oct 03 10:38:04 2019 -0400
@@ -107,11 +107,6 @@
:notf
:callf))
-(defpackage :losh.iterate-pre
- (:use :cl :iterate :losh.quickutils)
- (:export
- :in-whatever))
-
(defpackage :losh.arrays
(:use :cl :iterate :losh.quickutils
@@ -241,6 +236,49 @@
:remhash-if-value
:remhash-if-not-value))
+(defpackage :losh.iterate
+ (:use :cl :iterate :losh.quickutils
+ :losh.hash-sets
+ :losh.control-flow) ;; always needed because we need a single RECURSIVELY symbol
+ (:documentation "Custom `iterate` drivers and clauses.")
+ (:export
+
+ :across-flat-array
+ :anding
+ :averaging
+ :collect-frequencies
+ :collect-hash
+ :collect-set
+ :cycling
+ :every-nth
+ :finding-all
+ :for-nested
+ :in-array
+ :in-hashset
+ :in-lists
+ :in-sequences
+ :in-whatever
+ :index-of-flat-array
+ :initially
+ :into
+ :macroexpand-iterate
+ :modulo
+ :oring
+ :pairs-of-list
+ :per-iteration-into
+ :real-time
+ :recursively
+ :run-time
+ :seed
+ :since-start-into
+ :skip-origin
+ :test
+ :then
+ :timing
+ :within-radius
+
+ ))
+
(defpackage :losh.random
(:use :cl :iterate :losh.quickutils
@@ -263,7 +301,7 @@
:losh.chili-dogs
:losh.functions
:losh.hash-tables
- :losh.iterate-pre
+ :losh.iterate
:losh.mutation)
(:documentation "Utilities for operating on sequences.")
(:export
@@ -321,50 +359,6 @@
:gnuplot-function
:gnuplot-histogram))
-(defpackage :losh.iterate
- (:use :cl :iterate :losh.quickutils
- :losh.iterate-pre
- :losh.hash-sets
- :losh.control-flow ;; always needed because we need a single RECURSIVELY symbol
- :losh.sequences)
- (:documentation "Custom `iterate` drivers and clauses.")
- (:export
-
- :across-flat-array
- :anding
- :averaging
- :collect-hash
- :collect-set
- :cycling
- :every-nth
- :finding-all
- :for-nested
- :in-array
- :in-hashset
- :in-lists
- :in-sequences
- :in-whatever
- :index-of-flat-array
- :initially
- :into
- :macroexpand-iterate
- :modulo
- :oring
- :pairs-of-list
- :per-iteration-into
- :real-time
- :recursively
- :run-time
- :seed
- :since-start-into
- :skip-origin
- :test
- :then
- :timing
- :within-radius
-
- ))
-
(defpackage :losh.weightlists
(:use :cl :iterate :losh.quickutils
:losh.sequences)
--- a/src/iterate-pre.lisp Sun Jun 09 11:26:44 2019 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-(in-package :losh.iterate-pre)
-
-(defmacro-driver (FOR var IN-WHATEVER seq)
- "Iterate over items in the given sequence.
-
- Unlike iterate's own `in-sequence` this won't use the horrifyingly inefficient
- `elt`/`length` functions on a list.
-
- "
- (let ((kwd (if generate 'generate 'for)))
- (with-gensyms (is-list source i len)
- `(progn
- (with ,source = ,seq)
- (with ,is-list = (typep ,source 'list))
- (with ,len = (if ,is-list -1 (length ,source)))
- (for ,i :from 0)
- (,kwd ,var next (if ,is-list
- (if ,source
- (pop ,source)
- (terminate))
- (if (< ,i ,len)
- (elt ,source ,i)
- (terminate))))))))
--- a/src/iterate.lisp Sun Jun 09 11:26:44 2019 -0400
+++ b/src/iterate.lisp Thu Oct 03 10:38:04 2019 -0400
@@ -13,6 +13,29 @@
:with-index iterate::with-index))
+(defmacro-driver (FOR var IN-WHATEVER seq)
+ "Iterate over items in the given sequence.
+
+ Unlike iterate's own `in-sequence` this won't use the horrifyingly inefficient
+ `elt`/`length` functions on a list.
+
+ "
+ (let ((kwd (if generate 'generate 'for)))
+ (with-gensyms (is-list source i len)
+ `(progn
+ (with ,source = ,seq)
+ (with ,is-list = (typep ,source 'list))
+ (with ,len = (if ,is-list -1 (length ,source)))
+ (for ,i :from 0)
+ (,kwd ,var next (if ,is-list
+ (if ,source
+ (pop ,source)
+ (terminate))
+ (if (< ,i ,len)
+ (elt ,source ,i)
+ (terminate))))))))
+
+
(defmacro-driver (FOR var MODULO divisor &sequence)
"Iterate numerically with `var` bound modulo `divisor`.
@@ -616,6 +639,30 @@
(with ,hash-set = (make-hash-set :test ,test))
(hset-insert! ,hash-set ,element))))
+(defmacro-clause (COLLECT-FREQUENCIES expr &optional
+ INTO var
+ TEST (test '#'eql))
+ "Collect frequencies of `expr` values into a hash table at `var`.
+
+ If `var` is omitted the hash table will be returned instead.
+
+ `test` specifies the test used for the hash table.
+
+ Example:
+
+ (iterate (for x :in '(b a n a n a s))
+ (collect-frequencies x))
+ ; => {b 1
+ ; a 3
+ ; n 2
+ ; s 1}
+
+ "
+ (let ((hash-table (or var iterate::*result-var*)))
+ `(progn
+ (with ,hash-table = (make-hash-table :test ,test))
+ (incf (gethash ,expr ,hash-table 0)))))
+
(defmacro-clause (ORING expr &optional INTO var)
(let ((result (or var iterate::*result-var*)))
@@ -634,7 +681,8 @@
(defun keywordize-some-of-clause (clause)
; please kill me
- (append (take 2 clause) (keywordize-clause (nthcdr 2 clause))))
+ (append (list (first clause) (second clause))
+ (keywordize-clause (nthcdr 2 clause))))
(defun macroexpand-iterate (clause)
"Macroexpand the given iterate clause/driver.
--- a/src/sequences.lisp Sun Jun 09 11:26:44 2019 -0400
+++ b/src/sequences.lisp Thu Oct 03 10:38:04 2019 -0400
@@ -35,11 +35,8 @@
bar 1}
"
- (iterate
- (with result = (make-hash-table :test test))
- (for i :in-whatever sequence)
- (incf (gethash i result 0))
- (finally (return result))))
+ (iterate (for i :in-whatever sequence)
+ (collect-frequencies i)))
(defun proportions (sequence &key (test 'eql) (float t))
"Return a hash table containing the proportions of the items in `sequence`.