From: J.C. Roberts
Subject: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <t15om15k8qe8v20as5dr2to5hm6lqkb40d@4ax.com>
If you need to do more than one thing in the THEN and ELSE portions of
the IF-THEN-ELSE (i.e. procedural with side-effects), what are the
approaches that can be used in CommonLisp to evaluate multiple
statements?

For example, using (list ...) works but I'm curious if there is a more
conventional/accepted/common or better performance way of doing it?

(defun RELEASER ()
  (if (= (length EXT:*ARGS*) 0)
    (list
      (format t "~%~A~%" "Nope, No Command Line Args Were Provided")
      (show-usage)
      (return-from RELEASER))
    (list
      (format t "~%~A~%" "Yep, We've Got Command Line Args")
      (format t "~%~A~%" "Processing Args..."))
      ; more stuff...
      ))

I looked for a treatment of this in "Practical Common Lisp" (Peter
Seibel) and "Successful Lisp" (David Lamkins) but found nothing.

Thanks,
JCR

From: Tayssir John Gabbour
Subject: Re: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <1131157743.312305.44960@g49g2000cwa.googlegroups.com>
J. C. Roberts NO_SPAM wrote:
> If you need to do more than one thing in the THEN and ELSE portions of
> the IF-THEN-ELSE (i.e. procedural with side-effects), what are the
> approaches that can be used in CommonLisp to evaluate multiple
> statements?
>
> For example, using (list ...) works but I'm curious if there is a more
> conventional/accepted/common or better performance way of doing it?
>
> (defun RELEASER ()
>   (if (= (length EXT:*ARGS*) 0)
>     (list
>       (format t "~%~A~%" "Nope, No Command Line Args Were Provided")
>       (show-usage)
>       (return-from RELEASER))
>     (list
>       (format t "~%~A~%" "Yep, We've Got Command Line Args")
>       (format t "~%~A~%" "Processing Args..."))
>       ; more stuff...
>       ))

PROGN.
http://www.lisp.org/HyperSpec/Body/speope_progn.html

Yes, the clearly named PROGN, I'm sure anyone can guess what it does by
the name... ;) Here's a cute little history on it...
http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node91.html

Tayssir
From: J.C. Roberts
Subject: Re: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <gf6om11ted5tridpmlso2utp5aa14cdtde@4ax.com>
On 4 Nov 2005 18:29:03 -0800, "Tayssir John Gabbour"
<···········@yahoo.com> wrote:

>J. C. Roberts NO_SPAM wrote:
>> If you need to do more than one thing in the THEN and ELSE portions of
>> the IF-THEN-ELSE (i.e. procedural with side-effects), what are the
>> approaches that can be used in CommonLisp to evaluate multiple
>> statements?
>>
>> For example, using (list ...) works but I'm curious if there is a more
>> conventional/accepted/common or better performance way of doing it?
>>
>> (defun RELEASER ()
>>   (if (= (length EXT:*ARGS*) 0)
>>     (list
>>       (format t "~%~A~%" "Nope, No Command Line Args Were Provided")
>>       (show-usage)
>>       (return-from RELEASER))
>>     (list
>>       (format t "~%~A~%" "Yep, We've Got Command Line Args")
>>       (format t "~%~A~%" "Processing Args..."))
>>       ; more stuff...
>>       ))
>
>PROGN.
>http://www.lisp.org/HyperSpec/Body/speope_progn.html
>
>Yes, the clearly named PROGN, I'm sure anyone can guess what it does by
>the name... ;) Here's a cute little history on it...
>http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node91.html
>
>Tayssir

So even when you have no need to use vars or tags, PROGN is the
correct/efficient way to simply execute a set of statements?

(defun RELEASER ()
  (if (= (length EXT:*ARGS*) 0)
    (progn
      (format t "~%~A~%" "Nope, No Command Line Args Were Provided")
      (show-usage)
      (return-from RELEASER))
    (progn
      (format t "~%~A~%" "Yep, We've Got Command Line Args")
      (format t "~%~A~%" "Processing Args...")
      ; more stuff...
    )
)

Even with the docs, I never would have guessed PROGN. ;-)

Thanks,
JCR
From: Tayssir John Gabbour
Subject: Re: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <1131163380.544953.270540@g47g2000cwa.googlegroups.com>
J.C. Roberts (NO_SPAM) wrote:
> On 4 Nov 2005 18:29:03 -0800, "Tayssir John Gabbour"
> <···········@yahoo.com> wrote:
>
> >J. C. Roberts NO_SPAM wrote:
> >> If you need to do more than one thing in the THEN and ELSE portions of
> >> the IF-THEN-ELSE (i.e. procedural with side-effects), what are the
> >> approaches that can be used in CommonLisp to evaluate multiple
> >> statements?
> >>
> >> For example, using (list ...) works but I'm curious if there is a more
> >> conventional/accepted/common or better performance way of doing it?
> >>
> >> (defun RELEASER ()
> >>   (if (= (length EXT:*ARGS*) 0)
> >>     (list
> >>       (format t "~%~A~%" "Nope, No Command Line Args Were Provided")
> >>       (show-usage)
> >>       (return-from RELEASER))
> >>     (list
> >>       (format t "~%~A~%" "Yep, We've Got Command Line Args")
> >>       (format t "~%~A~%" "Processing Args..."))
> >>       ; more stuff...
> >>       ))
> >
> >PROGN.
> >http://www.lisp.org/HyperSpec/Body/speope_progn.html
> >
> >Yes, the clearly named PROGN, I'm sure anyone can guess what it does by
> >the name... ;) Here's a cute little history on it...
> >http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node91.html
> >
> >Tayssir
>
> So even when you have no need to use vars or tags, PROGN is the
> correct/efficient way to simply execute a set of statements?

Yes. In fact, PROGN has nothing to do with vars or tags, quite a simple
operator.


Tayssir
From: Tayssir John Gabbour
Subject: Re: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <1131164655.380748.102230@g49g2000cwa.googlegroups.com>
J.C. Roberts (NO_SPAM) wrote:
> On 4 Nov 2005 18:29:03 -0800, "Tayssir John Gabbour"
> <···········@yahoo.com> wrote:
> So even when you have no need to use vars or tags, PROGN is the
> correct/efficient way to simply execute a set of statements?
>
> (defun RELEASER ()
>   (if (= (length EXT:*ARGS*) 0)
>     (progn
>       (format t "~%~A~%" "Nope, No Command Line Args Were Provided")
>       (show-usage)
>       (return-from RELEASER))
>     (progn
>       (format t "~%~A~%" "Yep, We've Got Command Line Args")
>       (format t "~%~A~%" "Processing Args...")
>       ; more stuff...
>     )
> )
>
> Even with the docs, I never would have guessed PROGN. ;-)

Oh, and keep in mind that many people prefer the following style
instead, as it probably makes intention clearer:

(defun RELEASER ()
  (when (= (length EXT:*ARGS*) 0)
    (format t "~%~A~%" "Nope, No Command Line Args Were Provided")
    (show-usage)
    (return-from RELEASER))

  (format t "~%~A~%" "Yep, We've Got Command Line Args")
  (format t "~%~A~%" "Processing Args...")
  ;; more stuff...
  )


Tayssir
From: Rob Warnock
Subject: Re: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <LcmdnWpaid8wqPHenZ2dnUVZ_tednZ2d@speakeasy.net>
Tayssir John Gabbour <···········@yahoo.com> wrote:
+---------------
| Oh, and keep in mind that many people prefer the following style
| instead, as it probably makes intention clearer:
| 
| (defun RELEASER ()
|   (when (= (length EXT:*ARGS*) 0)
|     (format t "~%~A~%" "Nope, No Command Line Args Were Provided")
|     (show-usage)
|     (return-from RELEASER))
| 
|   (format t "~%~A~%" "Yep, We've Got Command Line Args")
|   (format t "~%~A~%" "Processing Args...")
|   ;; more stuff...
|   )
+---------------

If the body of both branches is multiple expressions, I'll just use COND:

 (defun RELEASER ()
   (cond
     ((= (length EXT:*ARGS*) 0)
      (format t "~%~A~%" "Nope, No Command Line Args Were Provided")
      (show-usage))
     (t
      (format t "~%~A~%" "Yep, We've Got Command Line Args")
      (format t "~%~A~%" "Processing Args...")
      ;; more stuff...
      )))

This also avoid the nasty mid-function GOTOs [yes, RETURN-FROM is
a kind on constrained GOTO], which tend to bite you later after the
function has grown a bit...


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Barry Margolin
Subject: Re: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <barmar-361440.23541204112005@comcast.dca.giganews.com>
In article <··································@4ax.com>,
 J.C. Roberts <unknown(NO_SPAM)@abac.com> wrote:

> So even when you have no need to use vars or tags, PROGN is the
> correct/efficient way to simply execute a set of statements?

You're confusing PROGN with PROG.  PROG allows you to have local 
variables and tags (it's like a combination of LET and TAGBODY), PROGN 
is just a way to group a bunch of expressions to be executed 
sequentially.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Bruce Hoult
Subject: Re: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <bruce-D0E6A6.18472605112005@news.clear.net.nz>
In article <····························@comcast.dca.giganews.com>,
 Barry Margolin <······@alum.mit.edu> wrote:

> In article <··································@4ax.com>,
>  J.C. Roberts <unknown(NO_SPAM)@abac.com> wrote:
> 
> > So even when you have no need to use vars or tags, PROGN is the
> > correct/efficient way to simply execute a set of statements?
> 
> You're confusing PROGN with PROG.  PROG allows you to have local 
> variables and tags (it's like a combination of LET and TAGBODY), PROGN 
> is just a way to group a bunch of expressions to be executed 
> sequentially.

*and* return the result of the Nth one.  As opposed to the 1st one in 
PROG1...

-- 
Bruce |  41.1670S | \  spoken |          -+-
Hoult | 174.8263E | /\ here.  | ----------O----------
From: Thomas F. Burdick
Subject: Re: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <xcvfyq7y0cb.fsf@conquest.OCF.Berkeley.EDU>
J.C. Roberts <unknown(NO_SPAM)@abac.com> writes:

> I'm still a bit murky on what CL (PROG ...) returns and more
> importantly, why, but a bit more reading and testing will probably
> shed some light on it.

It returns NIL, unless you explicitly return something from it with
RETURN.  I wouldn't worry about PROG unless you want to use two or
more of: a block named NIL, LET, and TAGBODY/GO.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Peter Seibel
Subject: Re: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <m2ll03jcae.fsf@gigamonkeys.com>
J.C. Roberts <unknown(NO_SPAM)@abac.com> writes:

> If you need to do more than one thing in the THEN and ELSE portions of
> the IF-THEN-ELSE (i.e. procedural with side-effects), what are the
> approaches that can be used in CommonLisp to evaluate multiple
> statements?


> I looked for a treatment of this in "Practical Common Lisp" (Peter
> Seibel) and "Successful Lisp" (David Lamkins) but found nothing.

Take a look at the section "WHEN and UNLESS" in chapter 7:

  <http://www.gigamonkeys.com/book/macros-standard-control-constructs.html>


-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: J.C. Roberts
Subject: Re: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <cmbqm1p3cakhv79soje5iopkmlmllbir73@4ax.com>
On Sat, 05 Nov 2005 16:21:29 GMT, Peter Seibel <·····@gigamonkeys.com>
wrote:

>J.C. Roberts <unknown(NO_SPAM)@abac.com> writes:
>
>> If you need to do more than one thing in the THEN and ELSE portions of
>> the IF-THEN-ELSE (i.e. procedural with side-effects), what are the
>> approaches that can be used in CommonLisp to evaluate multiple
>> statements?
>
>
>> I looked for a treatment of this in "Practical Common Lisp" (Peter
>> Seibel) and "Successful Lisp" (David Lamkins) but found nothing.
>
>Take a look at the section "WHEN and UNLESS" in chapter 7:
>
>  <http://www.gigamonkeys.com/book/macros-standard-control-constructs.html>
>
>
>-Peter

Thanks Peter, I'll give Ch 7 a read.

BTW, as someone who was "asked/told" by a client to format Cadence
SKILL code like this:

(defun foo ()
  (if (condition)
  then
    (run-then-funct-1
    ; args ...
    )
    (run-then-funct-2
    ; args  ...
    )
    ; more code...
  else
    (run-else-funct-1
    ; args  ...
    )
    (run-else-funct-2
    ; args ...
    )
    ; more code...
  )
)

I absolutely loved your reasoning for putting closing parentheses on
the same line as the last element of the list they are closing, 

"as long as your code is properly indented the parentheses should fade
away - no need to give them undue prominence by spreading them across
several lines" Ch 4, p.48

If you look past the weird formatting above, you can see how the SKILL
(if ...) has "then" and "else" tags built in -somewhat similar to the
Common Lisp (prog ...) statement.

JCR
From: Ivan Boldyrev
Subject: Re: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <f5c243-kho.ln1@ibhome.cgitftp.uiggm.nsc.ru>
On 9285 day of my life J. C. Roberts wrote:
> If you look past the weird formatting above, you can see how the SKILL
> (if ...) has "then" and "else" tags built in -somewhat similar to the
> Common Lisp (prog ...) statement.

See http://www.franz.com/~jkf/ifstar.txt

(defun foo ()
  (if* (condition)
    :then
      (func1 ...)
      (func2 ...)
      (func3 ...)
    :else
      (func4 ...)
      (func5 ...)))

-- 
Ivan Boldyrev

        Outlook has performed an illegal operation and will be shut down.
        If the problem persists, contact the program vendor.
From: Ivan Boldyrev
Subject: Re: CL Performance/Syntax of IF-THEN-ELSE
Date: 
Message-ID: <adn043-fi3.ln1@ibhome.cgitftp.uiggm.nsc.ru>
On 9284 day of my life J. C. Roberts wrote:
> (defun RELEASER ()
>   (if (= (length EXT:*ARGS*) 0)
>     (list
>       (format t "~%~A~%" "Nope, No Command Line Args Were Provided")
>       (show-usage)
>       (return-from RELEASER))
>     (list
>       (format t "~%~A~%" "Yep, We've Got Command Line Args")
>       (format t "~%~A~%" "Processing Args..."))
>       ; more stuff...
>       ))

(defun releaser ()
  (if (null ext:*args*) ; You want to check if list is empty, don't  you?
     (progn
        (format t "~%Nope, No Command Line Args Were Provided~%")
        (show-usage))
     (progn ; Else
       (format t "~%~A~%" "Yep, We've Got Command Line Args")
       (format t "~%~A~%" "Processing Args...")
       ; More stuff...
       )))

Or:

(defun releaser ()
  (cond
    ((null ext:*args*)  ; Cond has "implicit PROGN" inside
      (format t "~%Nope, No Command Line Args Were Provided~%")
      (show-usage))
    (t
      (format t "~%~A~%" "Yep, We've Got Command Line Args")
      (format t "~%~A~%" "Processing Args...")
      ; More stuff...
      )))

Choose any style you like :)

-- 
Ivan Boldyrev

                                      Life!  Don't talk to me about life.