From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.help Subject: Re: defining a setter function with gv.el Date: Mon, 27 Aug 2012 08:54:42 -0400 Message-ID: References: <87ehmsyj2b.fsf@googlemail.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1346072100 8827 80.91.229.3 (27 Aug 2012 12:55:00 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 27 Aug 2012 12:55:00 +0000 (UTC) Cc: emacs help To: Ivan Kanis Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Mon Aug 27 14:55:01 2012 Return-path: Envelope-to: geh-help-gnu-emacs@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 1T5yqH-0004lM-BS for geh-help-gnu-emacs@m.gmane.org; Mon, 27 Aug 2012 14:54:57 +0200 Original-Received: from localhost ([::1]:42384 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T5yqE-0005AY-Sx for geh-help-gnu-emacs@m.gmane.org; Mon, 27 Aug 2012 08:54:54 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:46368) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T5yq9-0005AM-31 for help-gnu-emacs@gnu.org; Mon, 27 Aug 2012 08:54:50 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T5yq7-0006Zo-Cx for help-gnu-emacs@gnu.org; Mon, 27 Aug 2012 08:54:49 -0400 Original-Received: from ironport2-out.teksavvy.com ([206.248.154.182]:51462) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T5yq7-0006Z7-8V for help-gnu-emacs@gnu.org; Mon, 27 Aug 2012 08:54:47 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EAG6Zu0/O+KG6/2dsb2JhbABEtBGBCIIVAQEEAVYjBQsLNBIUGA0kiBwFugmQRAOjM4FYgwU X-IronPort-AV: E=Sophos;i="4.75,637,1330923600"; d="scan'208";a="196799137" Original-Received: from 206-248-161-186.dsl.teksavvy.com (HELO pastel.home) ([206.248.161.186]) by ironport2-out.teksavvy.com with ESMTP/TLS/ADH-AES256-SHA; 27 Aug 2012 08:54:42 -0400 Original-Received: by pastel.home (Postfix, from userid 20848) id 2B74F59401; Mon, 27 Aug 2012 08:54:42 -0400 (EDT) In-Reply-To: <87ehmsyj2b.fsf@googlemail.com> (Ivan Kanis's message of "Mon, 27 Aug 2012 07:56:12 +0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2.50 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 206.248.154.182 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:86545 Archived-At: > 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