unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Replacement for `aput' from obsolete assoc.el?
@ 2012-06-04 16:46 Michael Heerdegen
  2012-06-05  3:27 ` Christopher Schmidt
  0 siblings, 1 reply; 19+ messages in thread
From: Michael Heerdegen @ 2012-06-04 16:46 UTC (permalink / raw)
  To: emacs-devel

Hello,

I make much use of `aput' from assoc.el in my .emacs.  It lets me modify
the value associated with a certain key in an alist, where keys are
compared with `equal'.

I often saw people reinventing this function who didn't yet know
assoc.el.  Now, assoc.el is obsolete.  I'm not against that, since there
were not many useful things in assoc.el besides `aput'.

But I wonder if there is a simple replacement for `aput' in vanilla
Emacs?  I don't think so, but maybe I have overseen something.

If not, can we add a new function `assoc-delete-all' to subr.el (which
would be like `assq-delete-all', but would compare keys with `equal'
instead of `eq')?  Dunno why this function does not exist yet, but it
would ease handling alists e.g. if its keys are strings.


Thanks,

Michael.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-04 16:46 Replacement for `aput' from obsolete assoc.el? Michael Heerdegen
@ 2012-06-05  3:27 ` Christopher Schmidt
  2012-06-05 17:43   ` Stefan Monnier
  0 siblings, 1 reply; 19+ messages in thread
From: Christopher Schmidt @ 2012-06-05  3:27 UTC (permalink / raw)
  To: emacs-devel

Michael Heerdegen <michael_heerdegen@web.de> writes:

> But I wonder if there is a simple replacement for `aput' in vanilla
> Emacs?  I don't think so, but maybe I have overseen something.
>
> If not, can we add a new function `assoc-delete-all' to subr.el (which
> would be like `assq-delete-all', but would compare keys with `equal'
> instead of `eq')?  Dunno why this function does not exist yet, but it
> would ease handling alists e.g. if its keys are strings.

You can use the Common Lisp subset provided by cl.*\.el.

    (push '(key . emacs) alist)
    (setf (cdr (assoc 'key alist)) 'rms)
    (setf alist (delete* 'key alist :test 'equal :key 'car))

Starting with GNU Emacs 24.2 you are allowed to use the cl functions in
end-user code.  See <jwvehpvtdnb.fsf-monnier+emacs@gnu.org> for more
information.

        Christopher



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-05  3:27 ` Christopher Schmidt
@ 2012-06-05 17:43   ` Stefan Monnier
  2012-06-05 19:31     ` Michael Heerdegen
  0 siblings, 1 reply; 19+ messages in thread
From: Stefan Monnier @ 2012-06-05 17:43 UTC (permalink / raw)
  To: emacs-devel

>> But I wonder if there is a simple replacement for `aput' in vanilla
>> Emacs?  I don't think so, but maybe I have overseen something.

Usually, for alists, you can do:

 (push (cons key val) alist)

If you want to do it via side-effects, then it largely depends on what
kind of "alist" this is.  If you know the key is already in there, you
can do

  (setcdr (assoc key alist) val)
 
>> instead of `eq')?  Dunno why this function does not exist yet, but it
>> would ease handling alists e.g. if its keys are strings.

Using side-effects on alists is often a bad idea.

> Starting with GNU Emacs 24.2 you are allowed to use the cl functions in
> end-user code.

Now that's a confusing statement:
- CL functions have always been allowed in end-user code (and third
  party packages for that matter).  Being the "canonical" Free Software,
  Emacs is usually not in the business of disallowing its users to do
  whatever they want.
- Code bundled with Emacs-24.2 is still not "allowed" to use the CL
  function you showed (i.e. `delete*').  It can require the new `cl-lib'
  and use `cl-delete' instead, tho.


        Stefan



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-05 17:43   ` Stefan Monnier
@ 2012-06-05 19:31     ` Michael Heerdegen
  2012-06-05 22:52       ` Stefan Monnier
  2012-06-08  7:57       ` Vitalie Spinu
  0 siblings, 2 replies; 19+ messages in thread
From: Michael Heerdegen @ 2012-06-05 19:31 UTC (permalink / raw)
  To: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> Usually, for alists, you can do:
>
>  (push (cons key val) alist)
>
> If you want to do it via side-effects, then it largely depends on what
> kind of "alist" this is.  If you know the key is already in there, you
> can do
>
>   (setcdr (assoc key alist) val)

So I think I want something like that:

(defun my-aput (alist-sym key val)
  (let ((cons (assoc key (symbol-value alist-sym))))
    (if cons (setcdr cons val) (push (cons key val) (symbol-value alist-sym)))))

  
> >> instead of `eq')?  Dunno why this function does not exist yet, but it
> >> would ease handling alists e.g. if its keys are strings.
>
> Using side-effects on alists is often a bad idea.

Why?  I do this very often in my .emacs.  For example:


--8<---------------cut here---------------start------------->8---
(aput 'find-constituents 'readable (list 0))

(eval-after-load "linkd"
  '(aput 'minor-mode-alist 'linkd-mode '(" Ld")))

(aput 'default-frame-alist 'width 104)

(aput 'warning-suppress-types 'undo '(discard-info))

(aput 'auto-mode-alist "\\.v?dired\\'" 'dired-virtual-mode)

(aput 'org-show-siblings 'org-goto t)

(aput 'w3m-search-engine-alist
          "duckduckgo" '("http://duckduckgo.com/?q=%s"))
--8<---------------cut here---------------end--------------->8---


Is it a bad idea in these cases?


> - Code bundled with Emacs-24.2 is still not "allowed" to use the CL
>   function you showed (i.e. `delete*').  It can require the new `cl-lib'
>   and use `cl-delete' instead, tho.

Will it be ok to require cl-lib at run-time in third-party packages?
That would be great.


Thanks,

Michael.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-05 19:31     ` Michael Heerdegen
@ 2012-06-05 22:52       ` Stefan Monnier
  2012-06-08  7:57       ` Vitalie Spinu
  1 sibling, 0 replies; 19+ messages in thread
From: Stefan Monnier @ 2012-06-05 22:52 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel

>> Using side-effects on alists is often a bad idea.
> Why?  I do this very often in my .emacs.  For example:

Because a lot of code assumes alists are used in a "pure" way.

> --8<---------------cut here---------------start------------->8---
> (aput 'find-constituents 'readable (list 0))
> (eval-after-load "linkd"
>   '(aput 'minor-mode-alist 'linkd-mode '(" Ld")))
> (aput 'default-frame-alist 'width 104)
> (aput 'warning-suppress-types 'undo '(discard-info))
> (aput 'auto-mode-alist "\\.v?dired\\'" 'dired-virtual-mode)
> (aput 'org-show-siblings 'org-goto t)
> (aput 'w3m-search-engine-alist
>           "duckduckgo" '("http://duckduckgo.com/?q=%s"))
> --8<---------------cut here---------------end--------------->8---

> Is it a bad idea in these cases?

AFAICT, (push (cons key val) foo) would work just as well in those cases.

> Will it be ok to require cl-lib at run-time in third-party packages?

Requiring `cl' has been allowed for ever in third party packages (as if
we could disallow it, anyway).
What is new is that require `cl-lib' is OK in non-third-party packages.


        Stefan



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-05 19:31     ` Michael Heerdegen
  2012-06-05 22:52       ` Stefan Monnier
@ 2012-06-08  7:57       ` Vitalie Spinu
  2012-06-08 12:39         ` Stephen J. Turnbull
  1 sibling, 1 reply; 19+ messages in thread
From: Vitalie Spinu @ 2012-06-08  7:57 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel


  > So I think I want something like that:

  > (defun my-aput (alist-sym key val)
  >   (let ((cons (assoc key (symbol-value alist-sym))))
  >     (if cons (setcdr cons val) (push (cons key val) (symbol-value alist-sym)))))

  >> >> instead of `eq')?  Dunno why this function does not exist yet, but it
  >> >> would ease handling alists e.g. if its keys are strings.
  >> 
  >> Using side-effects on alists is often a bad idea.

  > Why?  I do this very often in my .emacs.  For example:


This is essential. A lot of packages store settings in alists, and there
is no handy function to alter the values inside those. 

I wish for a `setq-within':

(setq-within object
   name1 value1
   name2 value2
   ...
 )

where OBJECT is any dict-like container - alist, plist or
hash-table. 

Doesn't this make sense as a base emacs functionality?

Thanks, 
Vitalie.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-08  7:57       ` Vitalie Spinu
@ 2012-06-08 12:39         ` Stephen J. Turnbull
  2012-06-08 19:50           ` Stefan Monnier
  0 siblings, 1 reply; 19+ messages in thread
From: Stephen J. Turnbull @ 2012-06-08 12:39 UTC (permalink / raw)
  To: Vitalie Spinu; +Cc: Michael Heerdegen, emacs-devel

Vitalie Spinu writes:

 > This is essential. A lot of packages store settings in alists, and there
 > is no handy function to alter the values inside those. 

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.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-08 12:39         ` Stephen J. Turnbull
@ 2012-06-08 19:50           ` Stefan Monnier
  2012-06-09  8:59             ` Stephen J. Turnbull
  0 siblings, 1 reply; 19+ messages in thread
From: Stefan Monnier @ 2012-06-08 19:50 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Michael Heerdegen, Vitalie Spinu, emacs-devel

>> This is essential. A lot of packages store settings in alists, and there
>> is no handy function to alter the values inside those. 
> 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?


        Stefan "who doesn't like plists much, but must recognize he's not
                very familiar with their API"



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-08 19:50           ` Stefan Monnier
@ 2012-06-09  8:59             ` Stephen J. Turnbull
  2012-06-09  9:46               ` Andreas Schwab
                                 ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: Stephen J. Turnbull @ 2012-06-09  8:59 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

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.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-09  8:59             ` Stephen J. Turnbull
@ 2012-06-09  9:46               ` Andreas Schwab
  2012-06-09 10:13                 ` Thien-Thi Nguyen
  2012-06-09 16:11                 ` Drew Adams
  2012-06-09 11:32               ` Vitalie Spinu
                                 ` (2 subsequent siblings)
  3 siblings, 2 replies; 19+ messages in thread
From: Andreas Schwab @ 2012-06-09  9:46 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Stefan Monnier, emacs-devel

"Stephen J. Turnbull" <stephen@xemacs.org> writes:

> `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)))

That fails if key is eq to a value.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-09  9:46               ` Andreas Schwab
@ 2012-06-09 10:13                 ` Thien-Thi Nguyen
  2012-06-10 12:11                   ` Stephen J. Turnbull
  2012-06-09 16:11                 ` Drew Adams
  1 sibling, 1 reply; 19+ messages in thread
From: Thien-Thi Nguyen @ 2012-06-09 10:13 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Stephen J. Turnbull, Stefan Monnier, emacs-devel

() Andreas Schwab <schwab@linux-m68k.org>
() Sat, 09 Jun 2012 11:46:38 +0200

   "Stephen J. Turnbull" <stephen@xemacs.org> writes:

   > `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)))

   That fails if key is eq to a value.

That is, a value closer to the plist head than the desired key.
(If after, no worries.)



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-09  8:59             ` Stephen J. Turnbull
  2012-06-09  9:46               ` Andreas Schwab
@ 2012-06-09 11:32               ` Vitalie Spinu
  2012-06-10 12:53                 ` Stephen J. Turnbull
  2012-06-09 16:10               ` Drew Adams
  2012-06-10  0:52               ` Stefan Monnier
  3 siblings, 1 reply; 19+ messages in thread
From: Vitalie Spinu @ 2012-06-09 11:32 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Stefan Monnier, emacs-devel

  >> "Stephen J. Turnbull" <stephen@xemacs.org>
  >> on Sat, 09 Jun 2012 17:59:05 +0900 wrote:

  > Analogous to `put' and `get' for symbols, disembodied plists are
  > managed with `plist-put' and `plist-get'.  

There is no way to associate multiple values at once. What is the
canonical way to do that?

Assume FOO and BAR are plists. You want values of FOO set into BAR. The
best I can think of is:

   
   (setq
    FOO '(:a 1 :b 2)
    BAR '(:b 3 :c 4))
   
   (loop for X on FOO  by 'cddr
         do (setq BAR (plist-put BAR (car X) (cadr X))))
   
   BAR
   (:b 2 :c 4 :a 1)


And for a setq like macro:
   
   
   (defmacro plist-put* (plist &rest body)
     "Like `plist-put' but allows multiple pairs. 
   
   \(fn PLIST [PROP VALUE] ...)"
     (declare (indent defun))
     `(let ((PL ,plist)
   	 (VALS ',body))
        (loop for X on VALS by 'cddr
   	   do (setq PL (plist-put PL (car X) (eval (cadr X)))))
        PL))
   
   (plist-put* FOO
     :d 5
     :e (+ 100 50))
   
   ==>
    (:a 1 :b 2 :d 5 :e 150)


I find reasonable that this sort of functionality be in the core for all
available containers. FWIW, for text properties there are `propertize'
and `set-text-properties' which don't have an uniform interface.

Vitalie.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: Replacement for `aput' from obsolete assoc.el?
  2012-06-09  8:59             ` Stephen J. Turnbull
  2012-06-09  9:46               ` Andreas Schwab
  2012-06-09 11:32               ` Vitalie Spinu
@ 2012-06-09 16:10               ` Drew Adams
  2012-06-10  0:52               ` Stefan Monnier
  3 siblings, 0 replies; 19+ messages in thread
From: Drew Adams @ 2012-06-09 16:10 UTC (permalink / raw)
  To: 'Stephen J. Turnbull', 'Stefan Monnier'; +Cc: emacs-devel

> In an API, dunno exactly how emacs does this..., but setting
> several frame properties at once is a typical usage from XEmacs.
...
> (set-frame-properties FRAME PLIST)
> Change some properties of a frame.
> PLIST is a property list.

See GNU Emacs function `modify-frame-parameters'.
You pass it an alist, not a plist.

And an alist of frame parameters is what you get from function
`frame-parameters'.  

And an alist of frame parameters is the value of user options such as
`default-frame-alist'.

And yes, since Emacs uses alists for frame parameters you can take advantage (or
disadvantage) of shadowing frame-parameter values.





^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: Replacement for `aput' from obsolete assoc.el?
  2012-06-09  9:46               ` Andreas Schwab
  2012-06-09 10:13                 ` Thien-Thi Nguyen
@ 2012-06-09 16:11                 ` Drew Adams
  2012-06-09 16:17                   ` Drew Adams
  1 sibling, 1 reply; 19+ messages in thread
From: Drew Adams @ 2012-06-09 16:11 UTC (permalink / raw)
  To: 'Stephen J. Turnbull'; +Cc: emacs-devel

Alists and plists each have their advantages.

The main difference is mentioned in (elisp) `Plists and Alists':

 In contrast to association lists, the order of the pairs
 in the property list is not significant since the property
 names must be distinct.

That gives alists the ability to shadow associations.

 An association list may be used like a stack where associations
 are pushed on the front of the list and later discarded...

And it means that:

 All properties for a symbol are stored in the same property
 list, so there is a possibility of a conflict between different
 uses of a property name.

[But sure, you could use a plist as a stack, with shadowing, by defining your
own accessor etc.  It's just a list, after all.  But `plist-get' and `get' do
not act that way.]

The advantage for plists pointed out in that doc section is that plists are what
you get with symbols - they are built in.  It contrasts a global alist with the
plists associated with individual symbols.

[But that's just the way things are designed.  Lisp could be/have been designed
with individual symbols having asssociated alists instead of plists.]

Here is another typical difference (from (elisp) `Association Lists'):

 Both the values and the keys in an alist may be any Lisp
 objects. For example, in the following alist, the symbol
 `a' is associated with the number `1', and the string `"b"'
 is associated with the _list_ `(2 3)', which is the CDR of
 the alist element: ((a . 1) ("b" 2 3))

[But again, a plist too could use anything as a key, provided you roll your own
accessor.  But `plist-get' and `get' use `eq' comparison.]

In short, each is just a list; each is general enough to replace the other.  But
to do so means going beyond the usual accessors etc.  And in the case of symbol
properties it would require a different Lisp implementation (or some indirection
hack).




^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: Replacement for `aput' from obsolete assoc.el?
  2012-06-09 16:11                 ` Drew Adams
@ 2012-06-09 16:17                   ` Drew Adams
  0 siblings, 0 replies; 19+ messages in thread
From: Drew Adams @ 2012-06-09 16:17 UTC (permalink / raw)
  To: 'Stephen J. Turnbull'; +Cc: emacs-devel

> [But again, a plist too could use anything as a key, provided 
>  you roll your own accessor.  But `plist-get' and `get' use `eq' comparison.]

Actually, Emacs now (22+) has `lax-plist-(get|put)' (which should probably have
been named `plist-(get|put)-lax').  So someone clearly thought s?he needed that.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-09  8:59             ` Stephen J. Turnbull
                                 ` (2 preceding siblings ...)
  2012-06-09 16:10               ` Drew Adams
@ 2012-06-10  0:52               ` Stefan Monnier
  2012-06-10 13:48                 ` Stephen J. Turnbull
  3 siblings, 1 reply; 19+ messages in thread
From: Stefan Monnier @ 2012-06-10  0:52 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: emacs-devel

>> > 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. ;-)

I didn't see much ion their which addresses the issue of setting
elements in plists (other than plist-put which doesn't seem to be
significantly better than (push (cons a b) c)).


        Stefan



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-09 10:13                 ` Thien-Thi Nguyen
@ 2012-06-10 12:11                   ` Stephen J. Turnbull
  0 siblings, 0 replies; 19+ messages in thread
From: Stephen J. Turnbull @ 2012-06-10 12:11 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: Andreas Schwab, Stefan Monnier, emacs-devel

Thien-Thi Nguyen writes:
 > () Andreas Schwab <schwab@linux-m68k.org>
 > () Sat, 09 Jun 2012 11:46:38 +0200
 > 
 >    "Stephen J. Turnbull" <stephen@xemacs.org> writes:
 > 
 >    > `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)))
 > 
 >    That fails if key is eq to a value.
 > 
 > That is, a value closer to the plist head than the desired key.
 > (If after, no worries.)

True, but of course it's a bug.  My bad.

In practice the idiom `(memq key plist)' is sometimes useful where
keys are guaranteed to be disjoint from values.  I shouldn't have
tried to overgeneralize.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-09 11:32               ` Vitalie Spinu
@ 2012-06-10 12:53                 ` Stephen J. Turnbull
  0 siblings, 0 replies; 19+ messages in thread
From: Stephen J. Turnbull @ 2012-06-10 12:53 UTC (permalink / raw)
  To: Vitalie Spinu; +Cc: Stefan Monnier, emacs-devel

Vitalie Spinu writes:

 > There is no way to associate multiple values at once. What is the
 > canonical way to do that?

I don't see such a great need for it.  The loop idiom you propose is
fine (except that I suppose in GNU Emacs you need to use `cl-loop', at
least in core).  In XEmacs, the canonical destructive idiom is

    (setq plist (canonicalize-lax-plist (nconc plist-new plist)))

which gives preference to entries in plist-new, and would be more
efficient (all of the functions are primitives implemented in C).

 > I find reasonable that this sort of functionality be in the core for all
 > available containers.

Reasonable, in some sense, yes.  That probably would pass in Common
Lisp, but as you're probably aware Emacs Lisp prefers simplicity over
generality for generality's sake.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Replacement for `aput' from obsolete assoc.el?
  2012-06-10  0:52               ` Stefan Monnier
@ 2012-06-10 13:48                 ` Stephen J. Turnbull
  0 siblings, 0 replies; 19+ messages in thread
From: Stephen J. Turnbull @ 2012-06-10 13:48 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Stefan Monnier writes:

 > I didn't see much ion their which addresses the issue of setting
 > elements in plists (other than plist-put which doesn't seem to be
 > significantly better than (push (cons a b) c)).

Multiple pair updates?  As Drew points out, a plist can be treated
like a stack in the same way as an alist.  For lax plists, `nconc'
works, and if you need a true plist, canonicalize-lax-plist is
efficient.

But really, it's a matter of style.



^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2012-06-10 13:48 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-04 16:46 Replacement for `aput' from obsolete assoc.el? Michael Heerdegen
2012-06-05  3:27 ` Christopher Schmidt
2012-06-05 17:43   ` Stefan Monnier
2012-06-05 19:31     ` Michael Heerdegen
2012-06-05 22:52       ` Stefan Monnier
2012-06-08  7:57       ` Vitalie Spinu
2012-06-08 12:39         ` Stephen J. Turnbull
2012-06-08 19:50           ` Stefan Monnier
2012-06-09  8:59             ` Stephen J. Turnbull
2012-06-09  9:46               ` Andreas Schwab
2012-06-09 10:13                 ` Thien-Thi Nguyen
2012-06-10 12:11                   ` Stephen J. Turnbull
2012-06-09 16:11                 ` Drew Adams
2012-06-09 16:17                   ` Drew Adams
2012-06-09 11:32               ` Vitalie Spinu
2012-06-10 12:53                 ` Stephen J. Turnbull
2012-06-09 16:10               ` Drew Adams
2012-06-10  0:52               ` Stefan Monnier
2012-06-10 13:48                 ` Stephen J. Turnbull

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).