From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Joseph Turner via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#63509: [PATCH] Make copy-tree work with records Date: Mon, 15 May 2023 10:59:57 -0700 Message-ID: <87sfbxtoib.fsf@breatheoutbreathe.in> References: <87fs7yfdg2.fsf@breatheoutbreathe.in> <83lehp25ug.fsf@gnu.org> Reply-To: Joseph Turner Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="20907"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 63509@debbugs.gnu.org, Stefan Monnier To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon May 15 20:54:23 2023 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pydKw-0005ES-TB for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 15 May 2023 20:54:22 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pydKi-0002rb-0p; Mon, 15 May 2023 14:54:08 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pydKe-0002r8-AS for bug-gnu-emacs@gnu.org; Mon, 15 May 2023 14:54:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pydKc-0007sK-IN for bug-gnu-emacs@gnu.org; Mon, 15 May 2023 14:54:04 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1pydKb-0002zu-VU for bug-gnu-emacs@gnu.org; Mon, 15 May 2023 14:54:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Joseph Turner Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 15 May 2023 18:54:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63509 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 63509-submit@debbugs.gnu.org id=B63509.168417682311496 (code B ref 63509); Mon, 15 May 2023 18:54:01 +0000 Original-Received: (at 63509) by debbugs.gnu.org; 15 May 2023 18:53:43 +0000 Original-Received: from localhost ([127.0.0.1]:44412 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pydKJ-0002zL-1H for submit@debbugs.gnu.org; Mon, 15 May 2023 14:53:43 -0400 Original-Received: from out-44.mta1.migadu.com ([95.215.58.44]:51669) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1pydKF-0002zA-Dr for 63509@debbugs.gnu.org; Mon, 15 May 2023 14:53:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=breatheoutbreathe.in; s=key1; t=1684176817; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=FWrXy5R0xEeJvjus32HXtLDvk29xJOWN6OYoGtTWjMc=; b=Ta7p1Ik0IkvsCW0qbL9ph3T/K64P4/tCOr5UaJP7D16dhs+jlQT4MsLmLW72Su7DOyrnPo sQOj9YumsrcjaIMZnXNawCWnjdyk1ttZoVg6xxFisoO+dLJwSA8JO8FouXDjhHEdDTOCM5 17FbUTOjfG8CAMBlOLZNdYRzyECuX8o= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. In-reply-to: <83lehp25ug.fsf@gnu.org> X-Migadu-Flow: FLOW_OUT X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:261763 Archived-At: --=-=-= Content-Type: text/plain Eli Zaretskii writes: > - NEWS entry I updated the 29 entry. Should I move it to 30? > - update for the ELisp manual Changes made in patch: - updated the entry in lists.texi - added a new entry in records.texi - added entry in the vector group in shortdoc.el > - preferably added tests to regression-test this feature Done. > I also think we should rename the second argument, as VECP no longer > fits. How about VECTOR-LIKE-P? See patch. Joseph --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Make-copy-tree-work-with-records.patch >From 14383e9fe8a107f597d06ad486a441b761cc6ade Mon Sep 17 00:00:00 2001 From: Joseph Turner Date: Sun, 14 May 2023 21:02:15 -0700 Subject: [PATCH] Make copy-tree work with records --- doc/lispref/lists.texi | 9 +++++---- doc/lispref/records.texi | 12 ++++++++++++ etc/NEWS.29 | 5 +++++ lisp/emacs-lisp/shortdoc.el | 2 ++ lisp/subr.el | 14 +++++++------- test/lisp/subr-tests.el | 31 +++++++++++++++++++++++++++++++ 6 files changed, 62 insertions(+), 11 deletions(-) diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi index 22a5f7f1239..16ed0358974 100644 --- a/doc/lispref/lists.texi +++ b/doc/lispref/lists.texi @@ -696,16 +696,17 @@ not a list, the sequence's elements do not become elements of the resulting list. Instead, the sequence becomes the final @sc{cdr}, like any other non-list final argument. -@defun copy-tree tree &optional vecp +@defun copy-tree tree &optional vector-like-p This function returns a copy of the tree @var{tree}. If @var{tree} is a cons cell, this makes a new cons cell with the same @sc{car} and @sc{cdr}, then recursively copies the @sc{car} and @sc{cdr} in the same way. Normally, when @var{tree} is anything other than a cons cell, -@code{copy-tree} simply returns @var{tree}. However, if @var{vecp} is -non-@code{nil}, it copies vectors too (and operates recursively on -their elements). This function cannot cope with circular lists. +@code{copy-tree} simply returns @var{tree}. However, if +@var{vector-like-p} is non-@code{nil}, it copies vectors and records +too (and operates recursively on their elements). This function +cannot cope with circular lists. @end defun @defun flatten-tree tree diff --git a/doc/lispref/records.texi b/doc/lispref/records.texi index 26c6f30a6b5..0f44198a6b0 100644 --- a/doc/lispref/records.texi +++ b/doc/lispref/records.texi @@ -81,6 +81,18 @@ This function returns a new record with type @var{type} and @end example @end defun +@defun copy-tree tree &optional vector-like-p +This function copies a record when @var{vector-like-p} is +non-@code{nil}. + +@example +@group +(copy-tree (record 'foo "a")) + @result{} #s(foo "a") +@end group +@end example +@end defun + @node Backward Compatibility @section Backward Compatibility diff --git a/etc/NEWS.29 b/etc/NEWS.29 index fa428d9c790..ae9a89203bf 100644 --- a/etc/NEWS.29 +++ b/etc/NEWS.29 @@ -4897,6 +4897,11 @@ Instead, Emacs uses the already-existing 'make-directory' handlers. This can let a caller know whether it created DIR. Formerly, 'make-directory's return value was unspecified. ++++ +** 'copy-tree' now correctly copies records when its optional second +argument is non-nil. The second argument has been renamed from VECP +to VECTOR-LIKE-P since it now works with both vectors and records. + * Changes in Emacs 29.1 on Non-Free Operating Systems diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 9a6f5dd12ce..6580e0e4e0c 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -833,6 +833,8 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'), (seq-subseq :eval (seq-subseq [1 2 3 4 5] 1 3) :eval (seq-subseq [1 2 3 4 5] 1)) + (copy-tree + :eval (copy-tree [1 2 3 4])) "Mapping Over Vectors" (mapcar :eval (mapcar #'identity [1 2 3])) diff --git a/lisp/subr.el b/lisp/subr.el index 03d3324f3d8..83735933963 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -824,26 +824,26 @@ of course, also replace TO with a slightly larger value next (+ from (* n inc))))) (nreverse seq)))) -(defun copy-tree (tree &optional vecp) +(defun copy-tree (tree &optional vector-like-p) "Make a copy of TREE. If TREE is a cons cell, this recursively copies both its car and its cdr. Contrast to `copy-sequence', which copies only along the cdrs. With second -argument VECP, this copies vectors as well as conses." +argument VECTOR-LIKE-P, this copies vectors and records as well as conses." (declare (side-effect-free error-free)) (if (consp tree) (let (result) (while (consp tree) (let ((newcar (car tree))) - (if (or (consp (car tree)) (and vecp (vectorp (car tree)))) - (setq newcar (copy-tree (car tree) vecp))) + (if (or (consp (car tree)) (and vector-like-p (or (vectorp (car tree)) (recordp (car tree))))) + (setq newcar (copy-tree (car tree) vector-like-p))) (push newcar result)) (setq tree (cdr tree))) (nconc (nreverse result) - (if (and vecp (vectorp tree)) (copy-tree tree vecp) tree))) - (if (and vecp (vectorp tree)) + (if (and vector-like-p (or (vectorp tree) (recordp tree))) (copy-tree tree vector-like-p) tree))) + (if (and vector-like-p (or (vectorp tree) (recordp tree))) (let ((i (length (setq tree (copy-sequence tree))))) (while (>= (setq i (1- i)) 0) - (aset tree i (copy-tree (aref tree i) vecp))) + (aset tree i (copy-tree (aref tree i) vector-like-p))) tree) tree))) diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 8f46c2af136..4ebb68556be 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -1206,5 +1206,36 @@ final or penultimate step during initialization.")) (should (equal a-dedup '("a" "b" "a" "b" "c"))) (should (eq a a-dedup)))) +(ert-deftest subr--copy-tree () + (should (eq (copy-tree nil) nil)) + (let* ((a (list (list "a") "b" (list "c") "g")) + (copy1 (copy-tree a)) + (copy2 (copy-tree a t))) + (should (equal a copy1)) + (should (equal a copy2)) + (should-not (eq a copy1)) + (should-not (eq a copy2))) + (let* ((a (list (list "a") "b" (list "c" (record 'foo "d")) (list ["e" "f"]) "g")) + (copy1 (copy-tree a)) + (copy2 (copy-tree a t))) + (should (equal a copy1)) + (should (equal a copy2)) + (should-not (eq a copy1)) + (should-not (eq a copy2))) + (let* ((a (record 'foo "a" (record 'bar "b"))) + (copy1 (copy-tree a)) + (copy2 (copy-tree a t))) + (should (equal a copy1)) + (should (equal a copy2)) + (should (eq a copy1)) + (should-not (eq a copy2))) + (let* ((a ["a" "b" ["c" ["d"]]]) + (copy1 (copy-tree a)) + (copy2 (copy-tree a t))) + (should (equal a copy1)) + (should (equal a copy2)) + (should (eq a copy1)) + (should-not (eq a copy2)))) + (provide 'subr-tests) ;;; subr-tests.el ends here -- 2.40.1 --=-=-=--