branch: externals/taxy commit 51dfeb41da4a905ee3831caeec5d4a4805c981c0 Author: Adam Porter <a...@alphapapa.net> Commit: Adam Porter <a...@alphapapa.net>
Change: objects -> items More concise, same meaning--what's not to love? In the documentation, the term "object" is still used in places to subtly distinguish between arbitrary objects (which might be added to a taxy's items) and ones that have been added to a taxy's items (thereby becoming one of that taxy's items). Yay, jargon. --- README.org | 66 ++++++++++----------- examples/diredy.el | 2 +- examples/musicy.el | 4 +- taxy-magit-section.el | 28 ++++----- taxy.el | 112 ++++++++++++++++++------------------ taxy.info | 156 ++++++++++++++++++++++++++++---------------------- 6 files changed, 194 insertions(+), 174 deletions(-) diff --git a/README.org b/README.org index 81be48f..8391272 100644 --- a/README.org +++ b/README.org @@ -54,7 +54,7 @@ Let's imagine a silly taxonomy of numbers below 100: (0 2 4 6 8) ;; These sub-taxys further classify the numbers below 10 into odd ;; and even. The odd taxy "consumes" numbers, while the even one - ;; doesn't, leaving them to reappear in the parent taxy's objects. + ;; doesn't, leaving them to reappear in the parent taxy's items. (("Odd" "(consuming)" (1 3 5 7 9)) ("Even" "(non-consuming)" @@ -95,7 +95,7 @@ You might think about how to produce that by writing some imperative code, but = :taxys (list ;; These sub-taxys further classify the numbers below 10 into odd ;; and even. The odd taxy "consumes" numbers, while the even one - ;; doesn't, leaving them to reappear in the parent taxy's objects. + ;; doesn't, leaving them to reappear in the parent taxy's items. (make-taxy :name "Odd" :description "(consuming)" :predicate #'oddp) @@ -145,7 +145,7 @@ The ~taxy-fill~ function applies the numbers in a "cascade" down the hierarchy o ** Lettery (filling incrementally) -You can also add more objects after the hierarchy has been filled. In this example we'll make a comprehensive taxonomy of letters. The first sub-taxy collects vowels, and the second, by leaving its predicate at the default value, ~identity~, collects all letters not collected by the first taxy, i.e. non-vowels. +You can also add more items after the hierarchy has been filled. In this example we'll make a comprehensive taxonomy of letters. The first sub-taxy collects vowels, and the second, by leaving its predicate at the default value, ~identity~, collects all letters not collected by the first taxy, i.e. non-vowels. #+BEGIN_SRC elisp (defvar lettery @@ -203,8 +203,8 @@ Oh, they're out of order, now. That won't do. Let's fix that: #+BEGIN_SRC elisp :exports code :results code (taxy-plain (taxy-mapc* (lambda (taxy) - (setf (taxy-objects taxy) - (cl-sort (taxy-objects taxy) #'< + (setf (taxy-items taxy) + (cl-sort (taxy-items taxy) #'< :key #'string-to-char))) lettery)) #+END_SRC @@ -279,22 +279,22 @@ And finally we'll define a taxy to organize them. In this, we use a helper macr #+BEGIN_SRC elisp :exports code :results silent :lexical t (defvar sporty (cl-macrolet ((in (needle haystack) - `(lambda (object) - (when (member ,needle (funcall ,haystack object)) + `(lambda (item) + (when (member ,needle (funcall ,haystack item)) ,needle)))) (make-taxy :name "Sporty" - :take (lambda (object taxy) + :take (lambda (item 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 + item taxy ;; We set the `:then' function of the taxys ;; created by `taxy-take-keyed' to `identity' - ;; so they will not consume their objects. + ;; so they will not consume their items. :then #'identity))))) #+END_SRC @@ -333,19 +333,19 @@ That's pretty sporty. But classifying them by venue first makes the racket and #+BEGIN_SRC elisp :exports code :results silent (defvar sporty (cl-macrolet ((in (needle haystack) - `(lambda (object) - (when (member ,needle (funcall ,haystack object)) + `(lambda (item) + (when (member ,needle (funcall ,haystack item)) ,needle)))) (make-taxy :name "Sporty" - :take (lambda (object taxy) + :take (lambda (item 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 + item taxy :then #'identity))))) (thread-last sporty @@ -383,13 +383,13 @@ That's better. But I'd also like to see a very simple classification to help me (thread-last (make-taxy :name "Funny" - :take (lambda (object taxy) + :take (lambda (item taxy) (taxy-take-keyed (list (lambda (sport) (if (sport-fun sport) 'fun 'boring)) #'sport-venue) - object taxy))) + item taxy))) taxy-emptied (taxy-fill sports) (taxy-mapcar #'sport-name) @@ -445,13 +445,13 @@ A taxy is defined with the ~make-taxy~ constructor, like: :taxys (list ...)) #+END_SRC -The ~:predicate~ function determines whether an object fits into that taxy. If it does, ~taxy-fill~ adds the object to that taxy's descendant ~:taxys~, if present, or to its own ~:objects~. The function defaults to ~identity~, so a taxy "takes in" any object by default (i.e. if you only apply objects you want to classify, there's no need to test them at the top-level taxy). +The ~:predicate~ function determines whether an object fits into that taxy. If it does, ~taxy-fill~ adds the object to that taxy's descendant ~:taxys~, if present, or to its own ~:items~. The function defaults to ~identity~, so a taxy "takes in" any object by default (i.e. if you only apply objects you want to classify, there's no need to test them at the top-level taxy). -The ~:then~ function determines what happens to an object after being taken in: if the function, called with the object, returns a non-nil value, that value is applied to other taxys at the same level until one of their ~:then~ functions returns nil or no more taxys remain. The function defaults to ~ignore~, which makes a taxy "consume" its objects by default. Setting the function to, e.g. ~identity~, makes it not consume them, leaving them eligible to also be taken into subsequent tax [...] +The ~:then~ function determines what happens to an object after being taken in to the taxy's ~:items~: if the function, called with the object, returns a non-nil value, that value is applied to other taxys at the same level until one of their ~:then~ functions returns nil or no more taxys remain. The function defaults to ~ignore~, which makes a taxy "consume" its items by default. Setting the function to, e.g. ~identity~, makes it not consume them, leaving them eligible to also be take [...] -After defining a taxy, call ~taxy-fill~ with it and a list of objects to fill the taxy's hierarchy. *Note:* ~taxy-fill~ modifies the taxy given to it (filling its ~:objects~ and those of its ~:taxys~), so when using a statically defined taxy (e.g. one defined with ~defvar~), you should pass ~taxy-fill~ a taxy copied with ~taxy-emptied~, which recursively copies a taxy without ~:objects~. +After defining a taxy, call ~taxy-fill~ with it and a list of objects to fill the taxy's hierarchy. *Note:* ~taxy-fill~ modifies the taxy given to it (filling its ~:items~ and those of its ~:taxys~), so when using a statically defined taxy (e.g. one defined with ~defvar~), you should pass ~taxy-fill~ a taxy copied with ~taxy-emptied~, which recursively copies a taxy without ~:items~. -To return a taxy in a more human-readable format (with only relevant fields included), use ~taxy-plain~. You may also use ~taxy-mapcar~ to replace objects in a taxy with, e.g. a more useful representation. +To return a taxy in a more human-readable format (with only relevant fields included), use ~taxy-plain~. You may also use ~taxy-mapcar~ to replace items in a taxy with, e.g. a more useful representation. ** Dynamic taxys :PROPERTIES: @@ -462,7 +462,7 @@ To return a taxy in a more human-readable format (with only relevant fields incl - [[#chains-of-independent-multi-level-dynamic-taxys]["Chains" of independent, multi-level dynamic taxys]] :END: -You may not always know in advance what taxonomy a set of objects fits into, so =taxy= lets you add taxys dynamically by using the ~:take~ function to add a taxy when an object is "taken into" a parent taxy. For example, you could dynamically classify buffers by their major mode like so: +You may not always know in advance what taxonomy a set of objects fits into, so =taxy= lets you add taxys dynamically by using the ~:take~ function to add a taxy when an object is "taken into" a parent taxy's items. For example, you could dynamically classify buffers by their major mode like so: #+BEGIN_SRC elisp :exports code (defun buffery-major-mode (buffer) @@ -530,8 +530,8 @@ Expanding on the previous example, we use ~cl-labels~ to define functions which :taxys (list (make-taxy :name "Directories" - :take (lambda (object taxy) - (taxy-take-keyed (list #'buffer-directory #'buffer-mode) object taxy))))))) + :take (lambda (item taxy) + (taxy-take-keyed (list #'buffer-directory #'buffer-mode) item taxy))))))) (taxy-plain (taxy-fill (buffer-list) @@ -575,8 +575,8 @@ Building on the ~sporty~ example, let's define a taxy in which outdoor sports ar #+BEGIN_SRC elisp :exports code :results silent :lexical t (defvar sporty-dynamic (cl-macrolet ((in (needle haystack) - `(lambda (object) - (when (member ,needle (funcall ,haystack object)) + `(lambda (item) + (when (member ,needle (funcall ,haystack item)) ,needle)))) (cl-labels ((outdoor-p (sport) (when (eq 'outdoor (sport-venue sport)) @@ -590,7 +590,7 @@ Building on the ~sporty~ example, let's define a taxy in which outdoor sports ar 'non-disc))) (make-taxy :name "Sporty (dynamic)" - :take (lambda (object taxy) + :take (lambda (item taxy) (taxy-take-keyed (list (list #'outdoor-p #'disc-p) (list #'indoor-p @@ -598,7 +598,7 @@ Building on the ~sporty~ example, let's define a taxy in which outdoor sports ar (in 'disc 'sport-uses) (in 'glove 'sport-uses) (in 'racket 'sport-uses))) - object taxy)))))) + item taxy)))))) #+END_SRC Now let's fill the taxy with the sports and format it: @@ -731,7 +731,7 @@ If you happen to like macros, ~taxy~ works well with threading (i.e. ~thread-las ** Modifying filled taxys -Sometimes it's necessary to modify a taxy after filling it with objects, e.g. to sort the objects and/or the sub-taxys. For this, use the function ~taxy-mapc-taxys~ (a.k.a. ~taxy-mapc*~). For example, in the sample application [[file:examples/musicy.el][musicy.el]], the taxys and their objects are sorted after filling, like so: +Sometimes it's necessary to modify a taxy after filling it with objects, e.g. to sort the items and/or the sub-taxys. For this, use the function ~taxy-mapc-taxys~ (a.k.a. ~taxy-mapc*~). For example, in the sample application [[file:examples/musicy.el][musicy.el]], the taxys and their items are sorted after filling, like so: #+BEGIN_SRC elisp (defun musicy-files (files) @@ -743,9 +743,9 @@ Sometimes it's necessary to modify a taxy after filling it with objects, e.g. to (setf (taxy-taxys taxy) (cl-sort (taxy-taxys taxy) #'string< :key #'taxy-name)) - ;; Sort sub-taxys' objects by name. - (setf (taxy-objects taxy) - (cl-sort (taxy-objects taxy) #'string<)))) + ;; Sort sub-taxys' items by name. + (setf (taxy-items taxy) + (cl-sort (taxy-items taxy) #'string<)))) taxy-magit-section-pp)) #+END_SRC @@ -776,7 +776,9 @@ Note that while =taxy-magit-section.el= is installed with the =taxy= package, th ** 0.3-pre -Nothing new yet. +*** Changes + ++ Within the ~taxy~ struct and related functions, the term =objects= is renamed to =items=, which is more concise but has the same meaning. This makes code a bit more concise (e.g. ~(taxy-objects taxy)~ becomes ~(taxy-items taxy)~). ** 0.2 diff --git a/examples/diredy.el b/examples/diredy.el index 4448105..e5efe23 100644 --- a/examples/diredy.el +++ b/examples/diredy.el @@ -96,7 +96,7 @@ (inhibit-read-only t) (taxy-magit-section-indent 2)) (delete-region (point) (point-max)) - (taxy-magit-section-insert filled-taxy :objects 'first)))) + (taxy-magit-section-insert filled-taxy :items 'first)))) ;;;; Functions diff --git a/examples/musicy.el b/examples/musicy.el index b62c890..cd5bde0 100644 --- a/examples/musicy.el +++ b/examples/musicy.el @@ -107,8 +107,8 @@ (setf (taxy-taxys taxy) (cl-sort (taxy-taxys taxy) #'string< :key #'taxy-name)) - (setf (taxy-objects taxy) - (cl-sort (taxy-objects taxy) #'string<)))) + (setf (taxy-items taxy) + (cl-sort (taxy-items taxy) #'string<)))) ;; taxy-plain taxy-magit-section-pp)) diff --git a/taxy-magit-section.el b/taxy-magit-section.el index ff4f724..6203ced 100644 --- a/taxy-magit-section.el +++ b/taxy-magit-section.el @@ -53,18 +53,18 @@ ;;;; Functions -(cl-defun taxy-magit-section-insert (taxy &key (objects 'first)) +(cl-defun taxy-magit-section-insert (taxy &key (items 'first)) "Insert a `magit-section' for TAXY into current buffer. -If OBJECTS is `first', insert a taxy's objects before its +If ITEMS is `first', insert a taxy's items before its descendant taxys; if `last', insert them after descendants." (let* ((depth 0) (magit-section-set-visibility-hook (cons #'taxy-magit-section-visibility magit-section-set-visibility-hook))) - (cl-labels ((insert-object - (object format-fn indent) - (magit-insert-section (magit-section object) + (cl-labels ((insert-item + (item format-fn indent) + (magit-insert-section (magit-section item) (magit-insert-section-body (insert (make-string (+ 2 (* depth indent)) ? ) - (funcall format-fn object) + (funcall format-fn item) "\n")))) (insert-taxy (taxy) (let ((magit-section-set-visibility-hook magit-section-set-visibility-hook) @@ -86,25 +86,25 @@ descendant taxys; if `last', insert them after descendants." "") (taxy-size taxy))) (magit-insert-section-body - (when (eq 'first objects) - (dolist (object (taxy-objects taxy)) - (insert-object object format-fn (taxy-magit-section-indent taxy)))) + (when (eq 'first items) + (dolist (item (taxy-items taxy)) + (insert-item item format-fn (taxy-magit-section-indent taxy)))) (cl-incf depth) (mapc #'insert-taxy (taxy-taxys taxy)) (cl-decf depth) - (when (eq 'last objects) - (dolist (object (taxy-objects taxy)) - (insert-object object format-fn (taxy-magit-section-indent taxy))))))))) + (when (eq 'last items) + (dolist (item (taxy-items taxy)) + (insert-item item format-fn (taxy-magit-section-indent taxy))))))))) (magit-insert-section (magit-section) (insert-taxy taxy))))) -(cl-defun taxy-magit-section-pp (taxy &key (objects 'first)) +(cl-defun taxy-magit-section-pp (taxy &key (items 'first)) "Pretty-print TAXY into a buffer with `magit-section' and show it." (with-current-buffer (get-buffer-create "*taxy-magit-section-pp*") (magit-section-mode) (let ((inhibit-read-only t)) (erase-buffer) - (taxy-magit-section-insert taxy :objects objects)) + (taxy-magit-section-insert taxy :items items)) (pop-to-buffer (current-buffer)))) (defun taxy-magit-section-visibility (section) diff --git a/taxy.el b/taxy.el index 4380ad7..fc3319b 100644 --- a/taxy.el +++ b/taxy.el @@ -39,8 +39,8 @@ ;; Basic usage: ;; 1. Make a taxy with `make-taxy'. -;; 2. Fill the taxy with objects using `taxy-fill'. -;; 3. For a simple display of a taxy's objects, use `taxy-plain'. +;; 2. Fill the taxy with items using `taxy-fill'. +;; 3. For a simple display of a taxy's items, use `taxy-plain'. ;; For more details, please see the README.org file. @@ -54,7 +54,7 @@ ;;;; Structs (cl-defstruct taxy - name description key objects taxys + name description key items taxys (predicate #'identity) (then #'ignore) (make #'make-taxy) take) @@ -70,60 +70,60 @@ ;;;; Functions -(defun taxy-fill (objects taxy) - "Fill TAXY with OBJECTS according to its definition." - (cl-labels ((apply-object (object taxy) +(defun taxy-fill (items taxy) + "Fill TAXY with ITEMS according to its definition." + (cl-labels ((apply-item (item taxy) (or (cl-loop for taxy in (taxy-taxys taxy) - when (funcall (taxy-predicate taxy) object) + when (funcall (taxy-predicate taxy) item) do (progn (if (taxy-take taxy) - (funcall (taxy-take taxy) object taxy) + (funcall (taxy-take taxy) item taxy) (if (taxy-taxys taxy) - (or (apply-object object taxy) - (push object (taxy-objects taxy))) - (push object (taxy-objects taxy)))) - (setf object (funcall (taxy-then taxy) object))) - unless object return t + (or (apply-item item taxy) + (push item (taxy-items taxy))) + (push item (taxy-items taxy)))) + (setf item (funcall (taxy-then taxy) item))) + unless item return t finally return nil) - ;; No sub-taxys took the object: add it to this taxy. - (when (funcall (taxy-predicate taxy) object) + ;; No sub-taxys took the item: add it to this taxy. + (when (funcall (taxy-predicate taxy) item) (if (taxy-take taxy) - (funcall (taxy-take taxy) object taxy) - (push object (taxy-objects taxy))))))) - (dolist (object objects taxy) - (apply-object object taxy)))) + (funcall (taxy-take taxy) item taxy) + (push item (taxy-items taxy))))))) + (dolist (item items taxy) + (apply-item item taxy)))) (defun taxy-plain (taxy) "Return a list of the human-readable parts of TAXY." (delq nil (list (taxy-name taxy) (taxy-description taxy) - (taxy-objects taxy) + (taxy-items taxy) (mapcar #'taxy-plain (taxy-taxys taxy))))) (defun taxy-emptied (taxy) - "Return a copy of TAXY without objects. -Omits TAXY's objects and those of its descendant taxys. Useful + "Return a copy of TAXY without items. +Omits TAXY's items and those of its descendant taxys. Useful when reusing taxy definitions." (setf taxy (copy-taxy taxy) - (taxy-objects taxy) nil + (taxy-items taxy) nil (taxy-taxys taxy) (mapcar #'taxy-emptied (taxy-taxys taxy))) taxy) -(defun taxy-mapcar-objects (fn taxy) - "Return copy of TAXY, having replaced its objects with the value of FN on each. -Replaces every object in TAXY and its descendants. Useful to -replace objects with a more useful form after classification." +(defun taxy-mapcar-items (fn taxy) + "Return copy of TAXY, having replaced its items with the value of FN on each. +Replaces every item in TAXY and its descendants. Useful to +replace items with a more useful form after classification." (declare (indent defun)) - ;; It might be preferable to destructively replace objects rather + ;; It might be preferable to destructively replace items rather ;; than consing new lists, but I haven't found a way that works ;; (even `cl-loop' with `in-ref' hasn't worked). - (setf (taxy-objects taxy) (mapcar fn (taxy-objects taxy)) + (setf (taxy-items taxy) (mapcar fn (taxy-items taxy)) (taxy-taxys taxy) (cl-loop for taxy in (taxy-taxys taxy) - collect (taxy-mapcar-objects fn taxy))) + collect (taxy-mapcar-items fn taxy))) taxy) -(defalias 'taxy-mapcar #'taxy-mapcar-objects) +(defalias 'taxy-mapcar #'taxy-mapcar-items) (defun taxy-mapc-taxys (fn taxy) "Return TAXY having applied FN to it and its descendants. @@ -137,17 +137,17 @@ Does not copy TAXY. Destructively modifies TAXY, if FN does." (defalias 'taxy-mapc* #'taxy-mapc-taxys) (cl-defun taxy-take-keyed - (key-fns object taxy + (key-fns item 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 + "Take ITEM into TAXY, adding new taxys dynamically and recursively. +Places ITEM into a taxy in TAXY for the value returned by +KEY-FNS called with ITEM. The new taxys are added to TAXY recursively as necessary. Each new taxy's name is that returned -by KEY-NAME-FN called with OBJECT. +by KEY-NAME-FN called with ITEM. Each element of KEY-FNS may be a function or a list of functions. A list of functions creates a \"chain\" of functions: when an -object is matched by the first function in a chain, it is placed +item is matched by the first function in a chain, it is placed in that chain's taxonomy, and is not \"offered\" to functions outside of that chain. @@ -175,15 +175,15 @@ numbers greater-than-or-equal-to 10 are tested against (declare (indent defun)) (cl-macrolet ((offer-or-push () `(if (cdr key-fns) - (taxy-take-keyed (cdr key-fns) object taxy + (taxy-take-keyed (cdr key-fns) item taxy :key-name-fn key-name-fn :then then) - (push object (taxy-objects taxy))))) + (push item (taxy-items taxy))))) (cl-typecase (car key-fns) (function ;; A single key function. (let ((key-fn (car key-fns))) - (if-let ((key (funcall key-fn object))) - ;; This key function returned non-nil for the object: + (if-let ((key (funcall key-fn item))) + ;; This key function returned non-nil for the item: ;; apply it to the appropriate sub-taxy. (let ((key-taxy (or (cl-find-if (lambda (taxy-key) @@ -201,40 +201,40 @@ numbers greater-than-or-equal-to 10 are tested against (taxy-make taxy) :name (funcall key-name-fn key) :key key - :predicate (lambda (object) - (equal key (funcall key-fn object))) + :predicate (lambda (item) + (equal key (funcall key-fn item))) :take (when (cdr key-fns) - (lambda (object taxy) - (taxy-take-keyed (cdr key-fns) object taxy + (lambda (item taxy) + (taxy-take-keyed (cdr key-fns) item taxy :key-name-fn key-name-fn :then then))) :then then) (taxy-taxys taxy)))))) (if (cdr key-fns) - ;; Other key-fns remain: offer object to them, allowing + ;; Other key-fns remain: offer item to them, allowing ;; them to create more sub-taxys beneath this key-taxy. - (taxy-take-keyed (cdr key-fns) object key-taxy + (taxy-take-keyed (cdr key-fns) item key-taxy :key-name-fn key-name-fn :then then) - ;; No more key-fns remain: add object to this taxy. - (push object (taxy-objects key-taxy)))) + ;; No more key-fns remain: add item to this taxy. + (push item (taxy-items key-taxy)))) ;; No key value: offer to other KEY-FNS or push to this taxy. (offer-or-push)))) (list ;; A "chain" of key functions. - (or (when (funcall (caar key-fns) object) + (or (when (funcall (caar key-fns) item) ;; The first function in this chain returns non-nil for - ;; the object: apply the object to the chain. - (taxy-take-keyed (car key-fns) object taxy + ;; the item: apply the item to the chain. + (taxy-take-keyed (car key-fns) item taxy :key-name-fn key-name-fn :then then)) - ;; This "chain" of key-fns didn't take the object: offer it to + ;; This "chain" of key-fns didn't take the item: offer it to ;; other chains, or push to this taxy if they don't take it. (offer-or-push)))))) (defun taxy-size (taxy) - "Return the number of objects TAXY holds. -Includes objects in TAXY's sub-taxys." + "Return the number of items TAXY holds. +Includes items in TAXY's sub-taxys." (cl-loop for sub-taxy in (taxy-taxys taxy) sum (taxy-size sub-taxy) into total - finally return (+ total (length (taxy-objects taxy))))) + finally return (+ total (length (taxy-items taxy))))) ;;;; Footer diff --git a/taxy.info b/taxy.info index 0d967e8..b8251a1 100644 --- a/taxy.info +++ b/taxy.info @@ -52,10 +52,14 @@ Changelog * 0.2: 02. * 0.1: 01. +0.3-pre + +* Changes:: + 0.2 -* Changes:: +* Changes: Changesx. * Additions:: * Fixes:: @@ -108,7 +112,7 @@ Let’s imagine a silly taxonomy of numbers below 100: (0 2 4 6 8) ;; These sub-taxys further classify the numbers below 10 into odd ;; and even. The odd taxy "consumes" numbers, while the even one - ;; doesn't, leaving them to reappear in the parent taxy's objects. + ;; doesn't, leaving them to reappear in the parent taxy's items. (("Odd" "(consuming)" (1 3 5 7 9)) ("Even" "(non-consuming)" @@ -149,7 +153,7 @@ manner: :taxys (list ;; These sub-taxys further classify the numbers below 10 into odd ;; and even. The odd taxy "consumes" numbers, while the even one - ;; doesn't, leaving them to reappear in the parent taxy's objects. + ;; doesn't, leaving them to reappear in the parent taxy's items. (make-taxy :name "Odd" :description "(consuming)" :predicate #'oddp) @@ -204,7 +208,7 @@ File: README.info, Node: Lettery (filling incrementally), Next: Sporty (unders 1.2 Lettery (filling incrementally) =================================== -You can also add more objects after the hierarchy has been filled. In +You can also add more items after the hierarchy has been filled. In this example we’ll make a comprehensive taxonomy of letters. The first sub-taxy collects vowels, and the second, by leaving its predicate at the default value, ‘identity’, collects all letters not collected by the @@ -257,8 +261,8 @@ first taxy, i.e. non-vowels. (taxy-plain (taxy-mapc* (lambda (taxy) - (setf (taxy-objects taxy) - (cl-sort (taxy-objects taxy) #'< + (setf (taxy-items taxy) + (cl-sort (taxy-items taxy) #'< :key #'string-to-char))) lettery)) @@ -332,22 +336,22 @@ key functions: (defvar sporty (cl-macrolet ((in (needle haystack) - `(lambda (object) - (when (member ,needle (funcall ,haystack object)) + `(lambda (item) + (when (member ,needle (funcall ,haystack item)) ,needle)))) (make-taxy :name "Sporty" - :take (lambda (object taxy) + :take (lambda (item 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 + item taxy ;; We set the `:then' function of the taxys ;; created by `taxy-take-keyed' to `identity' - ;; so they will not consume their objects. + ;; so they will not consume their items. :then #'identity))))) Now let’s fill the taxy with the sports and format it: @@ -383,19 +387,19 @@ hierarchy: (defvar sporty (cl-macrolet ((in (needle haystack) - `(lambda (object) - (when (member ,needle (funcall ,haystack object)) + `(lambda (item) + (when (member ,needle (funcall ,haystack item)) ,needle)))) (make-taxy :name "Sporty" - :take (lambda (object taxy) + :take (lambda (item 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 + item taxy :then #'identity))))) (thread-last sporty @@ -430,13 +434,13 @@ to help me decide what to play: (thread-last (make-taxy :name "Funny" - :take (lambda (object taxy) + :take (lambda (item taxy) (taxy-take-keyed (list (lambda (sport) (if (sport-fun sport) 'fun 'boring)) #'sport-venue) - object taxy))) + item taxy))) taxy-emptied (taxy-fill sports) (taxy-mapcar #'sport-name) @@ -494,30 +498,30 @@ File: README.info, Node: Usage, Next: Changelog, Prev: Installation, Up: Top The ‘:predicate’ function determines whether an object fits into that taxy. If it does, ‘taxy-fill’ adds the object to that taxy’s descendant -‘:taxys’, if present, or to its own ‘:objects’. The function defaults -to ‘identity’, so a taxy "takes in" any object by default (i.e. if you +‘:taxys’, if present, or to its own ‘:items’. The function defaults to +‘identity’, so a taxy "takes in" any object by default (i.e. if you only apply objects you want to classify, there’s no need to test them at the top-level taxy). The ‘:then’ function determines what happens to an object after being -taken in: if the function, called with the object, returns a non-nil -value, that value is applied to other taxys at the same level until one -of their ‘:then’ functions returns nil or no more taxys remain. The -function defaults to ‘ignore’, which makes a taxy "consume" its objects -by default. Setting the function to, e.g. ‘identity’, makes it not -consume them, leaving them eligible to also be taken into subsequent -taxys, or to appear in the parent taxy’s objects. +taken in to the taxy’s ‘:items’: if the function, called with the +object, returns a non-nil value, that value is applied to other taxys at +the same level until one of their ‘:then’ functions returns nil or no +more taxys remain. The function defaults to ‘ignore’, which makes a +taxy "consume" its items by default. Setting the function to, e.g. +‘identity’, makes it not consume them, leaving them eligible to also be +taken into subsequent taxys, or to appear in the parent taxy’s items. After defining a taxy, call ‘taxy-fill’ with it and a list of objects to fill the taxy’s hierarchy. *Note:* ‘taxy-fill’ modifies the taxy -given to it (filling its ‘:objects’ and those of its ‘:taxys’), so when +given to it (filling its ‘:items’ and those of its ‘:taxys’), so when using a statically defined taxy (e.g. one defined with ‘defvar’), you should pass ‘taxy-fill’ a taxy copied with ‘taxy-emptied’, which -recursively copies a taxy without ‘:objects’. +recursively copies a taxy without ‘:items’. To return a taxy in a more human-readable format (with only relevant fields included), use ‘taxy-plain’. You may also use ‘taxy-mapcar’ to -replace objects in a taxy with, e.g. a more useful representation. +replace items in a taxy with, e.g. a more useful representation. * Menu: @@ -536,9 +540,9 @@ File: README.info, Node: Dynamic taxys, Next: Reusable taxys, Up: Usage • • You may not always know in advance what taxonomy a set of objects fits into, so taxy lets you add taxys dynamically by using the ‘:take’ -function to add a taxy when an object is "taken into" a parent taxy. -For example, you could dynamically classify buffers by their major mode -like so: +function to add a taxy when an object is "taken into" a parent taxy’s +items. For example, you could dynamically classify buffers by their +major mode like so: (defun buffery-major-mode (buffer) (buffer-local-value 'major-mode buffer)) @@ -620,8 +624,8 @@ directory. :taxys (list (make-taxy :name "Directories" - :take (lambda (object taxy) - (taxy-take-keyed (list #'buffer-directory #'buffer-mode) object taxy))))))) + :take (lambda (item taxy) + (taxy-take-keyed (list #'buffer-directory #'buffer-mode) item taxy))))))) (taxy-plain (taxy-fill (buffer-list) @@ -673,8 +677,8 @@ use: (defvar sporty-dynamic (cl-macrolet ((in (needle haystack) - `(lambda (object) - (when (member ,needle (funcall ,haystack object)) + `(lambda (item) + (when (member ,needle (funcall ,haystack item)) ,needle)))) (cl-labels ((outdoor-p (sport) (when (eq 'outdoor (sport-venue sport)) @@ -688,7 +692,7 @@ use: 'non-disc))) (make-taxy :name "Sporty (dynamic)" - :take (lambda (object taxy) + :take (lambda (item taxy) (taxy-take-keyed (list (list #'outdoor-p #'disc-p) (list #'indoor-p @@ -696,7 +700,7 @@ use: (in 'disc 'sport-uses) (in 'glove 'sport-uses) (in 'racket 'sport-uses))) - object taxy)))))) + item taxy)))))) Now let’s fill the taxy with the sports and format it: @@ -840,10 +844,10 @@ File: README.info, Node: Modifying filled taxys, Next: Magit section, Prev: T ========================== Sometimes it’s necessary to modify a taxy after filling it with objects, -e.g. to sort the objects and/or the sub-taxys. For this, use the +e.g. to sort the items and/or the sub-taxys. For this, use the function ‘taxy-mapc-taxys’ (a.k.a. ‘taxy-mapc*’). For example, in the sample application musicy.el (examples/musicy.el), the taxys and their -objects are sorted after filling, like so: +items are sorted after filling, like so: (defun musicy-files (files) (thread-last musicy-taxy @@ -854,9 +858,9 @@ objects are sorted after filling, like so: (setf (taxy-taxys taxy) (cl-sort (taxy-taxys taxy) #'string< :key #'taxy-name)) - ;; Sort sub-taxys' objects by name. - (setf (taxy-objects taxy) - (cl-sort (taxy-objects taxy) #'string<)))) + ;; Sort sub-taxys' items by name. + (setf (taxy-items taxy) + (cl-sort (taxy-items taxy) #'string<)))) taxy-magit-section-pp)) @@ -899,7 +903,20 @@ File: README.info, Node: 03-pre, Next: 02, Up: Changelog 4.1 0.3-pre =========== -Nothing new yet. +* Menu: + +* Changes:: + + +File: README.info, Node: Changes, Up: 03-pre + +4.1.1 Changes +------------- + + • Within the ‘taxy’ struct and related functions, the term objects is + renamed to items, which is more concise but has the same meaning. + This makes code a bit more concise (e.g. ‘(taxy-objects taxy)’ + becomes ‘(taxy-items taxy)’). File: README.info, Node: 02, Next: 01, Prev: 03-pre, Up: Changelog @@ -909,12 +926,12 @@ File: README.info, Node: 02, Next: 01, Prev: 03-pre, Up: Changelog * Menu: -* Changes:: +* Changes: Changesx. * Additions:: * Fixes:: -File: README.info, Node: Changes, Next: Additions, Up: 02 +File: README.info, Node: Changesx, Next: Additions, Up: 02 4.2.1 Changes ------------- @@ -924,7 +941,7 @@ File: README.info, Node: Changes, Next: Additions, Up: 02 reason to maintain two versions. -File: README.info, Node: Additions, Next: Fixes, Prev: Changes, Up: 02 +File: README.info, Node: Additions, Next: Fixes, Prev: Changesx, Up: 02 4.2.2 Additions --------------- @@ -1006,31 +1023,32 @@ GPLv3 Tag Table: Node: Top218 -Node: Examples1506 -Node: Numbery (starting basically)1825 -Node: Lettery (filling incrementally)7584 -Node: Sporty (understanding completely)10270 +Node: Examples1538 +Node: Numbery (starting basically)1857 +Node: Lettery (filling incrementally)7612 +Node: Sporty (understanding completely)10292 Node: Applications16279 Node: Installation16679 Node: Usage16980 -Node: Dynamic taxys19101 -Node: Multi-level dynamic taxys21645 -Node: "Chains" of independent multi-level dynamic taxys23842 -Node: Reusable taxys26722 -Node: Threading macros30891 -Node: Modifying filled taxys31430 -Node: Magit section32523 -Node: Changelog33181 -Node: 03-pre33343 -Node: 0233449 -Node: Changes33586 -Node: Additions33870 -Node: Fixes34781 -Node: 0135027 -Node: Development35126 -Node: Copyright assignment35332 -Node: Credits35919 -Node: License36109 +Node: Dynamic taxys19117 +Node: Multi-level dynamic taxys21672 +Node: "Chains" of independent multi-level dynamic taxys23865 +Node: Reusable taxys26737 +Node: Threading macros30906 +Node: Modifying filled taxys31445 +Node: Magit section32528 +Node: Changelog33186 +Node: 03-pre33348 +Node: Changes33458 +Node: 0233800 +Node: Changesx33947 +Node: Additions34232 +Node: Fixes35144 +Node: 0135390 +Node: Development35489 +Node: Copyright assignment35695 +Node: Credits36282 +Node: License36472 End Tag Table