From: Lowell
Subject: return values for functions
Date: 
Message-ID: <bguf4c$ep$1@mughi.cs.ubc.ca>
What should I return from a function which is used only for side 
effects? In Scheme I would usually return void, but I don't think that's 
an option in CL (is it?) Right now, the 2 best choices seem to be nil 
and t and I'm leaning towards nil. Are there pros and cons to the 
different choices, or is it jarbitrary?

Lowell

From: Artie Gold
Subject: Re: return values for functions
Date: 
Message-ID: <3F32BFFE.8070200@austin.rr.com>
Lowell wrote:
> What should I return from a function which is used only for side 
> effects? In Scheme I would usually return void, but I don't think that's 
> an option in CL (is it?) Right now, the 2 best choices seem to be nil 
> and t and I'm leaning towards nil. Are there pros and cons to the 
> different choices, or is it jarbitrary?

The best choice is probably to return

(values)

to express undeniably the fact that nothing is being returned.

HTH,
--ag

-- 
Artie Gold -- Austin, Texas
From: Kent M Pitman
Subject: Re: return values for functions
Date: 
Message-ID: <sfwfzkd54z3.fsf@shell01.TheWorld.com>
Artie Gold <·········@austin.rr.com> writes:

> Lowell wrote:
> > What should I return from a function which is used only for side
> > effects? In Scheme I would usually return void, but I don't think
> > that's an option in CL (is it?) Right now, the 2 best choices seem
> > to be nil and t and I'm leaning towards nil. Are there pros and cons
> > to the different choices, or is it jarbitrary?
> 
> The best choice is probably to return
> 
> (values)
> 
> to express undeniably the fact that nothing is being returned.
> 
> HTH,
> --ag


I don't agree with this.  Just return NIL.

Why?

 - "Portable Efficiency" (if that's not an oxymoron).

   Most functions return 1 value and I'd be surprised if most are not
   optimized for that case.  By returning (values), you are risking 
   that you are doing something non-optimal since you're selecting an
   unusual case.

 - Debuggability.

   People should not be looking at the return value if you've not
   documented any.  If they are, they're doing it by accident and will
   probably grab one value rather than none since that's what people
   usually assume.  That means they'll get NIL even if you return no
   values.  This in turn may confuse either you or them; you'd be better
   off just returning what the hapless user will probably see, for
   easier debugging.

 - Commonality.

   Most people return NIL since this is already the default for situations
   like 
     (defun frob-if (test x) 
       (when test (frob x)))
   No one I know is going to write
     (defun frob-if (test x)
       (if test (frob x) (values)))
   and so in the unconditional no-op case, I'd rather see the thing that
   is symmetric with the first of these two FROB-IF examples, that is,
   WHEN.  If we had defined in the language that WHEN returned (VALUES)
   in the null case, you could make a stronger case for (VALUES), but
   we didn't.  (And this is another reason I bet implemtnations are not
   optimized for (VALUES).

 - Visual Aesthetic.

   (values) print lousily.  In some contexts it's hard to tell that a 
   return value has happened.

 - Interaction with *, /, etc.

   There's some disagreement among implementations about the way to manage
   * and others.  The spec is explicit, but some implementations differ on
   whether * gets the last return value when it's (values); it's kind of
   a waste because the recent values are imporatnt to debugging, and having
   * get filled with NIL's is a waste.  Also, no serious conforming program
   is actually affected by such a non-conformance, so I can hardly fault
   a vendor for fixing this.
From: Steven M. Haflich
Subject: Re: return values for functions
Date: 
Message-ID: <3F33D096.3090500@alum.mit.edu>
Kent M Pitman wrote:

>  - Visual Aesthetic.
> 
>    (values) print lousily.  In some contexts it's hard to tell that a 
>    return value has happened.

I endore nearly everything else in this message, and in particular, that
returning zero values is more costly than returning NIL in practical
implementations.

However, there is one suituation where the visual aesthetic is reversed.
When I write a such function that I expect to be used primarily at top level,
I frequently end it with (values) with the express purpose of not cluttering
the top-level record with extra NILs.  CLtL recommended that the top level
"should" print as little as possible when no values are returned, and this is
a useful feature.  I suspect this wasn't preserved in the ANS, as it was
only a recommendation.
From: Barry Margolin
Subject: Re: return values for functions
Date: 
Message-ID: <5oQYa.52$7R.36@news.level3.com>
In article <················@alum.mit.edu>,
Steven M. Haflich <·················@alum.mit.edu> wrote:
>Kent M Pitman wrote:
>
>>  - Visual Aesthetic.
>> 
>>    (values) print lousily.  In some contexts it's hard to tell that a 
>>    return value has happened.
>
>I endore nearly everything else in this message, and in particular, that
>returning zero values is more costly than returning NIL in practical
>implementations.
>
>However, there is one suituation where the visual aesthetic is reversed.
>When I write a such function that I expect to be used primarily at top level,
>I frequently end it with (values) with the express purpose of not cluttering
>the top-level record with extra NILs.  CLtL recommended that the top level
>"should" print as little as possible when no values are returned, and this is
>a useful feature.  I suspect this wasn't preserved in the ANS, as it was
>only a recommendation.

Perhaps Kent's opinion may have been shaped by his early use of Maclisp,
which didn't display a prompt IIRC (I think there was also a way to turn
off the prompt on Lisp Machines, and perhaps he used this option as well).
So the only way to tell that a function had finished was when its value was
printed.  If (values) is displayed by displaying nothing, you wouldn't know
it at all.

Since most current CL implementations display a prompt in the REPL, this
concern is obsolete.

-- 
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Kent M Pitman
Subject: Re: return values for functions
Date: 
Message-ID: <sfwr83wlza9.fsf@shell01.TheWorld.com>
Barry Margolin <··············@level3.com> writes:

> Perhaps Kent's opinion may have been shaped by his early use of Maclisp,
> which didn't display a prompt IIRC (I think there was also a way to turn
> off the prompt on Lisp Machines, and perhaps he used this option as well).
> So the only way to tell that a function had finished was when its value was
> printed.  If (values) is displayed by displaying nothing, you wouldn't know
> it at all.
>
> Since most current CL implementations display a prompt in the REPL, this
> concern is obsolete.

This is from LispWorks, and is wholly conforming as far as I can tell.
You tell me.  Does it look "intuitive"?  This perfectly illustrates
why I'd rather _see_ the return value even when there's prompting
involved...


 CL-USER 54 > '(a b c)
 (A B C)

 CL-USER 55 > (pprint *)

 (A B C)

 CL-USER 56 > (car *)
 NIL
From: Erann Gat
Subject: Re: return values for functions
Date: 
Message-ID: <gat-0808031529270001@k-137-79-50-101.jpl.nasa.gov>
In article <···············@shell01.TheWorld.com>, Kent M Pitman
<······@world.std.com> wrote:

> Barry Margolin <··············@level3.com> writes:
> 
> > Perhaps Kent's opinion may have been shaped by his early use of Maclisp,
> > which didn't display a prompt IIRC (I think there was also a way to turn
> > off the prompt on Lisp Machines, and perhaps he used this option as well).
> > So the only way to tell that a function had finished was when its value was
> > printed.  If (values) is displayed by displaying nothing, you wouldn't know
> > it at all.
> >
> > Since most current CL implementations display a prompt in the REPL, this
> > concern is obsolete.
> 
> This is from LispWorks, and is wholly conforming as far as I can tell.
> You tell me.  Does it look "intuitive"?  This perfectly illustrates
> why I'd rather _see_ the return value even when there's prompting
> involved...
> 
> 
>  CL-USER 54 > '(a b c)
>  (A B C)
> 
>  CL-USER 55 > (pprint *)
> 
>  (A B C)
> 
>  CL-USER 56 > (car *)
>  NIL

This has nothing to do with returning zero values.  The same "unintuitive"
behavior can arise in functions that do not return zero values.  e.g.:

? (defun baz () (princ 1234) nil)
BAZ
? (defun foo () (values 1234 nil))
FOO
? (foo)
1234
NIL
? *
1234
? (baz)
1234
NIL
? *
NIL
? 

E.
From: Coby Beck
Subject: Re: return values for functions
Date: 
Message-ID: <bh1e7f$1vci$1@otis.netspace.net.au>
"Kent M Pitman" <······@world.std.com> wrote in message
····················@shell01.TheWorld.com...
> This is from LispWorks, and is wholly conforming as far as I can tell.
> You tell me.  Does it look "intuitive"?  This perfectly illustrates
> why I'd rather _see_ the return value even when there's prompting
> involved...
>
>
>  CL-USER 54 > '(a b c)
>  (A B C)
>
>  CL-USER 55 > (pprint *)
>
>  (A B C)
>
>  CL-USER 56 > (car *)
>  NIL


This one bites me quite often!  (not often enough to remember though...)

Though, personally I would prefer pprint to return a nil rather than the
REPL just print one.  Not a strong preference, but it is there.

-- 
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
From: Kenny Tilton
Subject: Re: return values for functions
Date: 
Message-ID: <3F32C2C9.2060702@nyc.rr.com>
Lowell wrote:
> What should I return from a function which is used only for side 
> effects? In Scheme I would usually return void, but I don't think that's 
> an option in CL (is it?) Right now, the 2 best choices seem to be nil 
> and t and I'm leaning towards nil. Are there pros and cons to the 
> different choices, or is it jarbitrary?

(values) is another option. Not sure how that changes anything in 
practice, since anyone /using/ the return value sees a nil. here is one 
manifestation I found:

CLO(17): (length (multiple-value-list nil))
1
CLO(18): (length (multiple-value-list (values)))
0

(values) would at least be self-documenting if nothing else.

Looking forward to better-informed answers....



-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
                                                  -- Bob Uecker
From: sv0f
Subject: Re: return values for functions
Date: 
Message-ID: <none-B28C37.20540614082003@news.vanderbilt.edu>
In article <················@nyc.rr.com>,
 Kenny Tilton <·······@nyc.rr.com> wrote:

>Lowell wrote:
>> What should I return from a function which is used only for side 
>> effects? In Scheme I would usually return void, but I don't think that's 
>> an option in CL (is it?) Right now, the 2 best choices seem to be nil 
>> and t and I'm leaning towards nil. Are there pros and cons to the 
>> different choices, or is it jarbitrary?
>
[...]
>
>(values) would at least be self-documenting if nothing else.
>
>Looking forward to better-informed answers....

I use (VALUES) for the reason you gave -- it's explicit,
and therefore self-documenting.

However, I do feel a bit icky, as if I'm breaking the
Lisp mindset and writing the equivalent of a Pascal
procedure.

(VALUES) tends to show up in my code when implementing what
are "top-level commands": the analog of (TIME) or (GC) in
Common Lisp itself.

When writing a non-command -- a regular function expected
to be called within other functions -- I sometimes veer
from (VALUES) and return NIL, which is a kind of catchall
value in Lisp.
From: Nikodemus Siivola
Subject: Re: return values for functions
Date: 
Message-ID: <bgukbg$2qb$1@nyytiset.pp.htv.fi>
Lowell <······@cs.ubc.ca> wrote:

> What should I return from a function which is used only for side 
> effects? 

Good question, and I'm for one curious to hear the answers of
experienced lispers. 

What I do is first try to find some actual value that would make sense
within the functions contract: something that may turn out to be
usefull later on. When there is none I just let it return whatever
happens to be the result of the last expression -- but I'm just lazy
and evil.

Cheers,

 -- Nikodemus
From: Kent M Pitman
Subject: Re: return values for functions
Date: 
Message-ID: <sfwbrv1545y.fsf@shell01.TheWorld.com>
Nikodemus Siivola <······@random-state.net> writes:

> What I do is first try to find some actual value that would make sense
> within the functions contract: something that may turn out to be
> usefull later on. When there is none I just let it return whatever
> happens to be the result of the last expression -- but I'm just lazy
> and evil.

The problem with this is two-fold:

 - If the caller grabs the return value and holds it, even if it doesn't
   use it in any material way that would imply it was "caring what the
   return value was", it can still gc-lock the result, which might otherwise
   want to get reclaimed.

 - You might return something "not for the caller to be side-effecting",
   and so you're risking that the caller will needlessly do so.
   It's fine that COMPUTE-RESTARTS returns such a list intentionally,
   but you don't want to do this kind of thing by accident.  e.g., having
   MP:PROCESS-RUN-FUNCTION return the actual list of processes used by
   the task scheduler just because it was the last value laying around
   after starting the process and adding it to some scheduling queue
   would be unbearably risky.
From: Kenny Tilton
Subject: Re: return values for functions
Date: 
Message-ID: <3F32E42C.5060206@nyc.rr.com>
Nikodemus Siivola wrote:
> Lowell <······@cs.ubc.ca> wrote:
> 
> 
>>What should I return from a function which is used only for side 
>>effects? 
> 
> 
> Good question, and I'm for one curious to hear the answers of
> experienced lispers. 
> 
> What I do is first try to find some actual value that would make sense
> within the functions contract: something that may turn out to be
> usefull later on.

Ah, good point. Something that sets a place by convention in CL returns 
the value set, kinda passing it along so the setting operation itself 
can be a useful argument to another function.

Or, if you are modifying a particular structure with one or more values, 
  you can return the modified structure as a possible convenience, so I 
can do:

     (interesting-work (newly-modified thing :left 'right :right 'left))

...where newly-modified returns thing.



-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
                                                  -- Bob Uecker
From: ··········@YahooGroups.Com
Subject: Re: return values for functions
Date: 
Message-ID: <REM-2003aug11-008@Yahoo.Com>
{{Date: Thu, 7 Aug 2003 22:37:36 +0000 (UTC)
  From: Nikodemus Siivola <······@random-state.net>
  What I do is first try to find some actual value that would make
  sense within the functions contract: something that may turn out to
  be usefull [sic] later on.}}

That's good thinking.

{{When there is none I just let it return whatever happens to be the
  result of the last expression -- but I'm just lazy}}

That's bad thinking, especially if the value is some internal thing
totally inscrutable to the caller. It's better to return (values)
or nil, or for a major task some kind of successful completion flag
such as :DONE or :SUCCESS, or something specific to the task such
as if it sent e-mail then :SENT.

Be sure to document what the return value is, whatever you decide to
return, and be sure that documentation is understandable in the context
of the caller, not the innerds of the function. One exception: If the
task takes a lot of work to set up, and there's some structure that
when passed back to the function later would make a subsequent task
much more efficient, then perhaps that can be returned. But maybe a
static variable (lexically bound around the function definition) would
be better if there would ever be only one thread of such going on.
From: Willy
Subject: Re: return values for functions
Date: 
Message-ID: <66401d34.0308080446.70e86ec3@posting.google.com>
Lowell <······@cs.ubc.ca> wrote in message news:<···········@mughi.cs.ubc.ca>...
> What should I return from a function which is used only for side 
> effects? In Scheme I would usually return void, but I don't think that's 
> an option in CL (is it?) Right now, the 2 best choices seem to be nil 
> and t and I'm leaning towards nil. Are there pros and cons to the 
> different choices, or is it jarbitrary?
> 
> Lowell

Is there anything wrong with returning T? Can one of the old lisp hands comment?

Thanks
From: Kenny Tilton
Subject: Re: return values for functions
Date: 
Message-ID: <3F33A426.60906@nyc.rr.com>
Willy wrote:
> Lowell <······@cs.ubc.ca> wrote in message news:<···········@mughi.cs.ubc.ca>...
> 
>>What should I return from a function which is used only for side 
>>effects? In Scheme I would usually return void, but I don't think that's 
>>an option in CL (is it?) Right now, the 2 best choices seem to be nil 
>>and t and I'm leaning towards nil. Are there pros and cons to the 
>>different choices, or is it jarbitrary?
>>
>>Lowell
> 
> 
> Is there anything wrong with returning T? Can one of the old lisp hands comment?

Yecch. :)

I'd hate to see a value conjured up and stuck at the end of a function. 
Just write the function naturally and correctly and put enough parens at 
the end to make the compiler happy.

Don't forget, the premise is that we have a function called only for its 
side effects, with no reasonable value to return. I think it is time to 
invoke the No Abstract Questions Rule -- I'd like to see this function.

but if it turns out to make sense, hell, just fall off the end of the 
function. anyone capturing the random return value deserves what they 
get (The Lisp Way).

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
                                                  -- Bob Uecker
From: Kent M Pitman
Subject: Re: return values for functions
Date: 
Message-ID: <sfwn0eklz35.fsf@shell01.TheWorld.com>
·········@sbcglobal.net (Willy) writes:

> Lowell <······@cs.ubc.ca> wrote in message news:<···········@mughi.cs.ubc.ca>...
> > What should I return from a function which is used only for side 
> > effects? In Scheme I would usually return void, but I don't think that's 
> > an option in CL (is it?) Right now, the 2 best choices seem to be nil 
> > and t and I'm leaning towards nil. Are there pros and cons to the 
> > different choices, or is it jarbitrary?
> > 
> > Lowell
> 
> Is there anything wrong with returning T? Can one of the old 
> lisp hands comment?

Returning T is sometimes ok, too, with the caveat that it should confirm
that some action has occurred or been done successfully in cases where
there might be a question of whether anything happened.

Even in a no-op, you might return NIL meaning "I made this a no-op because
I didn't know what to do and I didn't think it warranted an error" while
it might return T meaning "I made this a no-op because I know that doing
nothing is going to be the right thing, so I'm confirming to the caller 
that to the degree that he should care, I have done what I was asked."

In otherwords, even considering returning T usually means you're thinking 
about "useful values", which is slightly different than trying to find a
neutral value to return meaning "I didn't mean to convey information".
From: Gorbag
Subject: Re: return values for functions
Date: 
Message-ID: <6UVYa.3902$c6.3338@bos-service2.ext.raytheon.com>
"Kent M Pitman" <······@world.std.com> wrote in message
····················@shell01.TheWorld.com...
> ·········@sbcglobal.net (Willy) writes:
>
> > Lowell <······@cs.ubc.ca> wrote in message
news:<···········@mughi.cs.ubc.ca>...
> > > What should I return from a function which is used only for side
> > > effects? In Scheme I would usually return void, but I don't think
that's
> > > an option in CL (is it?) Right now, the 2 best choices seem to be nil
> > > and t and I'm leaning towards nil. Are there pros and cons to the
> > > different choices, or is it jarbitrary?
> > >
> > > Lowell
> >
> > Is there anything wrong with returning T? Can one of the old
> > lisp hands comment?
>
> In otherwords, even considering returning T usually means you're thinking
> about "useful values", which is slightly different than trying to find a
> neutral value to return meaning "I didn't mean to convey information".

How about returning

(values :I-DECIDED-NOT-TO-BE-FUNCTIONAL-AND-SIDE-EFFECT-SOMETHING-INSTEAD
            (random 32767)
            <favorite star-trek episode>
            <current RT Strategy game>)