all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
To: Ivan Kanis <ivan.kanis@googlemail.com>
Cc: emacs help <help-gnu-emacs@gnu.org>
Subject: Re: defining a setter function with gv.el
Date: Mon, 27 Aug 2012 08:54:42 -0400	[thread overview]
Message-ID: <jwvlih0ld2j.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <87ehmsyj2b.fsf@googlemail.com> (Ivan Kanis's message of "Mon, 27 Aug 2012 07:56:12 +0200")

> I am very new to setf. I would like to write a function that provides a
> place for setf to work on an alist. It would be wonderful if the
> function also worked as a getter.

The idea of setf is that you can define a getter (foo ARGS) which return
the data you want and then you can explain to setf how (setf (foo ARGS) VAL)
should work such that after that (foo ARGS) returns VAL.

> (defun my-function (&optional value)
>   (if value
>       (?)
>     (cdr (assoc 'oak tree))))
> (my-function) => tree
> (my-function 'shrub)
> foo => '((oak . shrub))

So I think what you mean is that you want

  (my-function) => tree
  (setf (my-function) 'shrub)
  (my-function) => shrub

So the "setf expander" for `my-function' will tell `setf' what
(setf (my-function) 'shrub) should macro-expand to.
  
> gv.el seems to have what I need to implement the setf portion.
> It doesn't provide example and I couldn't find doc in the elisp info.

gv.el itself has plenty of examples, I think.  As for Elisp doc, they
indeed haven't been updated for it yet, but you might like to look at
the CL documentation and then read the beginning of gv.el to understand
how they 2 differ.

As for you specific question, I suspect that it is answered in the last
few lines of gv.el:

   ;;; Vaguely related definitions that should be moved elsewhere.
   
   ;; (defun alist-get (key alist)
   ;;   "Get the value associated to KEY in ALIST."
   ;;   (declare
   ;;    (gv-expander
   ;;     (lambda (do)
   ;;       (macroexp-let2 macroexp-copyable-p k key
   ;;         (gv-letplace (getter setter) alist
   ;;           (macroexp-let2 nil p `(assoc ,k ,getter)
   ;;             (funcall do `(cdr ,p)
   ;;                      (lambda (v)
   ;;                        `(if ,p (setcdr ,p ,v)
   ;;                           ,(funcall setter
   ;;                                     `(cons (cons ,k ,v) ,getter)))))))))))
   ;;   (cdr (assoc key alist)))
   
If you uncomment the above, then (alist-get KEY ALIST) will do the
obvious lookup and (setf (alist-get KEY ALIST) VAL) will do the expected
in-place modification of ALIST so that (alist-get KEY ALIST) then
returns VAL.


        Stefan



  reply	other threads:[~2012-08-27 12:54 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-27  5:56 defining a setter function with gv.el Ivan Kanis
2012-08-27 12:54 ` Stefan Monnier [this message]
2012-08-27 18:10   ` Ivan Kanis
2012-08-27 20:28     ` Stefan Monnier
2012-08-30 16:05       ` Ivan Kanis
2012-08-31  0:59         ` 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=jwvlih0ld2j.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=help-gnu-emacs@gnu.org \
    --cc=ivan.kanis@googlemail.com \
    /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.