[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/dict-tree 9120845 032/154: Make weird variable names us
From: |
Stefan Monnier |
Subject: |
[elpa] externals/dict-tree 9120845 032/154: Make weird variable names used to avoid dynamic scoping bugs more consistent |
Date: |
Mon, 14 Dec 2020 12:21:38 -0500 (EST) |
branch: externals/dict-tree
commit 9120845b066423a8e7dc9767de120c90dabc1a57
Author: Toby Cubitt <toby-predictive@dr-qubit.org>
Commit: tsc25 <toby-predictive@dr-qubit.org>
Make weird variable names used to avoid dynamic scoping bugs more consistent
and document what should be avoided in user-visible functions.
---
dict-tree.el | 256 +++++++++++++++++++++++++++--------------------------------
1 file changed, 116 insertions(+), 140 deletions(-)
diff --git a/dict-tree.el b/dict-tree.el
index 030d5db..b2e5a39 100644
--- a/dict-tree.el
+++ b/dict-tree.el
@@ -209,12 +209,12 @@ If START or END is negative, it counts from the end."
;; `goto-line' without messing around with mark and messages
-;; Note: this is a bug in simple.el; there's clearly a place for
-;; non-interactive calls to goto-line from Lisp code, and
-;; there's no warning against doing this. Yet goto-line *always*
-;; calls push-mark, which usually *shouldn't* be invoked by
+;; Note: This is a bug in simple.el. There's clearly a place for
+;; non-interactive calls to goto-line from Lisp code, and there's no
+;; warning against doing this in the documentation. Yet goto-line
+;; *always* calls push-mark, which usually *shouldn't* be invoked by
;; Lisp programs, as its docstring warns.
-(defmacro dictree-goto-line (line)
+(defmacro dictree--goto-line (line)
"Goto line LINE, counting from line 1 at beginning of buffer."
`(progn
(goto-char 1)
@@ -227,11 +227,13 @@ If START or END is negative, it counts from the end."
;;; ====================================================================
;;; Internal functions and variables for use in the dictionary package
-
(defvar dictree-loaded-list nil
"Stores list of loaded dictionaries.")
+;; ----------------------------------------------------------------
+;; Dictionary data cell structures
+
;; Note: It would be more elegant to use a defstruct for the data cells, but
;; the problem is that the resulting setf in `dictree--wrap-insfun'
;; won't get expanded into the cell-data accessor function at
@@ -259,15 +261,9 @@ If START or END is negative, it counts from the end."
(defsetf dictree--cell-data dictree--cell-set-data)
(defsetf dictree--cell-plist dictree--cell-set-plist)
-;; (defstruct
-;; (dictree--cell
-;; :named
-;; (:constructor nil)
-;; (:constructor dictree--cell-create
-;; (data &optional plist)))
-;; data plist)
-
+;; ----------------------------------------------------------------
+;; Dictionary cache entry structures
;; Note: We *could* us a defstruct for the cache entries, but for something
;; this simple it doesn't seem worth it, especially given that we're
@@ -289,6 +285,8 @@ If START or END is negative, it counts from the end."
(defalias 'dictree--cache-set-maxnum 'setcdr) ; INTERNAL USE ONLY
+;; ----------------------------------------------------------------
+;; Wrapping functions
(defun dictree--wrap-insfun (insfun) ; INTERNAL USE ONLY
;; return wrapped insfun to deal with data wrapping
@@ -298,42 +296,6 @@ If START or END is negative, it counts from the end."
(dictree--cell-data old)))
old)))
-;; (defmacro dictree--wrap-insfun-2 (f-2)
-;; ;; construct body of `dictree--wrap-insfun'
-;; (let ((comma-f `(nil ,f-2)))
-;; (setcar comma-f ',)
-;; (macroexpand-all
-;; `(lambda (new old)
-;; (setf (dictree--cell-data old)
-;; (,comma-f (dictree--cell-data new)
-;; (dictree--cell-data old)))))))
-
-;; (defmacro dictree--wrap-insfun-1 (f-1)
-;; ;; return body of `dictree--wrap-insfun'
-;; `(eval (backquote ,(macroexpand-all `(dictree--wrap-insfun-2 ,f-1)))))
-
-;; (defun dictree--wrap-insfun (insfun) ; INTERNAL USE ONLY
-;; ;; return wrapped insfun to deal with data wrapping
-;; (byte-compile (dictree--wrap-insfun-1 insfun)))
-
-;; (eval-when-compile
-;; (let ((buff (get-buffer "*Compile-Log*")))
-;; (when buff
-;; (save-excursion
-;; (set-buffer buff)
-;; (setq buffer-read-only nil)
-;; (goto-char (point-max))
-;; (insert
-;; "\nThe above warning is true, though it's not obvious from the
-;; source code! Be that as it may, I can't fix this until someone
-;; explains to me how to define `dictree--wrap-insfun' without using
-;; old-style backquotes, whilst still ensuring that the `setf' in
-;; the `dictree--wrap-insfun-2' macro is expanded at compile-time
-;; rather than run-time.
-;; -- Toby Cubitt\n")
-;; (setq buffer-read-only t)))))
-
-
(defun dictree--wrap-rankfun (rankfun) ; INTERNAL USE ONLY
;; return wrapped rankfun to deal with data wrapping
(byte-compile
@@ -355,6 +317,8 @@ If START or END is negative, it counts from the end."
(dictree--cell-plist cell2))))))
+;; ----------------------------------------------------------------
+;; The dictionary data structures
(defstruct
(dictree-
@@ -501,6 +465,10 @@ If START or END is negative, it counts from the end."
dictlist meta-dict-list)
+
+;; ----------------------------------------------------------------
+;; Miscelaneous internal functions and macros
+
(defun dictree--trielist (dict)
;; Return a list of all the tries on which DICT is based. If DICT is a
;; meta-dict, this recursively descends the hierarchy, gathering all the
@@ -516,6 +484,35 @@ If START or END is negative, it counts from the end."
(setq accumulate (cons (dictree--trie dict) accumulate))))
+(defmacro dictree--query-triefun (query-type)
+ ;; Return trie query function corresponding to QUERY-TYPE
+ `(intern (concat "trie-" (symbol-name ,query-type))))
+
+(defmacro dictree--query-stackfun (query-type)
+ ;; Return dictree stack creation function corresponding to QUERY-TYPE
+ `(intern (concat "dictree-" (symbol-name ,query-type) "-stack")))
+
+(defmacro dictree--query-cacheparam (query-type dict ranked)
+ ;; Return DICT's QUERY-TYPE cache threshold.
+ `(if ,ranked
+ (funcall (intern (concat "dictree-" (symbol-name ,query-type)
+ "-ranked-cache-threshold"))
+ ,dict)
+ (funcall (intern (concat "dictree-" (symbol-name ,query-type)
+ "-cache-threshold"))
+ ,dict)))
+
+(defmacro dictree--query-cache (query-type dict ranked)
+ ;; Return DICT's QUERY-TYPE cache.
+ `(if ,ranked
+ (funcall
+ (intern (concat "dictree-" (symbol-name ,query-type) "-ranked-cache"))
+ ,dict)
+ (funcall
+ (intern (concat "dictree-" (symbol-name ,query-type) "-cache"))
+ ,dict)))
+
+
(defun dictree--merge (list1 list2 cmpfun &optional combfun maxnum)
;; Destructively merge together sorted lists LIST1 and LIST2 of completions,
;; sorting elements according to CMPFUN. For non-null MAXNUM, only the first
@@ -576,7 +573,7 @@ If START or END is negative, it counts from the end."
;;; ================================================================
-;;; The public functions which operate on dictionaries
+;;; The (mostly) public functions which operate on dictionaries
(defun dictree-create
(&optional
@@ -826,6 +823,7 @@ The other arguments are as for `dictree-create'."
dict))
+
(defun dictree-p (obj)
"Return t if OBJ is a dictionary tree, nil otherwise."
(or (dictree--p obj) (dictree--meta-dict-p obj)))
@@ -987,37 +985,6 @@ The other arguments are as for `dictree-create'."
(dictree--complete-ranked-cache dict)))
-(defmacro dictree--query-triefun (query-type)
- ;; Return trie query function corresponding to QUERY-TYPE
- `(intern (concat "trie-" (symbol-name ,query-type))))
-
-(defmacro dictree--query-stackfun (query-type)
- ;; Return dictree stack creation function corresponding to QUERY-TYPE
- `(intern (concat "dictree-" (symbol-name ,query-type) "-stack")))
-
-(defmacro dictree--query-cacheparam (query-type dict ranked)
- ;; Return DICT's QUERY-TYPE cache threshold.
- `(if ,ranked
- (funcall (intern (concat "dictree-" (symbol-name ,query-type)
- "-ranked-cache-threshold"))
- ,dict)
- (funcall (intern (concat "dictree-" (symbol-name ,query-type)
- "-cache-threshold"))
- ,dict)))
-
-(defmacro dictree--query-cache (query-type dict ranked)
- ;; Return DICT's QUERY-TYPE cache.
- `(if ,ranked
- (funcall
- (intern (concat "dictree-" (symbol-name ,query-type) "-ranked-cache"))
- ,dict)
- (funcall
- (intern (concat "dictree-" (symbol-name ,query-type) "-cache"))
- ,dict)))
-
-
-
-
;; ----------------------------------------------------------------
;; Inserting and deleting data
@@ -1161,11 +1128,11 @@ TEST returns non-nil."
cache
(dictree--merge
(list (cons key newdata)) completions
- `(lambda (a b)
- (,(eval (macroexpand
- `(trie-construct-sortfun
- ,(dictree-comparison-function dict))))
- (car a) (car b)))
+ (byte-compile
+ `(lambda (a b)
+ (,(trie-construct-sortfun
+ (dictree-comparison-function dict))
+ (car a) (car b))))
(when (dictree--meta-dict-p dict)
(dictree--meta-dict-combfun dict))
maxnum)))
@@ -1444,29 +1411,33 @@ If TYPE is 'string, it must be possible to apply the
function
`string' to the elements of sequences stored in DICT.
FUNCTION is applied in ascending order, or descending order if
-REVERSE is non-nil."
+REVERSE is non-nil.
+
+Note: to avoid nasty dynamic scoping bugs, FUNCTION must *not*
+bind any variables with names commencing \"--\"."
- ;; "rename" FUNCTION to something hopefully unique, to help avoid nasty
- ;; dynamical scoping bugs
- (let ((dictree-mapc--function function))
+ ;; "rename" FUNCTION to something hopefully unique to lessen the likelihood
+ ;; of dynamic scoping bugs caused by a supplied function binding a variable
+ ;; with the same name as one of the arguments
+ (let ((--dictree-mapc--function function))
(dictree--mapc
(lambda (key data plist)
- (funcall dictree-mapc--function key data))
+ (funcall --dictree-mapc--function key data))
dict type reverse)))
+
(defun dictree--mapc (function dict &optional type reverse)
;; Like `dictree-mapc', but FUNCTION is passed three arguments: the key, the
;; data, and the property list, instead of just key and data.
- ;; "rename" FUNCTION to something hopefully unique, to help avoid nasty
- ;; dynamical scoping bugs
- (let ((dictree--mapc--function function))
+ ;; try to avoid dynamic binding bugs
+ (let ((--dictree--mapc--function function))
;; for a normal dictionary, map the function over its trie
(if (not (dictree--meta-dict-p dict))
(trie-mapc
(lambda (key cell)
- (funcall dictree--mapc--function
+ (funcall --dictree--mapc--function
key
(dictree--cell-data cell)
(dictree--cell-plist cell)))
@@ -1476,13 +1447,14 @@ REVERSE is non-nil."
(let ((stack (dictree-stack dict))
entry)
(while (setq entry (dictree--stack-pop stack))
- (funcall dictree--mapc--function
+ (funcall --dictree--mapc--function
(car entry)
(dictree--cell-data (cdr entry))
(dictree--cell-plist (cdr entry)))))
)))
+
(defun dictree-mapf (function combinator dict &optional type reverse)
"Apply FUNCTION to all entries in dictionary DICT,
and combine the results using COMBINATOR.
@@ -1499,33 +1471,36 @@ stored in DICT.
The FUNCTION will be applied and the results combined in
asscending \"lexical\" order (i.e. the order defined by the
dictionary's comparison function; cf. `dictree-create'), or
-descending order if REVERSE is non-nil."
+descending order if REVERSE is non-nil.
+
+Note: to avoid nasty dynamic scoping bugs, FUNCTION and
+COMBINATOR must *not* bind any variables with names
+commencing \"--\"."
- ;; "rename" functions to something hopefully unique, to help avoid nasty
- ;; dynamical scoping bugs
- (let ((dictree-mapf--function function)
- (dictree-mapf--combinator combinator))
+ ;; try to avoid dynamic scoping bugs
+ (let ((--dictree-mapf--function function)
+ (--dictree-mapf--combinator combinator))
;; for a normal dictionary, map the function over its trie
(if (not (dictree--meta-dict-p dict))
(trie-mapf
`(lambda (key data)
- (,dictree-mapf--function key (dictree--cell-data data)))
- dictree-mapf--combinator (dictree--trie dict) type reverse)
+ (,--dictree-mapf--function key (dictree--cell-data data)))
+ --dictree-mapf--combinator (dictree--trie dict) type reverse)
;; for a meta-dict, use a dictree-stack
- (let ((dictree-mapf--stack (dictree-stack dict))
- dictree-mapf--entry
- dictree-mapf--accumulate)
- (while (setq dictree-mapf--entry
- (dictree-stack-pop dictree-mapf--stack))
- (setq dictree-mapf--accumulate
- (funcall dictree-mapf--combinator
- (funcall dictree-mapf--function
- (car dictree-mapf--entry)
- (cdr dictree-mapf--entry))
- dictree-mapf--accumulate)))
- dictree-mapf--accumulate))))
+ (let ((--dictree-mapf--stack (dictree-stack dict))
+ --dictree-mapf--entry
+ --dictree-mapf--accumulate)
+ (while (setq --dictree-mapf--entry
+ (dictree-stack-pop --dictree-mapf--stack))
+ (setq --dictree-mapf--accumulate
+ (funcall --dictree-mapf--combinator
+ (funcall --dictree-mapf--function
+ (car --dictree-mapf--entry)
+ (cdr --dictree-mapf--entry))
+ --dictree-mapf--accumulate)))
+ --dictree-mapf--accumulate))))
@@ -1553,7 +1528,10 @@ then
(trie-mapf function 'cons trie type (not reverse))
-is more efficient."
+is more efficient.
+
+Note: to avoid nasty dynamic scoping bugs, FUNCTION must *not*
+bind any variables with names commencing \"--\"."
(nreverse (dictree-mapf function 'cons dict type)))
@@ -1577,6 +1555,7 @@ is more efficient."
;; ordinary version is just a single trie-stack). It consists of a heap of
;; trie-stacks for its constituent tries, where the heap order is the usual
;; lexical order over the keys at the top of the trie-stacks.
+
(defstruct
(dictree--meta-stack
(:constructor nil)
@@ -1584,13 +1563,10 @@ is more efficient."
(dict &optional (type 'vector) reverse
&aux
(combfun (dictree--meta-dict-combfun dict))
- (sortfun (eval (macroexpand
- `(trie-construct-sortfun
- ,(dictree-comparison-function dict)))))
+ (sortfun (trie-construct-sortfun
+ (dictree-comparison-function dict)))
(heap (heap-create
- (eval (macroexpand
- `(dictree--construct-meta-stack-heapfun
- ,sortfun)))
+ (dictree--construct-meta-stack-heapfun sortfun)
(length (dictree--trielist dict))))
(dummy (mapc
(lambda (dic)
@@ -1600,14 +1576,11 @@ is more efficient."
(dict prefix &optional reverse
&aux
(combfun (dictree--meta-dict-combfun dict))
- (sortfun (eval (macroexpand
- `(trie-construct-sortfun
- ,(dictree-comparison-function dict)))))
+ (sortfun (trie-construct-sortfun
+ (dictree-comparison-function dict)))
(heap (heap-create
- (eval (macroexpand
- `(dictree--construct-meta-stack-heapfun
- ,sortfun
- ,reverse)))
+ (dictree--construct-meta-stack-heapfun
+ sortfun reverse)
(length (dictree--trielist dict))))
(dummy (mapc
(lambda (trie)
@@ -1620,14 +1593,17 @@ is more efficient."
combfun sortfun heap)
-(defmacro dictree--construct-meta-stack-heapfun (sortfun &optional reverse)
+
+(defun dictree--construct-meta-stack-heapfun (sortfun &optional reverse)
;; Wrap SORTFUN, which sorts keys, so it can act on dictree--meta-stack
;; elements.
(if reverse
- `(lambda (a b) (,sortfun (car (dictree-stack-first b))
- (car (dictree-stack-first a))))
- `(lambda (a b) (,sortfun (car (dictree-stack-first a))
- (car (dictree-stack-first b))))))
+ (byte-compile
+ `(lambda (b a) (,sortfun (car (dictree-stack-first a))
+ (car (dictree-stack-first b)))))
+ (byte-compile
+ `(lambda (a b) (,sortfun (car (dictree-stack-first a))
+ (car (dictree-stack-first b)))))))
(defun dictree-stack (dict &optional type reverse)
@@ -1767,7 +1743,7 @@ Returns nil if the stack is empty."
;; ----------------------------------------------------------------
-;; Advanced queries
+;; Functions for building advanced queries
(defun dictree--query (query-type dict arg
&optional
@@ -2602,7 +2578,7 @@ this can help produce an efficient data-structure."
(midpt (+ (/ lines 2) (mod lines 2)))
entry)
;; insert the median key and set the dictionary's modified flag
- (dictree-goto-line midpt)
+ (dictree--goto-line midpt)
(when (setq entry
(condition-case nil
(dictree--read-line dict)
@@ -2616,7 +2592,7 @@ this can help produce an efficient data-structure."
;; insert keys successively further away from the median in both
;; directions
(dotimes (i (1- midpt))
- (dictree-goto-line (+ midpt i 1))
+ (dictree--goto-line (+ midpt i 1))
(when (setq entry
(condition-case nil
(dictree--read-line dict)
@@ -2628,7 +2604,7 @@ this can help produce an efficient data-structure."
(when (= 49 (mod i 50))
(message "Inserting keys in %s...(%d of %d)"
(dictree-name dict) (+ (* 2 i) 2) lines))
- (dictree-goto-line (- midpt i 1))
+ (dictree--goto-line (- midpt i 1))
(when (setq entry
(condition-case nil
(dictree--read-line dict)
@@ -2641,7 +2617,7 @@ this can help produce an efficient data-structure."
;; if file contains an even number of keys, we still have to add
;; the last one
(when (= 0 (mod lines 2))
- (dictree-goto-line lines)
+ (dictree--goto-line lines)
(when (setq entry
(condition-case nil
(dictree--read-line dict)
- [elpa] externals/dict-tree 9e6d0f2 017/154: Fixed bug when deleting non-existent entries., (continued)
- [elpa] externals/dict-tree 9e6d0f2 017/154: Fixed bug when deleting non-existent entries., Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 4cd369d 027/154: Avoid breaking setf abstraction in dictree--wrap-insfun., Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 9827131 016/154: Fixed unwrapped rank-function bug in dictree--query, Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 87bb7e8 019/154: Allow custom write and load functions when saving and dumping dictionaries;, Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 2978fc7 024/154: ...and already a bug-fix to the new cache updating code, Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 7d9b258 033/154: Improved handling of dictionary file names in dictree-load, Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree f46da76 008/154: Minor bug fixes., Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 405d11b 023/154: Implemented the other cache and cache-update policies, Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 57d59eb 021/154: Bug-fixes to predictive-auto-learn and read-dict., Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 76140ec 026/154: Converted function wrapping macros into functions, Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 9120845 032/154: Make weird variable names used to avoid dynamic scoping bugs more consistent,
Stefan Monnier <=
- [elpa] externals/dict-tree 6c21fcb 038/154: Fix dictree--query and dictree-complete to return results in correct format, Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 8a575f6 039/154: Added new trie functions to dictree--create-custom., Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 3a18a06 042/154: Modified dictree-populate-from-file to read linearly by default,, Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree ca2c562 050/154: Bug-fix to dictree-complete, Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree e1a9f19 051/154: Documentation updates related to wildcard searches and predictive features that make use of them, Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree bf4002d 063/154: Bug-fixes to dictree--write-dict-code; allow loading non-matching filenames in read-dict, Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 6d9921e 067/154: Updated docstrings for regexp-related functions and others., Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree d88b867 002/154: Version 0.10.3 of the predictive completion package., Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree 7b52ebd 005/154: Version 0.13.1 of the predictive completion package., Stefan Monnier, 2020/12/14
- [elpa] externals/dict-tree ac40f3c 004/154: Version 0.12.2 of the predictive completion package., Stefan Monnier, 2020/12/14