From: Fred Kennedy
Subject: Please help for a beginner
Date: 
Message-ID: <3464BCD9.54E6@fredkennedy.com>
Hi:

I am a beginning student in Lisp and had a couple of basic questions.

Is it possible to call a function a number of times with different
parameters from within another function as in the following code:

(defun rev()
(setq k '(a b c d e f))
(revx k)
(terpri)
(setq k '(a b c))
(terpri)
(revx k)
(setq k '(a b))
(revx k))


(defun revx(lst)

(setq temp(cdr (cdr lst)))
(cons (car(cdr lst)) (cons(car lst) (list temp))))

When I run the above code it only displays the answer for the last
function call: (revx k)

Is Lisp executing each function call, going to the called function
executing all the code and then returning to the line in the calling
function from which it was called?

Thanks for your help

From: Kent M Pitman
Subject: Re: Please help for a beginner
Date: 
Message-ID: <sfwwwij5ci4.fsf@world.std.com>
Fred Kennedy <·····@fredkennedy.com> writes:

> Hi:

Hi.  Welcome.

> I am a beginning student in Lisp and had a couple of basic questions.
>
> Is it possible to call a function a number of times with different
> parameters from within another function 

Yes.  But if the function has no side-effects, you will never know it
happened.  For you to observe the effect, at least one of the
following must be true:

 - The inner function (the one called by the other function)
   has a side-effect that can be later observed.

 - The inner function returns a value that the outer function
   remembers and returns.

 - The inner function returns a value and the outer function 
   records that value by side-effect in a way that can be later
   observed.

> as in the following code:

I'm going to re-indent that code.  In Lisp, a left paren (we use
the term too often to say the whole word "parenthesis") should 
NEVER occur directly under or to the left of an outer left paren.
Lisp programmers find such programs too hard to look at.
Also, by convention, a left paren never directly touches a name
to its left as it might in an algebraic language; this helps you
remember that the operator is to the RIGHT, not the LEFT of
certain parens.  A more normal indentation of your code would be:

 (defun rev ()
   (setq k '(a b c d e f))
   (revx k)
   (terpri)
   (setq k '(a b c))
   (terpri)
   (revx k)
   (setq k '(a b))
   (revx k))

 (defun revx (lst)
   (setq temp (cdr (cdr lst)))
   (cons (car (cdr lst))
         (cons (car lst) 
               (list temp))))

Ah, now we can see that revx makes no side-effect and rev records
no result, so you'll never know revx was called (even though it
was).  You can do (trace revx) and then call rev and you'll see
that revx is being called.  You'll later want to do (untrace revx)
to turn off tracing before you continue with your work.

> When I run the above code it only displays the answer for the last
> function call: (revx k)

That's right.  Every function reports to its caller.  The first
two calls to REVX report to REV and are discarded by REV because
they are in the middle of a body of code.  The middle of a body
is sometimes called a "not for value" position.  If you don't do a
side-effect there, you'll be ignored.  If you'd like to force the
value to be printed, you'll want to call PRINT explicitly.

The last call to REVX also returns to REV, but in what's called
the "value producing" position of the body, and so it is returned.
Since REV was called interactively by you at the program, its value
is yielded interactively back to you through an implicit call to 
print.

> Is Lisp executing each function call, going to the called function
> executing all the code and then returning to the line in the calling
> function from which it was called?

Yes, as the call to TRACE above will hopefully help you see.
Calling TRACE asks Lisp to tell you when a function is called and
what it returns so that you can debug side-effect-free functions
more easily. 

> Thanks for your help

No problem.  Good luck!

p.s.  a good next question to ask once you get this sorted out is
      "how can I allocate local variables in my program?"  You
      might be thinking K and TEMP are local to the programs in
      which they occur, but they are not.  Since  you have named
      your local variables by different names, you fortunately
      (and probably only accidentally) won't hurt yourself yet,
      but this practice is ultimately one you want to rethink.
      one thing at a time, though.  go ahead and finish your
      work on this problem and then get someone to
      help you understand about "free" and "bound" variables.
From: Barry Margolin
Subject: Re: Please help for a beginner
Date: 
Message-ID: <642jhj$nhr@pasilla.bbnplanet.com>
In article <·············@fredkennedy.com>,
Fred Kennedy  <·····@fredkennedy.com> wrote:
>Is it possible to call a function a number of times with different
>parameters from within another function as in the following code:

Of course.  It's done all the time, e.g.

(defun foo (a b c d)
  (+ (* a b) (* c d)))

which calls * twice with different parameters.  It would be practically
impossible to program if you couldn't call the same function multiple times
with different parameters.

>When I run the above code it only displays the answer for the last
>function call: (revx k)

A function returns the value of the last form in its body.  The Lisp
top-level displays what the function returns.  Intermediate values in the
program are not printed automatically.  If you want to print values in the
middle of the function, you must do so explicitly in your code, by using a
function like PRINT or FORMAT.  Normally, the user of a function is not
interested in seeing its intermediate computations; if the purpose of your
function is to cause output, you have to put it in the function.

>Is Lisp executing each function call, going to the called function
>executing all the code and then returning to the line in the calling
>function from which it was called?

Yes.  Any Lisp tutorial should be quite clear about how functions are
executed.

P.S. If you expect people to help you, please make it easier to read your
code, by indenting it properly.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
Support the anti-spam movement; see <http://www.cauce.org/>
Please don't send technical questions directly to me, post them to newsgroups.