From fd5980eacecdad9723846da7ef33bee3416b63a6 Mon Sep 17 00:00:00 2001 From: citreu Date: Sat, 13 Apr 2019 08:44:01 +0800 Subject: [PATCH 1/3] Ensure `hash?` expander evaluates its arg only once. --- dash.el | 4 +++- dev/examples.el | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dash.el b/dash.el index 4b0857f..411e052 100644 --- a/dash.el +++ b/dash.el @@ -1828,10 +1828,12 @@ kv can be any key-value store, such as plist, alist or hash-table." "Generate extracting KEY from SOURCE for &alist destructuring." `(cdr (assoc ,key ,source))) +(require 'macroexp) + (defun dash-expand:&hash? (key source) "Generate extracting KEY from SOURCE for &hash? destructuring. Similar to &hash but check whether the map is not nil." - `(when ,source (gethash ,key ,source))) + (macroexp-let2 nil source source `(when ,source (gethash ,key ,source)))) (defalias 'dash-expand:&keys 'dash-expand:&plist) diff --git a/dev/examples.el b/dev/examples.el index f987d45..5718315 100644 --- a/dev/examples.el +++ b/dev/examples.el @@ -1150,6 +1150,12 @@ new list." (puthash :bar 2 hash) (-let (((&hash :foo :bar) hash)) (list foo bar))) => '(1 2) (-let (((&hash :foo (&hash? :bar)) (make-hash-table)))) => nil + ;; Ensure `hash?' expander evaluates its arg only once + (let* ((ht (make-hash-table :test #'equal)) + (fn (lambda (ht) (cl-incf (gethash 'a ht)) ht))) + (puthash 'a 3 ht) + (-let (((&hash? 'a) (funcall fn ht))) + a)) => 4 (-let (((_ &keys :foo :bar) (list 'ignored :foo 1 :bar 2))) (list foo bar)) => '(1 2) ;;; go over all the variations of match-form derivation (-let (((&plist :foo foo :bar) (list :foo 1 :bar 2))) (list foo bar)) => '(1 2) From 93e0465e0ea1d3fbcb49e84f0663c9be6a988225 Mon Sep 17 00:00:00 2001 From: citreu Date: Sat, 13 Apr 2019 09:45:30 +0800 Subject: [PATCH 2/3] Remove dependecy `macroexp` We need to support lower version since `macroexp-let2` was introduced at Emacs 24.3 --- dash.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dash.el b/dash.el index 411e052..e945fbb 100644 --- a/dash.el +++ b/dash.el @@ -1828,12 +1828,12 @@ kv can be any key-value store, such as plist, alist or hash-table." "Generate extracting KEY from SOURCE for &alist destructuring." `(cdr (assoc ,key ,source))) -(require 'macroexp) - (defun dash-expand:&hash? (key source) "Generate extracting KEY from SOURCE for &hash? destructuring. Similar to &hash but check whether the map is not nil." - (macroexp-let2 nil source source `(when ,source (gethash ,key ,source)))) + (let ((src (make-symbol "src"))) + `(let ((,src ,source)) + (when ,src (gethash ,key ,src))))) (defalias 'dash-expand:&keys 'dash-expand:&plist) From bbf8016a781c39efdf94ec37951325567fe0f5d3 Mon Sep 17 00:00:00 2001 From: citreu Date: Sat, 13 Apr 2019 09:50:50 +0800 Subject: [PATCH 3/3] Remove dependecy `cl-lib` in tests. For compatability for Emacs 24.2 and 24.1 --- dev/examples.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/examples.el b/dev/examples.el index 5718315..ff7a92d 100644 --- a/dev/examples.el +++ b/dev/examples.el @@ -1152,10 +1152,10 @@ new list." (-let (((&hash :foo (&hash? :bar)) (make-hash-table)))) => nil ;; Ensure `hash?' expander evaluates its arg only once (let* ((ht (make-hash-table :test #'equal)) - (fn (lambda (ht) (cl-incf (gethash 'a ht)) ht))) - (puthash 'a 3 ht) + (fn (lambda (ht) (push 3 (gethash 'a ht)) ht))) + (puthash 'a nil ht) (-let (((&hash? 'a) (funcall fn ht))) - a)) => 4 + a)) => '(3) (-let (((_ &keys :foo :bar) (list 'ignored :foo 1 :bar 2))) (list foo bar)) => '(1 2) ;;; go over all the variations of match-form derivation (-let (((&plist :foo foo :bar) (list :foo 1 :bar 2))) (list foo bar)) => '(1 2)