unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* design ponderings: plist to alist
@ 2014-04-16  5:48 Thien-Thi Nguyen
  2014-04-16  8:16 ` Thorsten Jolitz
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Thien-Thi Nguyen @ 2014-04-16  5:48 UTC (permalink / raw)
  To: help-gnu-emacs


[-- Attachment #1.1: Type: text/plain, Size: 31 bytes --]

This fragment (from gnugo.el):

[-- Attachment #1.2: Type: application/emacs-lisp, Size: 994 bytes --]

[-- Attachment #1.3: Type: text/plain, Size: 678 bytes --]

includes a function to convert plist (succinct to humans) to alist
(succinct to computers).  I spent 20 minutes poking around the Emacs
source searching for something builtin, to no avail.  I saw a few cases
of the opposite direction (alist to plist) and many cases where plists
are walked at time of use (e.g., the C code for text-properties), so
maybe this is a hint that plist to alist (pre-use) is a net lose.  :-/

What do people think?

-- 
Thien-Thi Nguyen
   GPG key: 4C807502
   (if you're human and you know it)
      read my lisp: (responsep (questions 'technical)
                               (not (via 'mailing-list)))
                     => nil

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

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

* Re: design ponderings: plist to alist
  2014-04-16  5:48 design ponderings: plist to alist Thien-Thi Nguyen
@ 2014-04-16  8:16 ` Thorsten Jolitz
  2014-04-16  8:35   ` Thien-Thi Nguyen
  2014-04-16 10:04 ` Pascal J. Bourguignon
  2014-04-16 17:29 ` Stefan Monnier
  2 siblings, 1 reply; 6+ messages in thread
From: Thorsten Jolitz @ 2014-04-16  8:16 UTC (permalink / raw)
  To: help-gnu-emacs

Thien-Thi Nguyen <ttn@gnu.org> writes:

> includes a function to convert plist (succinct to humans) to alist
> (succinct to computers).  I spent 20 minutes poking around the Emacs
> source searching for something builtin, to no avail.  

Are you aware of package kv.el from Nic Ferrier?

,--------------------------------------------------------------------------------
| 43 matches for "^[[:space:]]*(def[maus][^elt][a-z]*\*? " in buffer: kv.el
|      37:(defun kvalist->hash (alist &rest hash-table-args)
|      48:(defun kvhash->alist (hash &optional func)
|      68:(defun kvfa (key alist receive)
|      77:(defun kva (key alist)
|      83:(defun kvaq (key alist)
|      89:(defun kvaqc (key alist)
|      97:(defun kvassoc= (key value alist)
|     107:(defun kvassoqc (key alist)
|     115:(defun kvassoq= (key value alist)
|     129:(defun kvmatch (key regex alist)
|     134:(defun* kvquery->func (query &key
|     177:(defun kvplist2get (plist2 keyword value)
|     183:(defun kvthing->keyword (str-or-symbol)
|     192:(defun kvalist->plist (alist)
|     201:(defun kvacons (&rest args)
|     205:(defun keyword->symbol (keyword)
|     213:(defun kvplist->alist (plist &optional keys-are-keywords)
|     228:(defun kvalist2->plist (alist2)
|     234:(defun kvalist->keys (alist)
|     238:(defun kvalist->values (alist)
|     242:(defun kvalist-sort (alist pred)
|     246:(defun kvalist-sort-by-value (alist pred)
|     250:(defun kvalist->filter-keys (alist &rest keys)
|     258:(defun kvplist->filter-keys (plist &rest keys)
|     273:(defun kvplist2->filter-keys (plist2 &rest keys)
|     278:(defun kvalist2->filter-keys (alist2 &rest keys)
|     283:(defun kvalist2->alist (alist2 car-key cdr-key &optional proper)
| 
|     317:(defun* kvalist-keys->symbols (alist &key (first-fn 'identity))
|     329:(defun kvalist2-filter (alist2 fn)
|     337:(defun kvidentity (a b)
|     341:(defun kvcar (a b)
|     345:(defun kvcdr (a b)
|     349:(defun kvcmp (a b)
|     356:(defun kvqsort (lst)
|     368:(defun kvalist-set-value! (alist key value)
|     378:(defun kvdotassoc-fn (expr table func)
|     412:(defun kvdotassoc (expr table)
|     416:(defun kvdotassq (expr table)
|     420:(defun kvdotassoc= (expr value table)
|     428:(defmacro kv--destructuring-map (map-function args sequence &rest body)
|     436:(defmacro kvmap-bind (args sexp seq)
|     449:(defun kvplist-merge (&rest plists)
`--------------------------------------------------------------------------------

-- 
cheers,
Thorsten




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

* Re: design ponderings: plist to alist
  2014-04-16  8:16 ` Thorsten Jolitz
@ 2014-04-16  8:35   ` Thien-Thi Nguyen
  0 siblings, 0 replies; 6+ messages in thread
From: Thien-Thi Nguyen @ 2014-04-16  8:35 UTC (permalink / raw)
  To: help-gnu-emacs

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

() Thorsten Jolitz <tjolitz@gmail.com>
() Wed, 16 Apr 2014 10:16:19 +0200

   Are you aware of package kv.el from Nic Ferrier?

Before, no, now, yes.  Thanks for the tip.

-- 
Thien-Thi Nguyen
   GPG key: 4C807502
   (if you're human and you know it)
      read my lisp: (responsep (questions 'technical)
                               (not (via 'mailing-list)))
                     => nil

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

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

* Re: design ponderings: plist to alist
  2014-04-16  5:48 design ponderings: plist to alist Thien-Thi Nguyen
  2014-04-16  8:16 ` Thorsten Jolitz
@ 2014-04-16 10:04 ` Pascal J. Bourguignon
  2014-04-16 17:20   ` Stefan Monnier
  2014-04-16 17:29 ` Stefan Monnier
  2 siblings, 1 reply; 6+ messages in thread
From: Pascal J. Bourguignon @ 2014-04-16 10:04 UTC (permalink / raw)
  To: help-gnu-emacs

Thien-Thi Nguyen <ttn@gnu.org> writes:

> This fragment (from gnugo.el):
>  (let ((root (gnugo--root-node)))
>    (cl-flet
>        ((r! (&rest plist)
>             (gnugo--decorate
>              root (loop                 ; hmm, available elsewhere?
>                    while plist
>                    collect (let* ((k (pop plist))
>                                   (v (pop plist)))
>                              (cons k v))))))
>      (r! :SZ board-size
>          :DT (format-time-string "%Y-%m-%d")
>          :RU (if (string-match "--chinese-rules" args)
>                  "Chinese"
>                "Japanese")
>          :AP (cons "gnugo.el" gnugo-version)
>          :KM komi)
>      (let ((gb (gnugo--blackp (gnugo-other user-color))))
>        (r! (if gb :PW :PB) (user-full-name)
>            (if gb :PB :PW) (concat "GNU Go " (gnugo-query "version"))))
>      (unless (zerop handicap)
>        (r! :HA handicap
>            :AB (mapcar (gnugo--as-cc-func)
>                        (gnugo-lsquery "fixed_handicap %d"
>                                       handicap))))))
> includes a function to convert plist (succinct to humans) to alist
> (succinct to computers).  


Actually, an a-list contains the same number of cons cells and requires
the same number of accesses as a p-list.  I wouldn't say it's more
succinct to computer than p-list.

There are only two places where lisp marks a preference to p-list rather
than a-list:

     - symbol-plist, get, (setf get)
     - &key parameter.



The only advantage of A-list, is that you can process entries
independently.  So if you have to move entries from place to place
or if you need to share them amongst several collections, it's
preferable to p-list where you would have to copy all the cons cells:

(let* ((a1 (list (cons :a 1) (cons :b 2) (cons :c 3)))
       (a2 (list (first a1) (cons :b 3) (third a1))))
  (setf (cdr (assoc :a a1)) 42)
  a2)
--> ((:a . 42) (:b . 3) (:c . 3))

This wouldn't be possible with p-list, since the cons cell containing 1
couldn't have two cdr cells, to (cdr a1) and to (cdr a2).

But if you don't need to extract, insert or mutate entries
_independently_, then p-list may be prefered since they can be used with
&key.


> I spent 20 minutes poking around the Emacs
> source searching for something builtin, to no avail.  I saw a few cases
> of the opposite direction (alist to plist) and many cases where plists
> are walked at time of use (e.g., the C code for text-properties), so
> maybe this is a hint that plist to alist (pre-use) is a net lose.  :-/


> What do people think?

This is not a popularity contest.

-- 
__Pascal Bourguignon__
http://www.informatimago.com/
"Le mercure monte ?  C'est le moment d'acheter !"




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

* Re: design ponderings: plist to alist
  2014-04-16 10:04 ` Pascal J. Bourguignon
@ 2014-04-16 17:20   ` Stefan Monnier
  0 siblings, 0 replies; 6+ messages in thread
From: Stefan Monnier @ 2014-04-16 17:20 UTC (permalink / raw)
  To: help-gnu-emacs

> Actually, an a-list contains the same number of cons cells and requires
> the same number of accesses as a p-list.  I wouldn't say it's more
> succinct to computer than p-list.

It's half the depth, tho, so you get twice as much "memory
parallelism".  And you avoid "parsing" the plist.  This means you can
use regular list operations like mapcar, delq, ...


        Stefan




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

* Re: design ponderings: plist to alist
  2014-04-16  5:48 design ponderings: plist to alist Thien-Thi Nguyen
  2014-04-16  8:16 ` Thorsten Jolitz
  2014-04-16 10:04 ` Pascal J. Bourguignon
@ 2014-04-16 17:29 ` Stefan Monnier
  2 siblings, 0 replies; 6+ messages in thread
From: Stefan Monnier @ 2014-04-16 17:29 UTC (permalink / raw)
  To: help-gnu-emacs

> includes a function to convert plist (succinct to humans) to alist
> (succinct to computers).  I spent 20 minutes poking around the Emacs
> source searching for something builtin, to no avail.  I saw a few cases
> of the opposite direction (alist to plist) and many cases where plists
> are walked at time of use (e.g., the C code for text-properties), so
> maybe this is a hint that plist to alist (pre-use) is a net lose.  :-/

> What do people think?

I dislike plists, so the only thing that would make some sense would be
some kind of macro.

(defmacro plist (&rest args)
  (let ((l '()))
    (while args
      (push '(cons ,(pop l) ,(pop l)) args))
    `(list ,@(nreverse l))))

Then you'd write

 (let ((root (gnugo--root-node)))
   (cl-flet ((r! (alist) (gnugo--decorate root alist)))
     (r! (plist :SZ board-size
                :DT (format-time-string "%Y-%m-%d")
                :RU (if (string-match "--chinese-rules" args)
                        "Chinese"
                      "Japanese")
                :AP (cons "gnugo.el" gnugo-version)
                :KM komi))
     (let ((gb (gnugo--blackp (gnugo-other user-color))))
       (r! (plist (if gb :PW :PB) (user-full-name)
                  (if gb :PB :PW) (concat "GNU Go " (gnugo-query "version")))))
     (unless (zerop handicap)
       (r! (plist :HA handicap
                  :AB (mapcar (gnugo--as-cc-func)
                              (gnugo-lsquery "fixed_handicap %d"
                                             handicap)))))))

which would also be more efficient by avoiding the &rest processing.


        Stefan


PS: Not sure why I chose "plist" for that macro's name: a bad choice.




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

end of thread, other threads:[~2014-04-16 17:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-16  5:48 design ponderings: plist to alist Thien-Thi Nguyen
2014-04-16  8:16 ` Thorsten Jolitz
2014-04-16  8:35   ` Thien-Thi Nguyen
2014-04-16 10:04 ` Pascal J. Bourguignon
2014-04-16 17:20   ` Stefan Monnier
2014-04-16 17:29 ` Stefan Monnier

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