From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: [PATCH] extend map-into Date: Fri, 11 Oct 2019 12:19:47 -0400 Message-ID: References: <87v9sxdmxe.fsf@petton.fr> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="53321"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) Cc: emacs-devel@gnu.org, Nicolas Petton To: Andrea Corallo Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Oct 11 19:59:35 2019 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1iIzCQ-000Din-Qr for ged-emacs-devel@m.gmane.org; Fri, 11 Oct 2019 19:59:35 +0200 Original-Received: from localhost ([::1]:55032 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIzCO-00028Y-VP for ged-emacs-devel@m.gmane.org; Fri, 11 Oct 2019 13:59:33 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:39998) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIxe3-0004Rz-1K for emacs-devel@gnu.org; Fri, 11 Oct 2019 12:20:00 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIxe1-0006Ti-Nd for emacs-devel@gnu.org; Fri, 11 Oct 2019 12:19:58 -0400 Original-Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:3176) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIxe1-0006Qi-FN for emacs-devel@gnu.org; Fri, 11 Oct 2019 12:19:57 -0400 Original-Received: from pmg3.iro.umontreal.ca (localhost [127.0.0.1]) by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id 98CF0448DFF; Fri, 11 Oct 2019 12:19:56 -0400 (EDT) Original-Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg3.iro.umontreal.ca (Proxmox) with ESMTP id C3D29448DFD; Fri, 11 Oct 2019 12:19:53 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1570810793; bh=23zKAJCQVWwHP4UsWRskzf3KXbM37cBT0ltW4abp55s=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=gdT/wG9uWbAI8b37PoTeR14fsh0fN4jiP6Khx+ucX9UB+ULu1+vXretlvPL7skPQK XPaggqga6MPwSvYbBYTDPJ0kr0BM14E31nqNGhGPhyb3rjiKassVUxCvZJ2VAJeyQa n6ErPTwQ0XyzcpDUt0y26/ojmMptwqDXziTv8lApWEEVacw1kcYM0scEVmTaEqxEEA 0Aq6qOasB/KMkC6aPElgoFDEQ211X0Navv3elO9YU9M21hftKOJ8b3tlXyVjmsXRNH sTlfehB+suYEt2CGRjFtRN0lc6EXmIMFUNsPA9cqS3J1my+kJKLfkI0W/adtq43BTe 5bzurZkp1zrTQ== Original-Received: from alfajor (modemcable157.163-203-24.mc.videotron.ca [24.203.163.157]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 966051205D6; Fri, 11 Oct 2019 12:19:53 -0400 (EDT) In-Reply-To: (Andrea Corallo's message of "Thu, 10 Oct 2019 10:06:54 +0000") X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 132.204.25.50 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:240893 Archived-At: > attached. Thanks, installed into `master` with minor tweaks (e.g. the NEWS entry was misplaced, and I changed the defsubst into a defun because the function itself contains a loop so the overhead of the function call is unlikely to be significant in proportion). Stefan > From 7a1b42b1b58f7b0ee20ef24e9e73bce045a1987b Mon Sep 17 00:00:00 2001 > From: Andrea Corallo > Date: Sun, 6 Oct 2019 22:43:11 +0200 > Subject: [PATCH] Extend 'map-into' for better control on hash table creation. > > --- > etc/NEWS | 4 ++++ > lisp/emacs-lisp/map.el | 29 +++++++++++++++++++++-------- > test/lisp/emacs-lisp/map-tests.el | 5 ++++- > 3 files changed, 29 insertions(+), 9 deletions(-) > > diff --git a/etc/NEWS b/etc/NEWS > index c8cc753..5942a32 100644 > --- a/etc/NEWS > +++ b/etc/NEWS > @@ -24,6 +24,10 @@ applies, and please also update docstrings as needed. > > * Installation Changes in Emacs 27.1 > > +** Extend function 'map-into'. > +Add a 'map-into' method to have hash table creation parameters > +tweak-able. > + > ** 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..dfc1500 100644 > --- a/lisp/emacs-lisp/map.el > +++ b/lisp/emacs-lisp/map.el > @@ -338,7 +338,8 @@ map-every-p > t)) > > (defun map-merge (type &rest maps) > - "Merge into a map of type TYPE all the key/value pairs in MAPS." > + "Merge into a map of type TYPE all the key/value pairs in MAPS. > +See `map-into' for all supported values of TYPE." > (let ((result (map-into (pop maps) type))) > (while maps > ;; FIXME: When `type' is `list', we get an O(N^2) behavior. > @@ -354,7 +355,8 @@ map-merge-with > "Merge into a map of type TYPE all the key/value pairs in MAPS. > When two maps contain the same key (`eql'), call FUNCTION on the two > values and use the value returned by it. > -MAP can be a list, hash-table or array." > +MAP can be a list, hash-table or array. > +See `map-into' for all supported values of TYPE." > (let ((result (map-into (pop maps) type)) > (not-found (cons nil nil))) > (while maps > @@ -458,17 +460,28 @@ 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))) > +(defsubst map--into-hash (map keyword-args) > + "Convert MAP into a hash-table. > +KEYWORD-ARGS are forwarded to `make-hash-table'." > + (let ((ht (apply #'make-hash-table keyword-args))) > (map-apply (lambda (key value) > (setf (map-elt ht key) value)) > map) > ht)) > > +(cl-defmethod map-into (map (_type (eql hash-table))) > + "Convert MAP into a hash-table." > + (map--into-hash map (list :size (map-length map) :test 'equal))) > + > +(cl-defmethod map-into (map (args (head hash-table))) > + "Convert MAP into a hash-table. > +ARGS is a list where the car is 'hash-table' and the cdr are the keyword-args > + forwarded to `make-hash-table'. > + > +Example: > + (map-into '((1 . 3)) '(hash-table :test eql))" > + (map--into-hash map (cdr args))) > + > (defun map--make-pcase-bindings (args) > "Return a list of pcase bindings from ARGS to the elements of a map." > (seq-map (lambda (elt) > diff --git a/test/lisp/emacs-lisp/map-tests.el b/test/lisp/emacs-lisp/map-tests.el > index a54af80..9f61511 100644 > --- a/test/lisp/emacs-lisp/map-tests.el > +++ b/test/lisp/emacs-lisp/map-tests.el > @@ -340,7 +340,8 @@ test-map-every-p > > (ert-deftest test-map-into () > (let* ((alist '((a . 1) (b . 2))) > - (ht (map-into alist 'hash-table))) > + (ht (map-into alist 'hash-table)) > + (ht2 (map-into alist '(hash-table :test eq)))) > (should (hash-table-p ht)) > (should (equal (map-into (map-into alist 'hash-table) 'list) > alist)) > @@ -349,6 +350,8 @@ test-map-into > (map-keys ht))) > (should (equal (map-values (map-into (map-into ht 'list) 'hash-table)) > (map-values ht))) > + (should (equal (map-into ht 'alist) (map-into ht2 'alist))) > + (should (eq (hash-table-test ht2) 'eq)) > (should (null (map-into nil 'list))) > (should (map-empty-p (map-into nil 'hash-table))) > (should-error (map-into [1 2 3] 'string))))