From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Thorsten Jolitz Newsgroups: gmane.emacs.help Subject: Re: Change a symbol's plist member with (let ...)? Date: Sun, 16 Mar 2014 17:01:02 +0100 Message-ID: <87y50am8u9.fsf@gmail.com> References: <87wqfwo4yp.fsf@gmail.com> <87iorg31ie.fsf@yahoo.fr> <87siqko1tl.fsf@gmail.com> <87eh232lto.fsf@yahoo.fr> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1394985654 15580 80.91.229.3 (16 Mar 2014 16:00:54 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 16 Mar 2014 16:00:54 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sun Mar 16 17:01:02 2014 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 1WPDUj-0001YT-MN for geh-help-gnu-emacs@m.gmane.org; Sun, 16 Mar 2014 17:01:01 +0100 Original-Received: from localhost ([::1]:53704 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WPDUj-00051Y-Ay for geh-help-gnu-emacs@m.gmane.org; Sun, 16 Mar 2014 12:01:01 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:47419) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WPDTz-0004dS-QY for help-gnu-emacs@gnu.org; Sun, 16 Mar 2014 12:00:21 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WPDTq-0000zq-24 for help-gnu-emacs@gnu.org; Sun, 16 Mar 2014 12:00:15 -0400 Original-Received: from plane.gmane.org ([80.91.229.3]:36867) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WPDTp-0000xI-Sz for help-gnu-emacs@gnu.org; Sun, 16 Mar 2014 12:00:06 -0400 Original-Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1WPDTn-0000bh-AS for help-gnu-emacs@gnu.org; Sun, 16 Mar 2014 17:00:03 +0100 Original-Received: from g231232080.adsl.alicedsl.de ([92.231.232.80]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 16 Mar 2014 17:00:03 +0100 Original-Received: from tjolitz by g231232080.adsl.alicedsl.de with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 16 Mar 2014 17:00:03 +0100 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 63 Original-X-Complaints-To: usenet@ger.gmane.org X-Gmane-NNTP-Posting-Host: g231232080.adsl.alicedsl.de User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Cancel-Lock: sha1:+BZvm+cnsCtPww1WnOQLuskudsY= X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 80.91.229.3 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:96539 Archived-At: Nicolas Richard writes: > Thorsten Jolitz writes: >>> (letf (((get major-mode 'derived-mode-parent) 'special-mode)) >>> (derived-mode-p 'text-mode)) >>> returns nil. >> >> I have to get more involved with this cl stuff it seems ... > > This one is rather easy to understand. 'letf' does a temporary 'setf' > and then puts the previous value back. So what is 'setf' ? > > 'setf' is a generic way to *change* a value if you know how to *get* > that value. > > Example : if foo is a cons cell, you know how to get its car > : (car foo). Well, now (setf (car foo) 'bar) will change the car of foo > to 'bar. IOW, setf arranges so that the next invocations of (car foo) > will now return 'bar instead of its previous value. And it knows > internally how to do it : it uses 'setcar' : > (macroexpand '(setf (car foo) 'special-mode)) > => (let* ((v foo)) (setcar v (quote special-mode))) > (the surrounding let*-binding isn't needed in this case, is needed in > other cases, but let's ignore it.) > > So now : > (setf (get major-mode 'derived-mode-parent) 'special-mode) > simply arranges to change whatever is required so that (get major-mode > 'derived-mode-parent) will return 'special-mode. Internally, it knows > what to do : > (macroexpand '(setf (get major-mode 'derived-mode-parent) 'special-mode)) > gives : > (let* ((v major-mode)) (put v (quote derived-mode-parent) (quote special-mode))) > > And now if you want to do that temporarily, you use letf : letf will > arrange to revert the change upon exiting the letf form. > (macroexpand'(letf (((get major-mode 'derived-mode-parent) 'special-mode)) > (derived-mode-p 'text-mode))) > will give (I added comments) : > (let* ((v major-mode) > (old (get v (quote derived-mode-parent)))) ; save old value > (unwind-protect > (progn > (put v ; set new value > (quote derived-mode-parent) > (quote special-mode)) > (derived-mode-p ; run the body > (quote text-mode))) > (put v ; set old value back. > (quote derived-mode-parent) > old))) > > Simple, yet powerful. Interesting, thanks for the explanations! Amazing how intelligent this macro is ... I do have those Paul Graham CL books, and with these CL idioms becoming more standard in Elisp, I should take a second look at them I guess. -- cheers, Thorsten