git.fiddlerwoaroof.com
t/transducers.lisp
ea96548e
 (defpackage :data-lens.t.transducers
6aebcfe4
   (:use :cl )
   (:export ))
db5988ec
 (in-package :data-lens.t.transducers)
6aebcfe4
 
 (5am:def-suite :data-lens.transducers)
 (5am:in-suite :data-lens.transducers)
 
 (5am:def-test mapping (:suite :data-lens.transducers)
   (5am:is (equal '(2 3 4)
                  (data-lens.transducers:transduce (data-lens.transducers:mapping '1+)
                                                   'data-lens.transducers:list-builder
                                                   '(1 2 3)))))
 
47d7f624
 (5am:def-test mv-mapping (:suite :data-lens.transducers
                           :depends-on mapping)
6aebcfe4
   (5am:is (equal '((2 0) (3 1) (4 2))
                  (data-lens.transducers:transduce (data-lens.transducers:mv-mapping
                                                    (lambda (it)
                                                      (values (1+ it) (1- it))))
                                                   'data-lens.transducers:list-builder
                                                   '(1 2 3)))))
 
47d7f624
 (5am:def-test mv-selecting (:suite :data-lens.transducers
                             :depends-on mapping)
ea96548e
   (5am:is (equal '(2 4)
                  (data-lens.transducers:transduce (data-lens.transducers:mv-selecting
                                                    (lambda (it)
                                                      (values (1+ it) (oddp it))))
                                                   'data-lens.transducers:list-builder
                                                   '(1 2 3))))
   (5am:is (equal '(a b)
                  (data-lens.transducers:transduce (data-lens.transducers:hash-table-select
                                                    (alexandria:alist-hash-table
                                                     '((1 . a)
                                                       (2 . b))))
                                                   'data-lens.transducers:list-builder
                                                   '(1 2)))))
 
47d7f624
 (5am:def-test filtering (:suite :data-lens.transducers
                          :depends-on mapping)
ea96548e
   (5am:is (equal '(1 3)
                  (data-lens.transducers:transduce (data-lens.transducers:filtering 'oddp)
                                                   'data-lens.transducers:list-builder
                                                   '(1 2 3))))
   (5am:is (equal '(1 2)
                  (data-lens.transducers:transduce (data-lens.transducers:mv-filtering
                                                    'gethash (alexandria:alist-hash-table
                                                              '((1 . a)
                                                                (2 . b))))
                                                   'data-lens.transducers:list-builder
                                                   '(1 2 3)))))
 
47d7f624
 (5am:def-test deduping (:suite :data-lens.transducers
                         :depends-on mapping)
ea96548e
   (5am:is (equal '(1 2 1 2 3 4 1)
                  (data-lens.transducers:transduce (data-lens.transducers:deduping)
                                                   'data-lens.transducers:list-builder
                                                   '(1 1 2 1 2 2 3 3 4 1))))
   (loop for first-number = (random 4)
         for second-number = (+ 5 (random 4))
         for third-number = (+ 10 (random 4))
         repeat 10 do
           (5am:is
            (equal (data-lens.transducers:transduce
                    (data-lens:• (data-lens.transducers:catting)
                                 (data-lens.transducers:deduping))
                    'data-lens.transducers:list-builder
                    (list (data-lens.transducers:repeating* first-number :count (+ 1 (random 10)))
                          (data-lens.transducers:repeating* second-number :count (+ 1 (random 5)))
                          (data-lens.transducers:repeating* third-number :count (+ 1 (random 3)))))
                   (list first-number second-number third-number)))))
 
47d7f624
 (5am:def-test compressing-runs (:suite :data-lens.transducers
                                 :depends-on mapping)
ea96548e
   (5am:is (equal '(1 2 1 2 3 4 1)
                  (data-lens.transducers:transduce (data-lens.transducers:compressing-runs)
                                                   'data-lens.transducers:list-builder
                                                   '(1 1 2 1 2 2 3 3 4 1))))
   (loop for input = '(1) then (cons 1 input)
         repeat 5 do
           (5am:is (equal '(1)
                          (data-lens.transducers:transduce (data-lens.transducers:compressing-runs)
                                                           'data-lens.transducers:list-builder
                                                           input))))
   (loop for input = '(2 1) then (cons 2 input)
         repeat 5 do
           (5am:is (equal '(2 1)
                          (data-lens.transducers:transduce (data-lens.transducers:compressing-runs)
                                                           'data-lens.transducers:list-builder
                                                           input))))
   (loop for input = '(1 2) then (append input '(2))
         repeat 5 do
           (5am:is (equal '(1 2)
                          (data-lens.transducers:transduce (data-lens.transducers:compressing-runs)
                                                           'data-lens.transducers:list-builder
e08fccfe
                                                           input))))
 
   (5am:is
    (equal '((1 2 2 2 3 3 3)
             (2 4 4 4 5 5 5)
             (3 6 6 6))
           (data-lens.transducers:transduce
            (data-lens.transducers:compressing-runs
             :test (lambda (a b) (eql (car a) (car b)))
             :combiner (lambda (a b)
                         (if a
                             (append a (cdr b))
                             b)))
            'data-lens.transducers:list-builder
            '((1 2 2 2) (1 3 3 3)
              (2 4 4 4) (2 5 5 5)
              (3 6 6 6))))))
ea96548e
 
47d7f624
 (5am:def-test catting (:suite :data-lens.transducers
                        :depends-on mapping)
ea96548e
   (5am:is (equal '(1 1 2 1 2 2 3 3 4 1)
                  (data-lens.transducers:transduce (data-lens.transducers:catting)
                                                   'data-lens.transducers:list-builder
                                                   '((1 1) (2 1 2) (2) (3 3) (4 1))))))
 
47d7f624
 (5am:def-test mapcatting (:suite :data-lens.transducers
                           :depends-on catting)
ea96548e
   (5am:is (equal '(1 1 2 1 2 2 3 3 4 1)
                  (data-lens.transducers:transduce (data-lens.transducers:mapcatting 'list)
                                                   'data-lens.transducers:list-builder
d0e894f7
                                                   '(1 1 2 1 2 2 3 3 4 1))))
   (5am:is (equal '(0 0 1 0 1 2)
                  (data-lens.transducers:transduce (data-lens.transducers:mapcatting 'identity)
                                                   'data-lens.transducers:list-builder
                                                   (list (data-lens.transducers:iota :count 1)
                                                         (data-lens.transducers:iota :count 2)
                                                         (data-lens.transducers:iota :count 3))))))
ea96548e
 
47d7f624
 (5am:def-test collecting (:suite :data-lens.transducers
                           :depends-on mapcatting)
   (5am:is (equal '(1 3 6 9 13 18 22 27 33 40)
                  (data-lens.transducers:transduce (data-lens:• (data-lens.transducers:taking 5)
                                                                (data-lens.transducers:mapcatting 'identity)
                                                                (data-lens.transducers::collecting '+))
                                                   'data-lens.transducers:list-builder
                                                   (loop for x from 1
                                                         repeat 4
                                                         collect
                                                         (data-lens.transducers:iota :start x
                                                                                     :count x))))))
 
 (5am:def-test splitting (:suite :data-lens.transducers
                          :depends-on mapping)
ea96548e
   (5am:is (equal '((2 0) (3 1) (4 2))
                  (data-lens.transducers:transduce (data-lens.transducers:splitting '1+ '1-)
                                                   'data-lens.transducers:list-builder
                                                   '(1 2 3)))))
 
47d7f624
 (5am:def-test transducer-composition (:suite :data-lens.transducers
                                       :depends-on (and filtering mapping))
   (5am:is (equal '(7)
6aebcfe4
                  (data-lens.transducers:transduce (data-lens:•
47d7f624
                                                    (data-lens.transducers:filtering #'oddp)
6aebcfe4
                                                    (data-lens.transducers:mapping
                                                     (lambda (x)
                                                       (* 2 x)))
47d7f624
                                                    (data-lens.transducers:mapping '1+)
                                                    (data-lens.transducers:dropping 1))
6aebcfe4
                                                   'data-lens.transducers:list-builder
                                                   '(1 2 3))))
47d7f624
   (5am:is (equal '(3 5)
6aebcfe4
                  (data-lens.transducers:transduce (data-lens:•
47d7f624
                                                    (data-lens.transducers:taking 2)
6aebcfe4
                                                    (data-lens.transducers:mapping
                                                     (lambda (x)
                                                       (* 2 x)))
                                                    (data-lens.transducers:mapping '1+))
                                                   'data-lens.transducers:list-builder
                                                   '(1 2 3)))))
ea96548e
 
47d7f624
 (5am:def-test complicated (:suite :data-lens.transducers
                            :depends-on (and catting mapping filtering splitting
                                             transducer-composition))
ea96548e
   (let ((result (data-lens.transducers:transduce
                  (data-lens:•
                   (data-lens.transducers:catting)
                   (data-lens.transducers:mapping #'parse-integer)
                   (data-lens.transducers:filtering (complement #'evenp))
                   (data-lens.transducers:splitting (serapeum:op (* 2 _)) #'identity)
                   (data-lens.transducers:mapping (data-lens:transform-head #'1+))
                   (data-lens.transducers:taking 3))
                  'data-lens.transducers:hash-table-builder
                  '(("123" "234" "345" "454")
                    ("568" "490")
                    ("567" "213")))))
     (5am:is (equal '((247 . 123)
                      (691 . 345)
                      (1135 . 567))
                    (funcall (data-lens:• (data-lens:sorted '< :key 'car)
                                          (data-lens:sorted '< :key 'cdr))
                             (alexandria:hash-table-alist result))))))
bd9ef2fb
 
 (5am:def-test into (:suite :data-lens.transducers :depends-on mapping)
   (5am:is (equal '(0 1 2)
                  (data-lens.transducers:into '()
                                              (data-lens.transducers:taking 3)
                                              (data-lens.transducers:iota))))
 
   (5am:is (equal '(0 1 2)
                  (data-lens.transducers:into '(0 1 2)
                                              (data-lens.transducers:taking 0)
                                              (data-lens.transducers:iota))))
 
   (5am:is (equal '()
                  (data-lens.transducers:into '()
                                              (data-lens.transducers:taking 0)
                                              (data-lens.transducers:iota))))
 
   (5am:is (equal '()
                  (data-lens.transducers:into '()
                                              (data-lens.transducers:mapping #'identity)
                                              #())))
 
   (5am:is (equalp (alexandria:plist-hash-table '(:p 0 :l 1 :i 2 :s 3 :t 4))
                   (let ((count 0))
                     (data-lens.transducers:into (make-hash-table)
                                                 (data-lens.transducers:mapping
                                                  (lambda (it)
                                                    (prog1 (list it count)
                                                      (incf count))))
                                                 '(:p :l :i :s :t)))))
e0688b8f
   (let ((l '((1 . 2)
              (2 . 3)
              (3 . 4))))
     (5am:is (equal l
                    (sort (alexandria:hash-table-alist
                           (data-lens.transducers:into (make-hash-table)
                                                       (data-lens.transducers:mapping 'identity)
                                                       (alexandria:alist-hash-table l)))
                          '<
                          :key 'car))))
bd9ef2fb
 
   (loop for type in '(vector list)
         do (5am:is (equalp #(1 2 3 4 5 6)
                            (data-lens.transducers:into #(1 2 3)
                                                        (data-lens.transducers:mapping
                                                         (data-lens:inc 4))
                                                        (coerce #(0 1 2) type))))
            (5am:is (equal '(1 2 3 4 5 6)
                           (data-lens.transducers:into '(1 2 3)
                                                       (data-lens.transducers:mapping
                                                        (data-lens:inc 4))
                                                       (coerce #(0 1 2) type))))
 
            (5am:is (equal '(1 2 3 4 5 6)
                           (data-lens.transducers:into '(1 2 3)
                                                       (data-lens.transducers:mapping
                                                        (data-lens:inc 4))
                                                       (coerce #(0 1 2) type))))
            (5am:is (equal '(1 2 3 4 5 6)
                           (data-lens.transducers:into '(1 2 3)
                                                       (data-lens:•
                                                        (data-lens.transducers:taking 3)
                                                        (data-lens.transducers:mapping
                                                         (data-lens:inc 4)))
                                                       (data-lens.transducers:iota))))
            (5am:is (equalp #(1 2 3 4 5 6)
                            (data-lens.transducers:into #(1 2 3)
                                                        (data-lens:•
                                                         (data-lens.transducers:taking 3)
                                                         (data-lens.transducers:mapping
                                                          (data-lens:inc 4)))
1be82ea4
                                                        (data-lens.transducers:iota))))))