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

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

Re: if vs. when vs. and: style question


From: Pascal J. Bourguignon
Subject: Re: if vs. when vs. and: style question
Date: Tue, 24 Mar 2015 01:15:06 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

Marcin Borkowski <address@hidden> writes:

> Hi there,
>
> assuming (e1) and (e2) are some expressions, all three forms:
>
> (if (e1) (e2))
>
> (when (e1) (e2))
>
> (and (e1) (e2))
>
> are semantically equivalent.  Which one is better style (and when)?
> I would guess that =when= is better iff (e2) is a =progn= (since we can
> drop the =progn= altogether, and this seems to be the point of =when=),
> and =and= might be considered better (well, maybe) by some people when
> both (e1) and (e2) are very short (though I personally would avoid that,
> since =if= seems easier for a human to understand at a first glance).
> Am I right?

In general, WHEN is better than IF.

Also, (unless (e1) (e2)) is better than (if (not (e1)) (e2)).

Notably, WHEN and UNLESS have an implicit progn:

   (when (e1)
     (e21)
     (e22)
     …
     (e2n))

I use IF only in ternary form:

  (if (etest)
    (ethen)
    (eelse))


AND is better when the result is boolean (and any result is always a
generalized boolean, right?).

I would use WHEN rather than AND in general, with a preference for WHEN
for procedural forms, and AND for resulting expressions:

   (defun get-it (key)
      (when (full-moon-p)
         (error "full moon"))
      (when (invalid-key-p key)
         (error "invalid key"))
      (and (exist-key-p key)
           (find-key key)))


Notably if you consider OR, it's quite idiomatic
to use it even for non-boolean (and notice that in CL, AND and OR return
multiple values too):

So you can typically have functions such as:

  (defun find-thingy (name)
    (or (find-thingy-in-whatcha name)
        (find-thingy-in-macall name)
        (find-thingy-in-it name)
        (error "not found")))

which is much more concise and clear than:

    (let ((thingy-found-in-whatcha (find-thingy-in-whatcha name)))
      (if thingy-found-in-whatcha
        thingy-found-in-whatcha
        (let ((thingy-found-in-macall (find-thingy-in-macall name)))
           (if thingy-found-in-macall
             thingy-found-in-macall
             (let ((thingy-found-in-it (find-thingy-in-macall name)))
               (if thingy-found-in-it
                 thingy-found-in-it
                 (error "not found")))))))

So much so that if I had to wrap those steps in other expressions, I
would write a macro similar to OR to do it and keep the find-thingy
function that simple.


So by analogy, using AND can be justified:

  (defun find-thingy (name)
    (and (valid-name-p name name)
         (exists-thingy-named name)
         (find-thing-or-create name)))

compared to the less concise:

  (defun find-thingy (name)
    (when (valid-name-p name name)
      (when (exists-thingy-named name)
         (find-thing-or-create name))))

or

  (defun find-thingy (name)
    (when (and (valid-name-p name name) 
               (exists-thingy-named name))
       (find-thing-or-create name)))


-- 
__Pascal Bourguignon__                 http://www.informatimago.com/
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk




reply via email to

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