[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Moving between headers in message-mode
From: |
Pascal J. Bourguignon |
Subject: |
Re: Moving between headers in message-mode |
Date: |
Sat, 15 Jun 2013 20:22:03 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) |
Emanuel Berg <embe8573@student.uu.se> writes:
> "Pascal J. Bourguignon" <pjb@informatimago.com> writes:
>
> First, thanks *a lot*, however, your feedback is above me, I must
> admit. Perhaps, you can elaborate the four points below a bit? Or
> perhaps point me to related material?
>
>> I would factorize out the body ...
This is what I've done in the code I included in my message. Now, at
first the local function was named body, but then it's good also to try
to give more meaningful names to functions, even if they are local
functions.
Now, the first thing is that in simple cases, you could just use let:
Instead of:
(let (color)
(if prefixp
(setf color "red")
(setf color "blue"))
(set-foreground-color color)
(set-cursor-color color))
write:
(let ((color (if prefixp "red" "blue")))
(set-foreground-color color)
(set-cursor-color color))
but in your case, you have a lot of variables that depend on the same
condition, so it would be awkward to repeat it in all initialization
expressions.
Now one thing is that let is equivalent to an anonymous function call
(see: http://home.pipeline.com/~hbaker1/MetaCircular.html )
(let ((a e1)
(b e2)
(c e3))
(do-something-with a b c)
(and-something-with b c))
<=>
((lambda (a b c)
(do-something-with a b c)
(and-something-with b c))
e1 e2 e3)
Of course, we could just give a name to the function, and call it:
(defun body (a b c)
(do-something-with a b c)
(and-something-with b c))
(body e1 e2 e3)
or:
(if conditionp
(body e11 e21 e31)
(body e12 e22 e32))
But since your 'body' function is quite specific, there's no reason to
give it a global name. Hence using flet, to give it a local name.
>> Don't put spaces between openning or closing parentheses (you
>> may put a space between a closing and an opening one).
Have a look at:
http://labs.ariel-networks.com/cl-style-guide.html
http://mumble.net/~campbell/scheme/style.txt
http://google-styleguide.googlecode.com/svn/trunk/lispguide.xml
>> In general use paredit ...
It lets you mostly ignore those style questions, since emacs does almost
all the work for you.
http://www.emacswiki.org/emacs/ParEdit
http://www.emacswiki.org/emacs/PareditCheatsheet
http://mumble.net/~campbell/emacs/paredit.el
>> In general, try to avoid setq, you can only write better code if
>> you can avoid setq or setf. Of course, setf is often needed and
>> useful too, you have to know when ;-) But a (let (var) (setq var
>> expr)) is almost never a good expression.
setf does all that setq does, so you can just always use setf.
and you cannot do that with setq:
(let ((x (cons 1 2)))
(setf (car x) 42)
x)
--> (42 . 2)
this is equivalent to:
(let ((x (cons 1 2)))
(rplaca x 42)
x)
--> (42 . 2)
But setf is an operator that mutates variables or data objects. Of
course, the purpose of an editor is to mutate the state of a buffer, so
we're quite far from functional programming. Nonetheless, if you write
your emacs lisp code with a mostly functional programming style, it will
be good, since this has a lot of advantages:
http://www.emacswiki.org/emacs/FunctionalProgramming
http://c2.com/cgi/wiki?AdvantagesOfFunctionalProgramming
http://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
You know you've been lisping too long when you see a recent picture of George
Lucas and think "Wait, I thought John McCarthy was dead!" -- Dalek_Baldwin
Re: Moving between headers in message-mode, Stefan Monnier, 2013/06/19