Subject: Re: Simple LISP question (sequence of multiple statements)
From: Erik Naggum <erik@naggum.no>
Date: 15 Aug 2002 06:38:57 +0000
Newsgroups: comp.lang.lisp
Message-ID: <3238382337606467@naggum.no>

* Timothy Miller
| However, there is one place where I can't determine from the book I
| have how to list multiple statements, which is this:
|     (if (condition) (do something here) (do two somethings here))
| 
| How do I do two somethings there?

  I appreciate the intelligent way you arrive at the question.  There are
  multiple ways to do this.  You have already seen what is called an "implicit
  `progn´", where prog-n means that the nth value of a prog is returned.
  [There is a lot of history here.  You also have `prog1´ and `prog2´ which
  return the first and second values, respectively, of a multi-form body.]  An
  implicit `progn´ occurs in function bodies as you have already seen.  You
  could write

(if condition
    (do something here)
    (progn
      (do something-1 here)
      (do something-2 here)
      ...
      (do something-n here)))

  to use `progn´ explicitly.  [If you do this with both branches, some people
  have invented `then´ and `else´ as local macros that are really `progn´.]
  Notice how `prog1´, `prog2´ and `progn´ fall out from this example.

  However, you already know about implicit `progn´s from elsewhere.  You
  already listed function bodies and `cond´ clauses, but also, e.g., in local
  bindings with `let´, as in

(let ()
  (do something-1 here)
  (do something-2 here))

  only the value of the last form is returned.  [The empty list () would of
  course be filled with bindings if you needed any.]  The older `prog´ is
  similar to `let´, except it takes labels.  You need not worry about this; I
  mention it for the sake of completeness and to illustrate how this problem
  has been solved in many different ways over time.  The canonical way these
  days is with `progn´, but be forewarned that some people hate `progn´ with a
  passion so have invented a disturbingly non-Lispy version of `if´ that gets
  rid of it exchange for a lot of other random noise.
  
| Is there some function which, given multiple arguments, executes them and
| returns the value of the last one?

  You could do it with a function, but Common Lisp has found the use of
  special operators more convenient.  Essentially, a `progn´ works just like a
  function call would, evaluating each argument expression in turn, except
  that all values are discarded instead of being collected for a function
  call.  The same is true of `let´, which is also a special operator.  The
  name "special operator" comes from the fact that its evaluation rule is
  special, although in the case of `progn´ it is actually trivially normal.

| I wanted to setf a global variable and then return something else, but I
| ended up using cond instead which didn't result in the most straight-forward
| solution.

  I tend to prefer `cond´ when the number of branches is indeterminate, `if´
  when there are exactly two (such as because the `nil´ should be explicit
  when the form is used for its value) , and `when´ and `unless´ when there is
  only one branch that matters.

| Any help will be appreciated.

  I hope the above suffices.

| Also, and I'm sure there's a FAQ, and I'm going to go look for it right now,
| but I was wondering if anyone had any good suggestions for teaching LISP to
| someone who is generally unfamiliar with programming.  I'm teaching it to my
| wife.  Some may think it insane to teach LISP to someone as a first
| language, but humor me.  :)

  I think it is the best choice for a first language.  Eons ago, I found The
  Little LISPer absorbingly fascinating.

| The book I'm using, by Touretzki, is alright, but it really irritates me
| sometimes.

  It is the only book on Lisp I have declined to buy after looking at it.

-- 
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.