From 2b94c00384f7bd4bfd7b6108e5be3b261e1cf018 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sat, 5 Oct 2019 09:38:13 +0200 Subject: [PATCH] Extend 'map-into' for better control on hash table creation --- etc/NEWS | 5 +++++ lisp/emacs-lisp/map.el | 22 ++++++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index c8cc753..caea917 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -24,6 +24,11 @@ applies, and please also update docstrings as needed. * Installation Changes in Emacs 27.1 +** Extend function 'map-into'. +Change 'map-into' lambda-list into (map type &rest args). +When 'map-into' is used to create hash tables args are now forwarded to +'make-hash-table' for better control. + ** Emacs now uses GMP, the GNU Multiple Precision library. By default, if 'configure' does not find a suitable libgmp, it arranges for the included mini-gmp library to be built and used. diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el index 54e802e..7360705 100644 --- a/lisp/emacs-lisp/map.el +++ b/lisp/emacs-lisp/map.el @@ -367,12 +367,12 @@ map-merge-with (pop maps))) result)) -(cl-defgeneric map-into (map type) +(cl-defgeneric map-into (map type &rest args) "Convert the map MAP into a map of type TYPE.") ;; FIXME: I wish there was a way to avoid this η-redex! -(cl-defmethod map-into (map (_type (eql list))) (map-pairs map)) -(cl-defmethod map-into (map (_type (eql alist))) (map-pairs map)) -(cl-defmethod map-into (map (_type (eql plist))) +(cl-defmethod map-into (map (_type (eql list)) &rest _) (map-pairs map)) +(cl-defmethod map-into (map (_type (eql alist)) &rest _) (map-pairs map)) +(cl-defmethod map-into (map (_type (eql plist)) &rest _) (let ((plist '())) (map-do (lambda (k v) (setq plist `(,k ,v ,@plist))) map) plist)) @@ -458,12 +458,14 @@ map-do (funcall function index elt)) array)) -(cl-defmethod map-into (map (_type (eql hash-table))) - "Convert MAP into a hash-table." - ;; FIXME: Just knowing we want a hash-table is insufficient, since that - ;; doesn't tell us the test function to use with it! - (let ((ht (make-hash-table :size (map-length map) - :test 'equal))) +(cl-defmethod map-into (map (_type (eql hash-table)) &rest keyword-args) + "Convert MAP into a hash-table. +If KEYWORD-ARGS are provided they are forwarded to `make-hash-table'. +If KEYWORD-ARGS is nil hash table size is set to MAP length and test to `equal'." + (let* ((h-args (if keyword-args + keyword-args + (list :size (map-length map) :test 'equal))) + (ht (apply #'make-hash-table h-args))) (map-apply (lambda (key value) (setf (map-elt ht key) value)) map) -- 2.7.4