[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/compat edfad44bfb: compat-29: Add with-memoization
From: |
ELPA Syncer |
Subject: |
[elpa] externals/compat edfad44bfb: compat-29: Add with-memoization |
Date: |
Tue, 10 Jan 2023 04:57:26 -0500 (EST) |
branch: externals/compat
commit edfad44bfb382b3f464e27dd6ae72cbbd7793618
Author: Daniel Mendler <mail@daniel-mendler.de>
Commit: Daniel Mendler <mail@daniel-mendler.de>
compat-29: Add with-memoization
---
NEWS.org | 1 +
compat-29.el | 12 ++++++++++++
compat-tests.el | 27 +++++++++++++++++++++++++++
compat.texi | 7 +++++++
4 files changed, 47 insertions(+)
diff --git a/NEWS.org b/NEWS.org
index 4c9b6019ee..968b938364 100644
--- a/NEWS.org
+++ b/NEWS.org
@@ -6,6 +6,7 @@
- compat-25: Improve algorithmic complexity of ~sort~.
- compat-28: Add ~make-separator-line~.
- compat-29: Minor fixes to ~keymap-*~ functions.
+- compat-29: Add ~with-memoization~.
* Release of "Compat" Version 29.1.1.0
diff --git a/compat-29.el b/compat-29.el
index abb9346530..6250a896e5 100644
--- a/compat-29.el
+++ b/compat-29.el
@@ -177,6 +177,18 @@ This function does not move point. Also see
`line-end-position'."
;;;; Defined in subr.el
+(compat-defmacro with-memoization (place &rest code) ;; <OK>
+ "Return the value of CODE and stash it in PLACE.
+If PLACE's value is non-nil, then don't bother evaluating CODE
+and return the value found in PLACE instead."
+ (declare (indent 1))
+ (gv-letplace (getter setter) place
+ `(or ,getter
+ ,(macroexp-let2 nil val (macroexp-progn code)
+ `(progn
+ ,(funcall setter val)
+ ,val)))))
+
(compat-defalias string-split split-string) ;; <OK>
(compat-defun function-alias-p (func &optional noerror) ;; <OK>
diff --git a/compat-tests.el b/compat-tests.el
index c1a812cad8..5eea987985 100644
--- a/compat-tests.el
+++ b/compat-tests.el
@@ -60,6 +60,33 @@
(setq list (funcall sym list "first" 1 #'string=))
(should (eq (compat-call plist-get list "first" #'string=) 1))))
+(ert-deftest with-memoization ()
+ (let ((x (cons nil nil)) y computed)
+ (with-memoization (car x)
+ (setq computed 'a))
+ (should-equal (car x) 'a)
+ (should-equal computed 'a)
+ (with-memoization (car x)
+ (setq computed 'b))
+ (should-equal (car x) 'a)
+ (should-equal computed 'a)
+ (with-memoization (cdr x)
+ (setq computed 'c))
+ (should-equal (cdr x) 'c)
+ (should-equal computed 'c)
+ (with-memoization (cdr x)
+ (setq computed 'd))
+ (should-equal (cdr x) 'c)
+ (should-equal computed 'c)
+ (with-memoization y
+ (setq computed 'e))
+ (should-equal y 'e)
+ (should-equal computed 'e)
+ (with-memoization y
+ (setq computed 'f))
+ (should-equal y 'e)
+ (should-equal computed 'e)))
+
(ert-deftest make-separator-line ()
(should-equal (length (make-separator-line 10)) 11)
(should (string-suffix-p "\n" (make-separator-line 10)))
diff --git a/compat.texi b/compat.texi
index 6d3a45e105..a08d05d19e 100644
--- a/compat.texi
+++ b/compat.texi
@@ -2022,6 +2022,13 @@ provided by Compat. Note that due to upstream changes,
it might happen
that there will be the need for changes, so use these functions with
care.
+@c copied from lispref/cl.texi
+@defmac with-memoization @var{place} @var{code}@dots{}
+This macro provides a simple way to do memoization. @var{code} is
+evaluated and then stashed in @var{place}. If @var{place}'s value is
+non-@code{nil}, return that value instead of evaluating @var{code}.
+@end defmac
+
@c copied from lispref/positions.texi
@defun pos-bol &optional count
Like @code{line-beginning-position}, but ignores fields (and is more
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] externals/compat edfad44bfb: compat-29: Add with-memoization,
ELPA Syncer <=