[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/taxy a7ff557 33/42: Docs: Document new things
From: |
ELPA Syncer |
Subject: |
[elpa] externals/taxy a7ff557 33/42: Docs: Document new things |
Date: |
Wed, 15 Sep 2021 12:57:32 -0400 (EDT) |
branch: externals/taxy
commit a7ff5573aead56286177038d2b37aba4489afc59
Author: Adam Porter <adam@alphapapa.net>
Commit: Adam Porter <adam@alphapapa.net>
Docs: Document new things
---
README.org | 113 ++++++++++++++++++++++++++++++++++++
taxy.el | 2 -
taxy.info | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++-----------
3 files changed, 270 insertions(+), 37 deletions(-)
diff --git a/README.org b/README.org
index 8eebebe..529f475 100644
--- a/README.org
+++ b/README.org
@@ -456,6 +456,7 @@ To return a taxy in a more human-readable format (with only
relevant fields incl
:CONTENTS:
- [[#multi-level-dynamic-taxys][Multi-level dynamic taxys]]
- [[#chains-of-independent-multi-level-dynamic-taxys]["Chains" of independent,
multi-level dynamic taxys]]
+- [[#defining-a-classification-domain-specific-language][Defining a
classification domain-specific language]]
: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's items. For example, you
could dynamically classify buffers by their major mode like so:
@@ -623,6 +624,118 @@ Now let's fill the taxy with the sports and format it:
("Soccer" "Tennis" "Football" "Baseball"))))))
#+END_SRC
+*** Defining a classification domain-specific language
+
+When writing a larger Taxy-based application, it may be necessary to define a
number of key functions that would be unwieldy to manage in a ~cl-labels~ form.
For this case, Taxy provides the macro ~taxy-define-key-definer~ to easily
define Taxy key functions in an application library. Those functions are then
passed to the function ~taxy-make-take-function~ at runtime, along with a list
of keys being used to classify items. Using these allows key functions to be
defined in top-level f [...]
+
+Extending the previous ~sporty~ example, let's redefine its key functions
using ~taxy-define-key-definer~:
+
+#+begin_src elisp :exports code :results silent :lexical t
+ (taxy-define-key-definer sporty-define-key
+ sporty-keys "sporty"
+ "Define a `sporty' key function.")
+
+ (sporty-define-key disc-based ()
+ (if (member 'disc (sport-uses item))
+ "Disc-based"
+ "Non-disc-based"))
+
+ (sporty-define-key uses (&optional thing)
+ (pcase thing
+ (`nil (sport-uses item))
+ (_ (when (cl-typecase (sport-uses item)
+ (symbol (equal thing (sport-uses item)))
+ (list (member thing (sport-uses item))))
+ thing))))
+
+ (sporty-define-key venue (&optional place)
+ (pcase place
+ (`nil (sport-venue item))
+ (_ (when (equal place (sport-venue item))
+ (sport-venue item)))))
+#+end_src
+
+Now we'll define the default keys to use when classifying items. This list is
equivalent to the one passed to ~taxy-take-keyed~ in the previous, "Chains"
example.
+
+#+begin_src elisp :exports code :results silent :lexical t
+ (defvar sporty-default-keys
+ '(
+ ((venue 'outdoor)
+ disc-based)
+
+ ((venue 'indoor)
+ (uses 'ball)
+ (uses 'disc)
+ (uses 'glove)
+ (uses 'racket))))
+#+end_src
+
+Finally, rather than using a pre-made taxy struct, we make one at runtime,
making the ~:take~ function with ~taxy-make-take-function~.
+
+#+begin_src elisp :exports both :results code :lexical t
+ (let ((taxy (make-taxy
+ :name "Sporty (DSL)"
+ :take (taxy-make-take-function sporty-default-keys
+ sporty-keys))))
+ (thread-last taxy
+ (taxy-fill sports)
+ (taxy-mapcar #'sport-name)
+ taxy-plain))
+#+end_src
+
+Which gives us:
+
+#+RESULTS:
+#+begin_src elisp
+ ("Sporty (DSL)"
+ ((indoor
+ ((ball
+ ("Volleyball" "Basketball")
+ ((glove
+ ("Handball"))
+ (racket
+ ("Racquetball"))))))
+ (outdoor
+ (("Disc-based"
+ ("Ultimate" "Disc golf"))
+ ("Non-disc-based"
+ ("Soccer" "Tennis" "Football" "Baseball"))))))
+#+end_src
+
+As you can see, the result is the same as that in the previous example, but
we've defined a kind of DSL for grouping sports in a modular, extendable way.
+
+This also allows the grouping keys to be easily changed at runtime, producing
a different result. For example, we could group sports by, first, whether they
use a ball, and then by venue. Let's do this in a function so that users can
pass their own list of keys:
+
+#+begin_src elisp :exports both :results code :lexical t
+ (cl-defun sporty-classify (sports &key (keys sporty-default-keys))
+ (declare (indent defun))
+ (let* ((taxy (make-taxy
+ :name "Sporty (DSL)"
+ :take (taxy-make-take-function keys
+ sporty-keys))))
+ (thread-last taxy
+ (taxy-fill sports)
+ (taxy-mapcar #'sport-name)
+ taxy-plain)))
+
+ (sporty-classify sports
+ :keys '((uses 'ball) venue))
+#+end_src
+
+And this produces:
+
+#+RESULTS:
+#+begin_src elisp
+ ("Sporty (DSL)"
+ ((outdoor
+ ("Ultimate" "Disc golf"))
+ (ball
+ ((indoor
+ ("Volleyball" "Handball" "Racquetball" "Basketball"))
+ (outdoor
+ ("Soccer" "Tennis" "Football" "Baseball"))))))
+#+end_src
+
** Reusable taxys
Since taxys are structs, they may be stored in variables and used in other
structs (being sure to copy the root taxy with ~taxy-emptied~ before filling).
For example, this shows using =taxy= to classify Matrix rooms in
[[https://github.com/alphapapa/ement.el][Ement.el]]:
diff --git a/taxy.el b/taxy.el
index 0bd2160..972c4e4 100644
--- a/taxy.el
+++ b/taxy.el
@@ -267,8 +267,6 @@ KEY is passed to `cl-sort', which see."
;; Utilities to define key and take functions in a standard way.
-;; TODO: Document these.
-
(defmacro taxy-define-key-definer (name variable prefix docstring)
"Define a macro NAME that defines a key-function-defining macro.
The defined macro, having string DOCSTRING, associates the
diff --git a/taxy.info b/taxy.info
index 5699555..9f28f9e 100644
--- a/taxy.info
+++ b/taxy.info
@@ -60,6 +60,7 @@ Dynamic taxys
* Multi-level dynamic taxys::
* "Chains" of independent, multi-level dynamic taxys: "Chains" of independent
multi-level dynamic taxys.
+* Defining a classification domain-specific language::
Changelog
@@ -546,7 +547,7 @@ File: README.info, Node: Dynamic taxys, Next: Reusable
taxys, Up: Usage
3.1 Dynamic taxys
=================
- • •
+ • • •
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
@@ -605,6 +606,7 @@ and it produces this taxonomy of buffers:
* Multi-level dynamic taxys::
* "Chains" of independent, multi-level dynamic taxys: "Chains" of independent
multi-level dynamic taxys.
+* Defining a classification domain-specific language::
File: README.info, Node: Multi-level dynamic taxys, Next: "Chains" of
independent multi-level dynamic taxys, Up: Dynamic taxys
@@ -662,7 +664,7 @@ directory.
(#<buffer taxy-magit-section.el> #<buffer taxy.el<taxy.el>
#<buffer scratch.el>))))))))
-File: README.info, Node: "Chains" of independent multi-level dynamic taxys,
Prev: Multi-level dynamic taxys, Up: Dynamic taxys
+File: README.info, Node: "Chains" of independent multi-level dynamic taxys,
Next: Defining a classification domain-specific language, Prev: Multi-level
dynamic taxys, Up: Dynamic taxys
3.1.2 "Chains" of independent, multi-level dynamic taxys
--------------------------------------------------------
@@ -734,6 +736,125 @@ use:
("Soccer" "Tennis" "Football" "Baseball"))))))
+File: README.info, Node: Defining a classification domain-specific language,
Prev: "Chains" of independent multi-level dynamic taxys, Up: Dynamic taxys
+
+3.1.3 Defining a classification domain-specific language
+--------------------------------------------------------
+
+When writing a larger Taxy-based application, it may be necessary to
+define a number of key functions that would be unwieldy to manage in a
+‘cl-labels’ form. For this case, Taxy provides the macro
+‘taxy-define-key-definer’ to easily define Taxy key functions in an
+application library. Those functions are then passed to the function
+‘taxy-make-take-function’ at runtime, along with a list of keys being
+used to classify items. Using these allows key functions to be defined
+in top-level forms, and it allows an application to be extended by
+users’ defining additional key functions in their configuration.
+
+ Extending the previous ‘sporty’ example, let’s redefine its key
+functions using ‘taxy-define-key-definer’:
+
+ (taxy-define-key-definer sporty-define-key
+ sporty-keys "sporty"
+ "Define a `sporty' key function.")
+
+ (sporty-define-key disc-based ()
+ (if (member 'disc (sport-uses item))
+ "Disc-based"
+ "Non-disc-based"))
+
+ (sporty-define-key uses (&optional thing)
+ (pcase thing
+ (`nil (sport-uses item))
+ (_ (when (cl-typecase (sport-uses item)
+ (symbol (equal thing (sport-uses item)))
+ (list (member thing (sport-uses item))))
+ thing))))
+
+ (sporty-define-key venue (&optional place)
+ (pcase place
+ (`nil (sport-venue item))
+ (_ (when (equal place (sport-venue item))
+ (sport-venue item)))))
+
+ Now we’ll define the default keys to use when classifying items.
+This list is equivalent to the one passed to ‘taxy-take-keyed’ in the
+previous, "Chains" example.
+
+ (defvar sporty-default-keys
+ '(
+ ((venue 'outdoor)
+ disc-based)
+
+ ((venue 'indoor)
+ (uses 'ball)
+ (uses 'disc)
+ (uses 'glove)
+ (uses 'racket))))
+
+ Finally, rather than using a pre-made taxy struct, we make one at
+runtime, making the ‘:take’ function with ‘taxy-make-take-function’.
+
+ (let ((taxy (make-taxy
+ :name "Sporty (DSL)"
+ :take (taxy-make-take-function sporty-default-keys
+ sporty-keys))))
+ (thread-last taxy
+ (taxy-fill sports)
+ (taxy-mapcar #'sport-name)
+ taxy-plain))
+
+ Which gives us:
+
+ ("Sporty (DSL)"
+ ((indoor
+ ((ball
+ ("Volleyball" "Basketball")
+ ((glove
+ ("Handball"))
+ (racket
+ ("Racquetball"))))))
+ (outdoor
+ (("Disc-based"
+ ("Ultimate" "Disc golf"))
+ ("Non-disc-based"
+ ("Soccer" "Tennis" "Football" "Baseball"))))))
+
+ As you can see, the result is the same as that in the previous
+example, but we’ve defined a kind of DSL for grouping sports in a
+modular, extendable way.
+
+ This also allows the grouping keys to be easily changed at runtime,
+producing a different result. For example, we could group sports by,
+first, whether they use a ball, and then by venue. Let’s do this in a
+function so that users can pass their own list of keys:
+
+ (cl-defun sporty-classify (sports &key (keys sporty-default-keys))
+ (declare (indent defun))
+ (let* ((taxy (make-taxy
+ :name "Sporty (DSL)"
+ :take (taxy-make-take-function keys
+ sporty-keys))))
+ (thread-last taxy
+ (taxy-fill sports)
+ (taxy-mapcar #'sport-name)
+ taxy-plain)))
+
+ (sporty-classify sports
+ :keys '((uses 'ball) venue))
+
+ And this produces:
+
+ ("Sporty (DSL)"
+ ((outdoor
+ ("Ultimate" "Disc golf"))
+ (ball
+ ((indoor
+ ("Volleyball" "Handball" "Racquetball" "Basketball"))
+ (outdoor
+ ("Soccer" "Tennis" "Football" "Baseball"))))))
+
+
File: README.info, Node: Reusable taxys, Next: Threading macros, Prev:
Dynamic taxys, Up: Usage
3.2 Reusable taxys
@@ -1125,39 +1246,40 @@ GPLv3
Tag Table:
Node: Top218
-Node: Examples1761
-Node: Numbery (starting basically)2080
-Node: Lettery (filling incrementally)7841
-Node: Sporty (understanding completely)10355
-Node: Applications16342
-Node: Installation16742
-Node: Usage17055
-Node: Dynamic taxys19192
-Node: Multi-level dynamic taxys21752
-Node: "Chains" of independent multi-level dynamic taxys23945
-Node: Reusable taxys26817
-Node: Threading macros30992
-Node: Modifying filled taxys31531
-Node: Magit section32349
-Node: Changelog33037
-Node: 06-pre33229
-Node: Additions33341
-Node: 0534179
-Node: Additions (1)34318
-Node: Fixes35424
-Node: 0435578
-Node: 0335800
-Node: Changes35929
-Node: Fixes (1)36292
-Node: 0236727
-Node: Changes (1)36896
-Node: Additions (2)37188
-Node: Fixes (2)38047
-Node: 0138301
-Node: Development38400
-Node: Copyright assignment38606
-Node: Credits39194
-Node: License39384
+Node: Examples1816
+Node: Numbery (starting basically)2135
+Node: Lettery (filling incrementally)7896
+Node: Sporty (understanding completely)10410
+Node: Applications16397
+Node: Installation16797
+Node: Usage17110
+Node: Dynamic taxys19247
+Node: Multi-level dynamic taxys21866
+Node: "Chains" of independent multi-level dynamic taxys24059
+Node: Defining a classification domain-specific language26990
+Node: Reusable taxys31152
+Node: Threading macros35327
+Node: Modifying filled taxys35866
+Node: Magit section36684
+Node: Changelog37372
+Node: 06-pre37564
+Node: Additions37676
+Node: 0538514
+Node: Additions (1)38653
+Node: Fixes39759
+Node: 0439913
+Node: 0340135
+Node: Changes40264
+Node: Fixes (1)40627
+Node: 0241062
+Node: Changes (1)41231
+Node: Additions (2)41523
+Node: Fixes (2)42382
+Node: 0142636
+Node: Development42735
+Node: Copyright assignment42941
+Node: Credits43529
+Node: License43719
End Tag Table
- [elpa] externals/taxy updated (233f94c -> ade9a02), ELPA Syncer, 2021/09/15
- [elpa] externals/taxy e5b6429 07/42: Change: (taxy-magit-section-insert) Use format-fn from taxy, ELPA Syncer, 2021/09/15
- [elpa] externals/taxy fe190c2 09/42: Add: (taxy-magit-section-define-column-definer), ELPA Syncer, 2021/09/15
- [elpa] externals/taxy fb11a4f 19/42: WIP: (cl-defstruct deffy-def), ELPA Syncer, 2021/09/15
- [elpa] externals/taxy ad1cea3 14/42: Examples: Add elispy.el, ELPA Syncer, 2021/09/15
- [elpa] externals/taxy 6703d8b 21/42: WIP: Use deffy-def in -RET, ELPA Syncer, 2021/09/15
- [elpa] externals/taxy e92ef13 22/42: Comment: Add FIXME, ELPA Syncer, 2021/09/15
- [elpa] externals/taxy 0cda29a 38/42: Add: (taxy-magit-section-define-column-definer) Custom-type, ELPA Syncer, 2021/09/15
- [elpa] externals/taxy a7ff557 33/42: Docs: Document new things,
ELPA Syncer <=
- [elpa] externals/taxy 5020b43 31/42: Change: (deffy-goto-form) Bug #50576 is fixed., ELPA Syncer, 2021/09/15
- [elpa] externals/taxy 0826a47 02/42: WIP: taxy-magit-section column/table formatting, ELPA Syncer, 2021/09/15
- [elpa] externals/taxy d456f88 24/42: Add: (deffy-side-window-action), ELPA Syncer, 2021/09/15
- [elpa] externals/taxy 3787f4f 25/42: Fix: (deffy-buffer) Ensure file name, ELPA Syncer, 2021/09/15
- [elpa] externals/taxy 7ecc461 15/42: Fix: (taxy-magit-section-define-column-definer) Use defcustoms, ELPA Syncer, 2021/09/15
- [elpa] externals/taxy 8b7a95a 35/42: Docs: Clarify, ELPA Syncer, 2021/09/15
- [elpa] externals/taxy 2f4d9c3 05/42: Add: (taxy-magit-section-insert-indent-items), ELPA Syncer, 2021/09/15
- [elpa] externals/taxy 9f9cfef 34/42: Docs: Reorder sections, ELPA Syncer, 2021/09/15
- [elpa] externals/taxy 7a63677 08/42: Add: (taxy-define-key-definer), ELPA Syncer, 2021/09/15
- [elpa] externals/taxy 69872e4 06/42: Docs: Update readme, ELPA Syncer, 2021/09/15