emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/taxy 2c044ed 39/39: Add: (taxy-take-keyed*) :then, and


From: ELPA Syncer
Subject: [elpa] externals/taxy 2c044ed 39/39: Add: (taxy-take-keyed*) :then, and examples
Date: Fri, 27 Aug 2021 10:57:37 -0400 (EDT)

branch: externals/taxy
commit 2c044ed4b2033a36878b3ed00cdc2afb73f32368
Author: Adam Porter <adam@alphapapa.net>
Commit: Adam Porter <adam@alphapapa.net>

    Add: (taxy-take-keyed*) :then, and examples
---
 README.org | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 taxy.el    |   7 +-
 taxy.info  | 253 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 455 insertions(+), 24 deletions(-)

diff --git a/README.org b/README.org
index 94f5c24..da4b5b4 100644
--- a/README.org
+++ b/README.org
@@ -23,7 +23,10 @@ Helpful features include:
 :END:
 :CONTENTS:
 - [[#examples][Examples]]
-  - [[#example-applications][Example applications]]
+  - [[#numbery-starting-basically][Numbery (starting basically)]]
+  - [[#lettery-filling-incrementally][Lettery (filling incrementally)]]
+  - [[#sporty-understanding-completely][Sporty (understanding completely)]]
+  - [[#applications][Applications]]
 - [[#usage][Usage]]
   - [[#dynamic-taxys][Dynamic taxys]]
   - [[#reusable-taxys][Reusable taxys]]
@@ -35,6 +38,19 @@ Helpful features include:
 :END:
 
 * Examples
+:PROPERTIES:
+:TOC:      :include descendants :depth 1
+:END:
+:CONTENTS:
+- [[#numbery-starting-basically][Numbery (starting basically)]]
+- [[#lettery-filling-incrementally][Lettery (filling incrementally)]]
+- [[#sporty-understanding-completely][Sporty (understanding completely)]]
+- [[#applications][Applications]]
+:END:
+
+May these examples help you classify your understanding.
+
+** Numbery (starting basically)
 
 Let's imagine a silly taxonomy of numbers below 100:
 
@@ -134,6 +150,8 @@ You might think about how to produce that by writing some 
imperative code, but =
 
 The ~taxy-fill~ function applies the numbers in a "cascade" down the hierarchy 
of "taxys", and the ~taxy-plain~ function returns a meaningful subset of the 
taxys' slots, suitable for display.
 
+** Lettery (filling incrementally)
+
 You can also add more objects after the hierarchy has been filled:
 
 #+BEGIN_SRC elisp
@@ -200,7 +218,204 @@ That's better:
      ("B" "C" "D" "F" "G" "H" "J" "K" "L" "M" "N" "N" "P" "Q" "R" "S" "T" "V" 
"W" "X" "Y" "Z"))))
 #+END_SRC
 
-** Example applications
+** Sporty (understanding completely)
+
+Let's try to understand a few things about sports.  First we'll define a 
struct to make them easier to grasp:
+
+#+BEGIN_SRC elisp :exports code :results silent
+  (cl-defstruct sport
+    name uses venue fun)
+#+END_SRC
+
+Now we'll make a list of sports:
+
+#+BEGIN_SRC elisp :exports code :results silent
+  (defvar sports
+    (list (make-sport :name "Baseball"
+                      :uses '(bat ball glove)
+                      :venue 'outdoor
+                      :fun t)
+          (make-sport :name "Football"
+                      :uses '(ball)
+                      :venue 'outdoor
+                      :fun t)
+          (make-sport :name "Basketball"
+                      :uses '(ball hoop)
+                      :venue 'indoor
+                      :fun t)
+          (make-sport :name "Tennis"
+                      :uses '(ball racket)
+                      :venue 'outdoor
+                      :fun t)
+          (make-sport :name "Racquetball"
+                      :uses '(ball racket)
+                      :venue 'indoor
+                      :fun t)
+          (make-sport :name "Handball"
+                      :uses '(ball glove)
+                      :venue 'indoor
+                      :fun t)
+          (make-sport :name "Soccer"
+                      :uses '(ball)
+                      :venue 'outdoor
+                      :fun nil)
+          (make-sport :name "Disc golf"
+                      :uses '(disc basket)
+                      :venue 'outdoor
+                      :fun t)
+          (make-sport :name "Ultimate"
+                      :uses '(disc)
+                      :venue 'outdoor
+                      :fun t)
+          (make-sport :name "Volleyball"
+                      :uses '(ball)
+                      :venue 'indoor
+                      :fun t)))
+#+END_SRC
+
+And finally we'll define a taxy to organize them.  In this, we use a helper 
macro to make the ~member~ function easier to use in the list of key functions:
+
+#+BEGIN_SRC elisp :exports code :results silent :lexical t
+  (defvar sporty
+    (cl-macrolet ((in (needle haystack)
+                      `(lambda (object)
+                         (when (member ,needle (funcall ,haystack object))
+                           ,needle))))
+      (make-taxy
+       :taxys (list (make-taxy
+                     :name "Sporty"
+                     :take (lambda (object taxy)
+                             (taxy-take-keyed*
+                              (list #'sport-venue
+                                    (in 'ball 'sport-uses)
+                                    (in 'disc 'sport-uses)
+                                    (in 'glove 'sport-uses)
+                                    (in 'racket 'sport-uses))
+                              object taxy
+                              ;; We set the `:then' function of the taxys
+                              ;; created by `taxy-take-keyed*' to `identity'
+                              ;; so they will not consume their objects.
+                              :then #'identity)))))))
+#+END_SRC
+
+Now let's fill the taxy with the sports and format it:
+
+#+BEGIN_SRC elisp :exports code
+  (thread-last sporty
+    taxy-emptied
+    (taxy-fill sports)
+    (taxy-mapcar #'sport-name)
+    taxy-plain)
+#+END_SRC
+
+#+BEGIN_SRC elisp :exports code
+((("Sporty"
+   ((disc
+     ((outdoor
+       ("Ultimate" "Disc golf"))))
+    (ball
+     ((racket
+       ((indoor
+         ("Racquetball"))
+        (outdoor
+         ("Tennis"))))
+      (indoor
+       ("Volleyball" "Basketball"))
+      (outdoor
+       ("Soccer" "Football"))
+      (glove
+       ((indoor
+         ("Handball"))
+        (outdoor
+         ("Baseball"))))))))))
+#+END_SRC
+
+That's pretty sporty.  But classifying them by venue first makes the racket 
and glove sports not be listed together.  Let's swap that around:
+
+#+BEGIN_SRC elisp :exports code :results silent
+  (defvar sporty
+    (cl-macrolet ((in (needle haystack)
+                      `(lambda (object)
+                         (when (member ,needle (funcall ,haystack object))
+                           ,needle))))
+      (make-taxy
+       :taxys (list (make-taxy
+                     :name "Sporty"
+                     :take (lambda (object taxy)
+                             (taxy-take-keyed*
+                              (list (in 'ball 'sport-uses)
+                                    (in 'disc 'sport-uses)
+                                    (in 'glove 'sport-uses)
+                                    (in 'racket 'sport-uses)
+                                    #'sport-venue)
+                              object taxy
+                              :then #'identity)))))))
+
+  (thread-last sporty
+    taxy-emptied
+    (taxy-fill sports)
+    (taxy-mapcar #'sport-name)
+    taxy-plain)
+#+END_SRC
+
+#+BEGIN_SRC elisp :exports code
+((("Sporty"
+   ((disc
+     ((outdoor
+       ("Ultimate" "Disc golf"))))
+    (ball
+     ((racket
+       ((indoor
+         ("Racquetball"))
+        (outdoor
+         ("Tennis"))))
+      (indoor
+       ("Volleyball" "Basketball"))
+      (outdoor
+       ("Soccer" "Football"))
+      (glove
+       ((indoor
+         ("Handball"))
+        (outdoor
+         ("Baseball"))))))))))
+#+END_SRC
+
+That's better.  But I'd also like to see a very simple classification to help 
me decide what to play:
+
+#+BEGIN_SRC elisp :exports code
+  (thread-last
+      (make-taxy
+       :taxys (list
+               (make-taxy
+                :name "Funny"
+                :take (lambda (object taxy)
+                        (taxy-take-keyed*
+                         (list (lambda (sport)
+                                 (if (sport-fun sport)
+                                     'fun 'boring))
+                               #'sport-venue)
+                         object taxy)))))
+    taxy-emptied
+    (taxy-fill sports)
+    (taxy-mapcar #'sport-name)
+    taxy-plain)
+#+END_SRC
+
+#+BEGIN_SRC elisp :exports code
+((("Funny"
+   ((boring
+     ((outdoor
+       ("Soccer"))))
+    (fun
+     ((indoor
+       ("Volleyball" "Handball" "Racquetball" "Basketball"))
+      (outdoor
+       ("Ultimate" "Disc golf" "Tennis" "Football" "Baseball"))))))))
+#+END_SRC
+
+Ah, now I understand.
+
+** Applications
 
 Some example applications may be found in the 
[[file:examples/README.org][examples directory]]:
 
diff --git a/taxy.el b/taxy.el
index 334d1c8..0697aae 100644
--- a/taxy.el
+++ b/taxy.el
@@ -146,7 +146,9 @@ by KEY-NAME-FN called with OBJECT."
                      (taxy-taxys taxy))))))
     (push object (taxy-objects key-taxy))))
 
-(cl-defun taxy-take-keyed* (key-fns object taxy &key (key-name-fn #'identity))
+(cl-defun taxy-take-keyed*
+    (key-fns object taxy
+             &key (key-name-fn #'identity) (then #'ignore))
   "Take OBJECT into TAXY, adding new taxys dynamically and recursively.
 Places OBJECT into a taxy in TAXY for the value returned by
 KEY-FNS called with OBJECT.  The new taxys are added to TAXY
@@ -165,7 +167,8 @@ by KEY-NAME-FN called with OBJECT."
                                                  (equal key (funcall key-fn 
object)))
                                     :take (when (cdr key-fns)
                                             (lambda (object taxy)
-                                              (taxy-take-keyed* (cdr key-fns) 
object taxy))))
+                                              (taxy-take-keyed* (cdr key-fns) 
object taxy)))
+                                    :then then)
                                    (taxy-taxys taxy))))))
           (if (cdr key-fns)
               (taxy-take-keyed* (cdr key-fns) object key-taxy)
diff --git a/taxy.info b/taxy.info
index c8e4df4..418868f 100644
--- a/taxy.info
+++ b/taxy.info
@@ -23,7 +23,11 @@ taxy.el
 
 Examples
 
-* Example applications::
+* Numbery (starting basically)::
+* Lettery (filling incrementally)::
+* Sporty (understanding completely)::
+* Applications::
+
 
 
 Usage
@@ -63,6 +67,22 @@ File: README.info,  Node: Examples,  Next: Usage,  Prev: 
Top,  Up: Top
 1 Examples
 **********
 
+   • • • • 
+   May these examples help you classify your understanding.
+
+* Menu:
+
+* Numbery (starting basically)::
+* Lettery (filling incrementally)::
+* Sporty (understanding completely)::
+* Applications::
+
+
+File: README.info,  Node: Numbery (starting basically),  Next: Lettery 
(filling incrementally),  Up: Examples
+
+1.1 Numbery (starting basically)
+================================
+
 Let’s imagine a silly taxonomy of numbers below 100:
 
      ("Numbery" "A silly taxonomy of numbers."
@@ -161,7 +181,13 @@ manner:
 hierarchy of "taxys", and the ‘taxy-plain’ function returns a meaningful
 subset of the taxys’ slots, suitable for display.
 
-   You can also add more objects after the hierarchy has been filled:
+
+File: README.info,  Node: Lettery (filling incrementally),  Next: Sporty 
(understanding completely),  Prev: Numbery (starting basically),  Up: Examples
+
+1.2 Lettery (filling incrementally)
+===================================
+
+You can also add more objects after the hierarchy has been filled:
 
      (defvar lettery
        (make-taxy :name "Lettery"
@@ -215,15 +241,199 @@ subset of the taxys’ slots, suitable for display.
        ("Consonants" "Well, if they aren't a vowel..."
         ("B" "C" "D" "F" "G" "H" "J" "K" "L" "M" "N" "N" "P" "Q" "R" "S" "T" 
"V" "W" "X" "Y" "Z"))))
 
-* Menu:
+
+File: README.info,  Node: Sporty (understanding completely),  Next: 
Applications,  Prev: Lettery (filling incrementally),  Up: Examples
+
+1.3 Sporty (understanding completely)
+=====================================
+
+Let’s try to understand a few things about sports.  First we’ll define a
+struct to make them easier to grasp:
+
+     (cl-defstruct sport
+       name uses venue fun)
+
+   Now we’ll make a list of sports:
+
+     (defvar sports
+       (list (make-sport :name "Baseball"
+                         :uses '(bat ball glove)
+                         :venue 'outdoor
+                         :fun t)
+             (make-sport :name "Football"
+                         :uses '(ball)
+                         :venue 'outdoor
+                         :fun t)
+             (make-sport :name "Basketball"
+                         :uses '(ball hoop)
+                         :venue 'indoor
+                         :fun t)
+             (make-sport :name "Tennis"
+                         :uses '(ball racket)
+                         :venue 'outdoor
+                         :fun t)
+             (make-sport :name "Racquetball"
+                         :uses '(ball racket)
+                         :venue 'indoor
+                         :fun t)
+             (make-sport :name "Handball"
+                         :uses '(ball glove)
+                         :venue 'indoor
+                         :fun t)
+             (make-sport :name "Soccer"
+                         :uses '(ball)
+                         :venue 'outdoor
+                         :fun nil)
+             (make-sport :name "Disc golf"
+                         :uses '(disc basket)
+                         :venue 'outdoor
+                         :fun t)
+             (make-sport :name "Ultimate"
+                         :uses '(disc)
+                         :venue 'outdoor
+                         :fun t)
+             (make-sport :name "Volleyball"
+                         :uses '(ball)
+                         :venue 'indoor
+                         :fun t)))
+
+   And finally we’ll define a taxy to organize them.  In this, we use a
+helper macro to make the ‘member’ function easier to use in the list of
+key functions:
+
+     (defvar sporty
+       (cl-macrolet ((in (needle haystack)
+                         `(lambda (object)
+                            (when (member ,needle (funcall ,haystack object))
+                              ,needle))))
+         (make-taxy
+          :taxys (list (make-taxy
+                        :name "Sporty"
+                        :take (lambda (object taxy)
+                                (taxy-take-keyed*
+                                 (list #'sport-venue
+                                       (in 'ball 'sport-uses)
+                                       (in 'disc 'sport-uses)
+                                       (in 'glove 'sport-uses)
+                                       (in 'racket 'sport-uses))
+                                 object taxy
+                                 ;; We set the `:then' function of the taxys
+                                 ;; created by `taxy-take-keyed*' to `identity'
+                                 ;; so they will not consume their objects.
+                                 :then #'identity)))))))
+
+   Now let’s fill the taxy with the sports and format it:
+
+     (thread-last sporty
+       taxy-emptied
+       (taxy-fill sports)
+       (taxy-mapcar #'sport-name)
+       taxy-plain)
+
+     ((("Sporty"
+        ((disc
+          ((outdoor
+            ("Ultimate" "Disc golf"))))
+         (ball
+          ((racket
+            ((indoor
+              ("Racquetball"))
+             (outdoor
+              ("Tennis"))))
+           (indoor
+            ("Volleyball" "Basketball"))
+           (outdoor
+            ("Soccer" "Football"))
+           (glove
+            ((indoor
+              ("Handball"))
+             (outdoor
+              ("Baseball"))))))))))
+
+   That’s pretty sporty.  But classifying them by venue first makes the
+racket and glove sports not be listed together.  Let’s swap that around:
+
+     (defvar sporty
+       (cl-macrolet ((in (needle haystack)
+                         `(lambda (object)
+                            (when (member ,needle (funcall ,haystack object))
+                              ,needle))))
+         (make-taxy
+          :taxys (list (make-taxy
+                        :name "Sporty"
+                        :take (lambda (object taxy)
+                                (taxy-take-keyed*
+                                 (list (in 'ball 'sport-uses)
+                                       (in 'disc 'sport-uses)
+                                       (in 'glove 'sport-uses)
+                                       (in 'racket 'sport-uses)
+                                       #'sport-venue)
+                                 object taxy
+                                 :then #'identity)))))))
+
+     (thread-last sporty
+       taxy-emptied
+       (taxy-fill sports)
+       (taxy-mapcar #'sport-name)
+       taxy-plain)
+
+     ((("Sporty"
+        ((disc
+          ((outdoor
+            ("Ultimate" "Disc golf"))))
+         (ball
+          ((racket
+            ((indoor
+              ("Racquetball"))
+             (outdoor
+              ("Tennis"))))
+           (indoor
+            ("Volleyball" "Basketball"))
+           (outdoor
+            ("Soccer" "Football"))
+           (glove
+            ((indoor
+              ("Handball"))
+             (outdoor
+              ("Baseball"))))))))))
+
+   That’s better.  But I’d also like to see a very simple classification
+to help me decide what to play:
+
+     (thread-last
+         (make-taxy
+          :taxys (list
+                  (make-taxy
+                   :name "Funny"
+                   :take (lambda (object taxy)
+                           (taxy-take-keyed*
+                            (list (lambda (sport)
+                                    (if (sport-fun sport)
+                                        'fun 'boring))
+                                  #'sport-venue)
+                            object taxy)))))
+       taxy-emptied
+       (taxy-fill sports)
+       (taxy-mapcar #'sport-name)
+       taxy-plain)
+
+     ((("Funny"
+        ((boring
+          ((outdoor
+            ("Soccer"))))
+         (fun
+          ((indoor
+            ("Volleyball" "Handball" "Racquetball" "Basketball"))
+           (outdoor
+            ("Ultimate" "Disc golf" "Tennis" "Football" "Baseball"))))))))
 
-* Example applications::
+   Ah, now I understand.
 
 
-File: README.info,  Node: Example applications,  Up: Examples
+File: README.info,  Node: Applications,  Prev: Sporty (understanding 
completely),  Up: Examples
 
-1.1 Example applications
-========================
+1.4 Applications
+================
 
 Some example applications may be found in the examples directory
 (examples/README.org):
@@ -601,19 +811,22 @@ GPLv3
 
 Tag Table:
 Node: Top218
-Node: Examples1164
-Node: Example applications9099
-Node: Usage9481
-Node: Dynamic taxys11598
-Node: Multi-level dynamic taxys14016
-Node: Reusable taxys16179
-Node: Threading macros20348
-Node: Modifying filled taxys20887
-Node: Magit section21980
-Node: Changelog22581
-Node: 01-pre22719
-Node: Development22813
-Node: License22984
+Node: Examples1264
+Node: Numbery (starting basically)1576
+Node: Lettery (filling incrementally)7335
+Node: Sporty (understanding completely)9784
+Node: Applications16263
+Node: Usage16663
+Node: Dynamic taxys18780
+Node: Multi-level dynamic taxys21198
+Node: Reusable taxys23361
+Node: Threading macros27530
+Node: Modifying filled taxys28069
+Node: Magit section29162
+Node: Changelog29763
+Node: 01-pre29901
+Node: Development29995
+Node: License30166
 
 End Tag Table
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]