From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Drew Adams Newsgroups: gmane.emacs.bugs Subject: bug#34708: alist-get has unclear documentation Date: Tue, 12 Mar 2019 07:48:27 -0700 (PDT) Message-ID: <32eea01e-cec1-42b7-8221-f4dd4652f0fa@default> References: <87wolhr5k6.fsf@web.de> <87y35xdu4w.fsf@web.de> <87mumcdu7f.fsf@web.de> <875zsyhakx.fsf@ericabrahamsen.net> <87fts2h9we.fsf@web.de> <871s3mh85d.fsf@ericabrahamsen.net> <874l8iebyz.fsf@web.de> <878sxui7bo.fsf@ericabrahamsen.net> <87va0xcxco.fsf@web.de> <87h8chey12.fsf@ericabrahamsen.net> <60367f47-c0b0-45b4-8ccf-169044400a75@default> <8736ntmsy3.fsf@web.de> <3af3b645-84e0-4208-be48-810e8cd2cfa8@default> <87wol5l6xk.fsf@web.de> <6e0c5a88-34db-4957-9cc5-98a14ae64f9f@default> <87ef7c1bxs.fsf@web.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="218465"; mail-complaints-to="usenet@blaine.gmane.org" Cc: Eric Abrahamsen , 34708@debbugs.gnu.org To: Michael Heerdegen Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Mar 12 15:54:28 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1h3inT-000ugL-1F for geb-bug-gnu-emacs@m.gmane.org; Tue, 12 Mar 2019 15:54:27 +0100 Original-Received: from localhost ([127.0.0.1]:53884 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h3inS-0000iV-0F for geb-bug-gnu-emacs@m.gmane.org; Tue, 12 Mar 2019 10:54:26 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:46452) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h3inB-0000YF-74 for bug-gnu-emacs@gnu.org; Tue, 12 Mar 2019 10:54:10 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h3iiE-00026i-Oy for bug-gnu-emacs@gnu.org; Tue, 12 Mar 2019 10:49:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:55109) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1h3iiE-00026T-Hn for bug-gnu-emacs@gnu.org; Tue, 12 Mar 2019 10:49:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1h3iiE-0001yR-By for bug-gnu-emacs@gnu.org; Tue, 12 Mar 2019 10:49:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Drew Adams Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 12 Mar 2019 14:49:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 34708 X-GNU-PR-Package: emacs Original-Received: via spool by 34708-submit@debbugs.gnu.org id=B34708.15524021187551 (code B ref 34708); Tue, 12 Mar 2019 14:49:02 +0000 Original-Received: (at 34708) by debbugs.gnu.org; 12 Mar 2019 14:48:38 +0000 Original-Received: from localhost ([127.0.0.1]:40420 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1h3ihq-0001xi-3J for submit@debbugs.gnu.org; Tue, 12 Mar 2019 10:48:38 -0400 Original-Received: from userp2130.oracle.com ([156.151.31.86]:45066) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1h3iho-0001xU-6X for 34708@debbugs.gnu.org; Tue, 12 Mar 2019 10:48:36 -0400 Original-Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x2CEhxlB171164; Tue, 12 Mar 2019 14:48:30 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=RGdE8A51a4PymeodG1gSwY1YeO6x+7zerKBHEv3CQs4=; b=ObEwGlJlRGRqBjTXRDwq29lQlNCtLlxMm9Tdf0SmJqwfHZ5QQR/KM6AS927ZWkuU8cjX D88pQY6W0ftHVjI97mdOzg5wRtymK+7lPikZlUx2G1s7PMG9GgvcHbzjeulbx0PsHFNg bKgIj6j1M2c/Vm0B9Xtb7UIda6/10a8MZrwkovRz7Dg1P6hL9aCtnGS79l8PNNTh4tSZ hAoA9JooD5XLwJRpWzWAO2Eg/8vAXyChcETSpqYWT0CnINwNOgEhGasowcX8KmfRPOpi i8G9kQxcqn2G+qIT3oz9uMkjiWZjNnpwi0CcbmPd/yXjkVtzO+8nEBf9NpgKsTY+KLaB 4w== Original-Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp2130.oracle.com with ESMTP id 2r44wu54mr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 12 Mar 2019 14:48:29 +0000 Original-Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0021.oracle.com (8.14.4/8.14.4) with ESMTP id x2CEmSxJ026355 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 12 Mar 2019 14:48:29 GMT Original-Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x2CEmSQd029289; Tue, 12 Mar 2019 14:48:28 GMT In-Reply-To: <87ef7c1bxs.fsf@web.de> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4810.0 (x86)] X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9192 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1903120104 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 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.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:156262 Archived-At: > > If so, is `eql' really appropriate for most such cases (which are > > quite common)? > > > > And even for `(a . (1 2))', aka `(a 1 2)', is `eql' appropriate? > > Since the cdr of a list is more typically a list, why would we choose > > `eql' as the default value-comparison predicate? To compare lists the > > default predicate should be `equal' (or possibly but not likely `eq'), > > no? >=20 > Yes, in these cases eql is not useful. But they are the more common cases, I expect. The cdr of a list is typically a list, not an atom. And even for the elements of an alist I expect that is more typical: a list of values (as VALUE of a KEY) is more general and typically more useful than a single, atomic value. If this is the case then it's an argument for the default being set to `equal', not `eql'. > > > > > (2) The remove feature has a strange corner case. Normally the > > > > > first found association is removed, > > > > > > > > So "normally" it's really "remove one". > > > > > > > > Why is this? What's the point of REMOVE - why is > > > > it needed (added to the design) at all? Is it to > > > > provide a way to remove all entries with a given > > > > key or only the first such? > > > > > > The first. > > > > Then why did (does?) the doc say "if the new value > > is `eql' to DEFAULT"? It sounds like it removes > > only the entries with a given key AND a given value. >=20 > It removes the first entry with given KEY and value eql DEFAULT. [FYI: "The first such", above, meant the first entry with a given key - "such" refers to "entries with a given key". It doesn't mean the first entry with a given key and value. I guess I should have made that more explicit.] My question in that case is why REMOVE is made to work this way? Normally, alist element lookup/identification is by key only (or value only). To look up both key and value it's `member', not `assoc' (or `rassoc'). That's an operation on general list elements; it's not so much an alist operation. Why is removing an association different in this regard from adding or changing an association? Why does it need both key and value? I'm still having trouble grasping the point of having REMOVE in this construct. Seems like a ball of confusion and behavior not specifically related to alists. > > Anyway, if that's all REMOVE does (removes all > > occurrences), and if it can be a predicate, then it > > sounds like it just does `cl-delete-if'. > > > > If so, what's an example of why/when someone would > > want to use `setf' and `alist-get' to remove entries, > > as opposed to just using `cl-delete-if'? >=20 > You can also cl-delete-if, yes, there semantics overlap. OTOH > cl-delete-if doesn't support generalized variables. At any rate, that example was predicated on my wrong guess that REMOVE removes all, not just the first, identified instance, which you've now clarified is not the case. > > Then isn't it a bit misleading for the function name > > and doc to suggest that this is a general way of using > > alists? >=20 > I don't get that impression from the doc. For the name: what else would > you suggest? This _is_ the general way of getting associations from an > alist. You can also use it in place expressions where it is convenient, > you don't have to, of course. It's in the nature of place expressions > that there use is a bit limited compared to what you could do with > general lisp. I see no problem here. I find it misleading, but people can see things differently. Getting an association by both key and value is _not_ the general way of getting an alist association. Getting it by key only is the usual way. Getting it by value only is another, less common way. `alist-get' by itself seems to act normally wrt alists. But its use with `setf' and REMOVE doesn't seem, to me, to reflect the usual alist manipulation. =20 > > So far, I guess I don't see the use case for making it a generalized > > variable. It's easy enough to set alist values, and doing so with > > `setf' and `alist-get' sounds more complicated, not less. > > > > For getting, I think I get it: folks apparently don't want to get the > > full element and then dig out the value (cdr) from it. (Is there more > > to it than that?) For setting and removing, I don't get the > > advantage, so far. >=20 > You only seem to think of one case: I have a variable x which holds an > alist which I want to manipulate. There are more cases: the alist place > could be a real nontrivial place. How is that a different case? But maybe I don't have understand what you have in mind by a real nontrivial place. Presumably you're talking about an alist with complex elements? How does that change things? Could you give an example that shows what you mean? > And you can not only use setf on > alist-get places, but all macros that handle places, e.g. incf or callf > or letf or ... There are surely cases where using alist-get in a place > expression can be handy. Nowhere is said that you should use alist-get > only and always when dealing with alists, especially for manipulation. OK. An example would still help. The `setf' examples we've seen so far don't seem very helpful, to me. But maybe an example with some other `*f' place-manipulation functions would help understanding. I think it's mostly REMOVE that bothers me. I expect an alist "place" operation to set (create or update) an alist entry, not to remove an entry, and especially not by specifying that entry by both key and value. > > > One thing I don't find consistent is the case where the alist already > > > has multiple occurrences of a key. E.g. > > > > > > (setq my-alist '((a . 1) (b . 2) (a . -1))) > > > (setf (alist-get 'a my-alist 1 'remove) 1) > > > my-alist =3D=3D> ((b . 2) (a . -1)) > > > > > > (alist-get 'a my-alist 1) > > > =3D=3D> -1 (!) > > > > > > One would expect 1, of course. > > > > Why? The doc says that it returns DEFAULT only > > if KEY is not found in ALIST. But entry (a . -1) > > finds `a' associated with -1. What am I missing? >=20 > Think from the viewpoint of places: I have set the place to 1. Then I > expect that I get 1 when evaluating the place expression afterwards. You have _not_ set the place to 1, have you? The second 1, combined with REMOVE, doesn't set the place at all, does it? Doesn't REMOVE just remove the place altogether? I think that the REMOVE "feature" gets in the way of understanding here. I think you're agreeing, in a sense, by saying that the sexp gives the _impression_ that it sets the place to 1 without actually doing so. No? > > `alist-get' specifies an alist entry (a single one, BTW). `setf' of > > `alist-get' should set/create an alist entry (a single one, BTW). > > Otherwise, we're abusing the intention of one or both of these > > "functions". No? >=20 > I indeed see that point different, yes. The remove syntax when using it > as a place is not super sexy (no one says you have to use it for that > btw), but I don't see what you write as a requirement. When not using > REMOVE it's all very straightforward in my opinion. Let's consider just REMOVE then.