all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Christopher Genovese <genovese.cr@gmail.com>
To: 10146@debbugs.gnu.org
Subject: bug#10146: error in aput in assoc.el, Emacs 24, 23, and 22 (at least)
Date: Sun, 27 Nov 2011 00:53:59 -0500	[thread overview]
Message-ID: <CAPum5Fg-MNb_LFqa5fUco2pxS0WbeSm743PLVFucOdYSD3La+g@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 3618 bytes --]

The function aput in assoc.el  (within lisp/emacs-lisp) has two errors.

1. In the third case of the cond (see original below), when the alist is not
    null, the key is already in the list (and thus at the head), and the
value is not null,
    the return value is incorrect.

    The original returns the result of the setcar -- that is, the new entry
-- rather than
    the modified alist as it should.

2. The documentation string indicates that nil is returned when the list is
nil,
    but this is incorrect. The modified list is returned, which will
include the
    new key-value pair.

I have included below, in order: 1) the original function for reference, 2)
a simple
case showing the problem, and 3) a fixed version of the function. Only two
minor changes are required.

(FWIW, I'm running on Mac OS X 10.5, Emacs 24 and 23 nextstep
and Emacs 22 carbon.)


;; Original version (from the current emacs24 trunk)

(defun aput (alist-symbol key &optional value)
  "Inserts a key-value pair into an alist.
The alist is referenced by ALIST-SYMBOL.  The key-value pair is made
from KEY and optionally, VALUE.  Returns the altered alist or nil if
ALIST is nil.

If the key-value pair referenced by KEY can be found in the alist, and
VALUE is supplied non-nil, then the value of KEY will be set to VALUE.
If VALUE is not supplied, or is nil, the key-value pair will not be
modified, but will be moved to the head of the alist.  If the key-value
pair cannot be found in the alist, it will be inserted into the head
of the alist (with value nil if VALUE is nil or not supplied)."
  (lexical-let ((elem (aelement key value))
        alist)
    (asort alist-symbol key)
    (setq alist (symbol-value alist-symbol))
    (cond ((null alist) (set alist-symbol elem))
      ((anot-head-p alist key) (set alist-symbol (nconc elem alist)))
      (value (setcar alist (car elem)))
      (t alist))))

;; Simple case illustrating the problem
(require 'assoc)
(progn
  (setq tmp-alist '((a . 1)
                    (b . 2)
                    (c . 3)
                    (d . 4)))
  (setq tmp-ret1
        (aput 'tmp-alist 'e 5))  ; no problem
  (prin1 tmp-ret1)

  (print "\n")

  (setq tmp-ret2
        (aput 'tmp-alist 'b 10))    ; oops
  (prin1 tmp-ret2))

;; Fixed version of the function
;;
;; Changes:
;;   + The `values' case of the cond needs to return the
;;     alist *not* the value returned by setcar
;;   + The docstring indicating the return value has been
;;     corrected. The original was inaccurate about the
;;     case where the alist is nil.
;;
;; Note this needs (require 'cl) as in assoc.el for lexical-let

(defun aput (alist-symbol key &optional value)
  "Inserts a key-value pair into an alist.
The alist is referenced by ALIST-SYMBOL.  The key-value pair is made
from KEY and optionally, VALUE.  Returns the altered alist.

If the key-value pair referenced by KEY can be found in the alist, and
VALUE is supplied non-nil, then the value of KEY will be set to VALUE.
If VALUE is not supplied, or is nil, the key-value pair will not be
modified, but will be moved to the head of the alist.  If the key-value
pair cannot be found in the alist, it will be inserted into the head
of the alist (with value nil if VALUE is nil or not supplied)."
  (lexical-let ((elem (aelement key value))
        alist)
    (asort alist-symbol key)
    (setq alist (symbol-value alist-symbol))
    (cond ((null alist)
           (set alist-symbol elem))
      ((anot-head-p alist key)
           (set alist-symbol (nconc elem alist)))
      (value
           (setcar alist (car elem))
           alist)
      (t alist))))

[-- Attachment #2: Type: text/html, Size: 4045 bytes --]

             reply	other threads:[~2011-11-27  5:53 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-11-27  5:53 Christopher Genovese [this message]
2011-12-05 22:26 ` bug#10146: error in aput in assoc.el, Emacs 24, 23, and 22 (at least) Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAPum5Fg-MNb_LFqa5fUco2pxS0WbeSm743PLVFucOdYSD3La+g@mail.gmail.com \
    --to=genovese.cr@gmail.com \
    --cc=10146@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.