From: Andrew Cooke
Subject: Command/Style/Idiom - post-result actions
Date: 
Message-ID: <873km3$77m$1@nnrp1.deja.com>
Hi,

There may be a simple command that does the following, or an obvious
idiom.

In several functions I have to perform some operations after
calculating the return value.  At the moment I'm doing the following:

(let ((retval (.....)))
  (..other code...)
  retval)

which is rather ugly.

I can't find an example macro in On Lisp, which makes me suspicious
that this is either possible in some way (it's not common in my code,
but does occur more often than many of the idioms he writes macros
for) or reflects some soft thinking on my part in the design.

There is unwind-protect, but using that seems bad style as it is
intended for errors - this means both that I would be mis-using it and
that, if an error does occur, the final action will be taken (which I
do not want).

Thanks,
Andrew

PS By now I can easily write a macro that does what I want - I'm just
worried that I shouldn't have to.



Sent via Deja.com http://www.deja.com/
Before you buy.

From: Michael Hudson
Subject: Re: Command/Style/Idiom - post-result actions
Date: 
Message-ID: <m3n1pmwow8.fsf@atrus.jesus.cam.ac.uk>
Andrew Cooke <······@andrewcooke.free-online.co.uk> writes:

> Hi,
> 
> There may be a simple command that does the following, or an obvious
> idiom.
> 
> In several functions I have to perform some operations after
> calculating the return value.  At the moment I'm doing the following:
> 
> (let ((retval (.....)))
>   (..other code...)
>   retval)
> 
> which is rather ugly.
> 
> I can't find an example macro in On Lisp, which makes me suspicious
> that this is either possible in some way (it's not common in my code,
> but does occur more often than many of the idioms he writes macros
> for) or reflects some soft thinking on my part in the design.
> 
> There is unwind-protect, but using that seems bad style as it is
> intended for errors - this means both that I would be mis-using it and
> that, if an error does occur, the final action will be taken (which I
> do not want).
> 
> Thanks,
> Andrew
> 
> PS By now I can easily write a macro that does what I want - I'm just
> worried that I shouldn't have to.

Well, there's [multiple-value-]prog1:

[113]> (prog1 1 2 4)
1

It's not something I've seen very often, but it's there.

And, oh look:

[115]> (macroexpand-1 '(prog1 1 2 3))
(LET ((#:G1300 1)) 2 3 #:G1300) ;
T

... looks familiar.

Cheers,
Michael

PS: The line about `prog2' in the hyperspec:

prog2 evaluates first-form, then second-form, and then forms, yielding
as its only value the primary value yielded by first-form.

is just wrong, isn't it? (the last word should be second-form, surely)
From: Robert Monfera
Subject: Re: Command/Style/Idiom - post-result actions
Date: 
Message-ID: <3895AA6D.ECB48835@fisec.com>
Andrew Cooke wrote:

> (let ((retval (.....)))
>   (..other code...)
>   retval)

If your code does not have side effects, then the last function of
....other code... probably returns retval already.

If you use side effects very often, maybe you can see if it's possible
to avoid them to increase the clarity of the code.

Often you initialise retval and accumulate something in it.  Loop
constructs are easy to instruct to return the accumulated value, like

(dotimes (i 1000000 retval)
    (incf (aref a i) retval))

Robert