From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Stephen J. Turnbull" Newsgroups: gmane.emacs.devel Subject: Re: Replacement for `aput' from obsolete assoc.el? Date: Sat, 09 Jun 2012 17:59:05 +0900 Message-ID: <87mx4c97za.fsf@uwakimon.sk.tsukuba.ac.jp> References: <87txyrnhxi.fsf@web.de> <87oboytp45@ch.ristopher.com> <87haupwo6b.fsf@web.de> <871ulq44oj.fsf@gmail.com> <87pq9a7zab.fsf@uwakimon.sk.tsukuba.ac.jp> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 X-Trace: dough.gmane.org 1339232363 25190 80.91.229.3 (9 Jun 2012 08:59:23 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 9 Jun 2012 08:59:23 +0000 (UTC) Cc: emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Jun 09 10:59:22 2012 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1SdHVx-0006nr-Nd for ged-emacs-devel@m.gmane.org; Sat, 09 Jun 2012 10:59:21 +0200 Original-Received: from localhost ([::1]:41958 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SdHVx-0000ce-Lo for ged-emacs-devel@m.gmane.org; Sat, 09 Jun 2012 04:59:21 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:59825) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SdHVu-0000cW-BC for emacs-devel@gnu.org; Sat, 09 Jun 2012 04:59:19 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SdHVr-0007p0-Vq for emacs-devel@gnu.org; Sat, 09 Jun 2012 04:59:17 -0400 Original-Received: from mgmt1.sk.tsukuba.ac.jp ([130.158.97.223]:47577) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SdHVr-0007ob-Ev for emacs-devel@gnu.org; Sat, 09 Jun 2012 04:59:15 -0400 Original-Received: from uwakimon.sk.tsukuba.ac.jp (uwakimon.sk.tsukuba.ac.jp [130.158.99.156]) by mgmt1.sk.tsukuba.ac.jp (Postfix) with ESMTP id D31163FA0855; Sat, 9 Jun 2012 17:59:05 +0900 (JST) Original-Received: by uwakimon.sk.tsukuba.ac.jp (Postfix, from userid 1000) id 963FE1A355D; Sat, 9 Jun 2012 17:59:05 +0900 (JST) In-Reply-To: X-Mailer: VM 8.0.12-devo-585 under 21.5 (beta31) "ginger" b4715fcbe001 XEmacs Lucid (x86_64-unknown-linux) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 130.158.97.223 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 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-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:150849 Archived-At: Cleaned up the CC list. Stefan Monnier writes: > > It's precisely for this reason that XEmacs recommends plists over > > alists. Nobody will shoot you for using an alist, but plists do have > > a better API. > > Hmm... would you care to give some example? Of course, it's all a matter of taste; since you ask, I'll advocate mine. ;-) Analogous to `put' and `get' for symbols, disembodied plists are managed with `plist-put' and `plist-get'. (Except for the null plist, there would be no problem overloading `put' and `get', I think, but traditionalists strongly opposed that.) (plist-get (plist-put nil 'key 'value) 'key) => 'value `plist-put' and `plist-get' are actually defined in C, but this shows how `memq' works well with plists: (defun plist-get (plist key) (cadr (memq key plist))) `plist-put' and `plist-remprop' need to special-case the case where the key doesn't exist in the plist, so they're a bit ugly (you need temp variables or to evaluate the "get" twice, etc), but that's always the case in working with singly-linked lists. They look nice when printed, especially if the keys are keywords: (:top 10 :left 20 :height 25 :width 80) versus ((top . 10) (left . 20) (height . 25) (width . 80)) for alists (taking a little care to be fair to alists, which probably would not use keywords because the `:'s are just clutter). To my mind the improvement in style is only increased if the pairs are placed on separate lines. I suspect that many Lisp hackers would like alists just fine for cases where the values are naturally lists, though: ((stefan male canada professional) (stephen male japan dilettante)) although personally I still prefer the plist form (stefan (male canada professional) stephen (male japan dilettante)) especially when nested (stefan (:gender male :location canada :status professional) stephen (:gender male :location japan :status dilettante)) In an API, dunno exactly how emacs does this (I gather for one property/parameter `set-frame-parameter' is similar to XEmacs's `set-frame-property'), but setting several frame properties at once is a typical usage from XEmacs. Defaults are handled by variables containing plist (see the end of the following docstring). `set-frame-properties' is a built-in function -- loaded from "/playpen/src/XEmacs/xemacs/src/frame.c" (set-frame-properties FRAME PLIST) Documentation: Change some properties of a frame. PLIST is a property list. You can also change frame properties individually using `set-frame-property', but it may be more efficient to change many properties at once. Frame properties can be retrieved using `frame-property' or `frame-properties'. The following symbols etc. have predefined meanings: name Name of the frame. Used with X resources. Unchangeable after creation. height Height of the frame, in lines. width Width of the frame, in characters. minibuffer Gives the minibuffer behavior for this frame. Either t (frame has its own minibuffer), `only' (frame is a minibuffer-only frame), `none' (frame has no minibuffer) or a window (frame uses that window, which is on another frame, as the minibuffer). unsplittable If non-nil, frame cannot be split by `display-buffer'. current-display-table, menubar-visible-p, left-margin-width, right-margin-width, minimum-line-ascent, minimum-line-descent, use-left-overflow, use-right-overflow, scrollbar-width, scrollbar-height, default-toolbar, top-toolbar, bottom-toolbar, left-toolbar, right-toolbar, default-toolbar-height, default-toolbar-width, top-toolbar-height, bottom-toolbar-height, left-toolbar-width, right-toolbar-width, default-toolbar-visible-p, top-toolbar-visible-p, bottom-toolbar-visible-p, left-toolbar-visible-p, right-toolbar-visible-p, toolbar-buttons-captioned-p, top-toolbar-border-width, bottom-toolbar-border-width, left-toolbar-border-width, right-toolbar-border-width, modeline-shadow-thickness, has-modeline-p, default-gutter, top-gutter, bottom-gutter, left-gutter, right-gutter, default-gutter-height, default-gutter-width, top-gutter-height, bottom-gutter-height, left-gutter-width, right-gutter-width, default-gutter-visible-p, top-gutter-visible-p, bottom-gutter-visible-p, left-gutter-visible-p, right-gutter-visible-p, top-gutter-border-width, bottom-gutter-border-width, left-gutter-border-width, right-gutter-border-width, [Giving the name of any built-in specifier variable is equivalent to calling `set-specifier' on the specifier, with a locale of FRAME. Giving the name to `frame-property' calls `specifier-instance' on the specifier.] text-pointer-glyph, nontext-pointer-glyph, modeline-pointer-glyph, selection-pointer-glyph, busy-pointer-glyph, toolbar-pointer-glyph, menubar-pointer-glyph, scrollbar-pointer-glyph, gc-pointer-glyph, octal-escape-glyph, control-arrow-glyph, invisible-text-glyph, hscroll-glyph, truncation-glyph, continuation-glyph [Giving the name of any glyph variable is equivalent to calling `set-glyph-image' on the glyph, with a locale of FRAME. Giving the name to `frame-property' calls `glyph-image-instance' on the glyph.] [default foreground], [default background], [default font], [modeline foreground], [modeline background], [modeline font], etc. [Giving a vector of a face and a property is equivalent to calling `set-face-property' on the face and property, with a locale of FRAME. Giving the vector to `frame-property' calls `face-property-instance' on the face and property.] Finally, if a frame property symbol has the property `frame-property-alias' on it, then the value will be used in place of that symbol when looking up and setting frame property values. This allows you to alias one frame property name to another. See the variables `default-x-frame-plist', `default-tty-frame-plist' and `default-mswindows-frame-plist' for a description of the properties recognized for particular types of frames.