help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Change a symbol's plist member with (let ...)?


From: Nicolas Richard
Subject: Re: Change a symbol's plist member with (let ...)?
Date: Sat, 15 Mar 2014 22:28:35 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux)

Thorsten Jolitz <tjolitz@gmail.com> 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.

-- 
Nico.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]