In case these terms are too old for anyone to know them, we used to use the phrase "for effect" to mean a function that was called for the sake of its side-effects, versus "for value" when it was called for the sake of its returned value. (Actually I'm not sure I remember what we called a function with both properties.)
In some code I have seen, the author of the code has written (values) at the end of an implied-progn body. The purpose, pretty clearly, is to signal the reader of the code that the function was purely for-effect, i.e. that the returned value does not mean anything.
This is mostly stylistic. In most cases, returning "nil" means the same thing as returning no values, i.e. (values). The only situation where it makes any difference, as far as I know, is when multiple-value-list is being called, and that's used very, very rarely.
The question is, is it good style? That is, ought we consider it something to be recommended?
The pro is that it presents clear information to the reader of the code. Merely not putting anything at the end of the implied progn means that the value of the last function called is the returned value, and the reader of the code might think that was on purpose.
On the other hand, having a (values) at the end does not actually prove that the function does not have any meaningful value, since a "return" within the function could return a value (or many values).
From a purely emotional/historical point of view, I am not used to seeing these (values) forms, and they seem somewhat ugly and verbose. But that's just based on my own experience and should not carry much weight.
I'd like to write in our programming standards either that they should be used, or that they should not be used. I think it's suboptimal for them to be used in some places and not others, since the inconsistency could lead a reader of the code to draw wrong conclusions.
What do people think?
-- Dan
My taste tells me that's an over-clever idiom and should not be used. If it's not clear that a function is for-effect without (values) you've already lost.
-Peter
On Thu, Dec 2, 2010 at 3:00 PM, Daniel Weinreb dlw@itasoftware.com wrote:
In case these terms are too old for anyone to know them, we used to use the phrase "for effect" to mean a function that was called for the sake of its side-effects, versus "for value" when it was called for the sake of its returned value. (Actually I'm not sure I remember what we called a function with both properties.)
In some code I have seen, the author of the code has written (values) at the end of an implied-progn body. The purpose, pretty clearly, is to signal the reader of the code that the function was purely for-effect, i.e. that the returned value does not mean anything.
This is mostly stylistic. In most cases, returning "nil" means the same thing as returning no values, i.e. (values). The only situation where it makes any difference, as far as I know, is when multiple-value-list is being called, and that's used very, very rarely.
The question is, is it good style? That is, ought we consider it something to be recommended?
The pro is that it presents clear information to the reader of the code. Merely not putting anything at the end of the implied progn means that the value of the last function called is the returned value, and the reader of the code might think that was on purpose.
On the other hand, having a (values) at the end does not actually prove that the function does not have any meaningful value, since a "return" within the function could return a value (or many values).
From a purely emotional/historical point of view, I am not used to seeing these (values) forms, and they seem somewhat ugly and verbose. But that's just based on my own experience and should not carry much weight.
I'd like to write in our programming standards either that they should be used, or that they should not be used. I think it's suboptimal for them to be used in some places and not others, since the inconsistency could lead a reader of the code to draw wrong conclusions.
What do people think?
-- Dan
pro mailing list pro@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/pro
On Thu, 2 Dec 2010, Peter Seibel wrote:
My taste tells me that's an over-clever idiom and should not be used. If it's not clear that a function is for-effect without (values) you've already lost.
I confess that I have used (values) before, not only to indicate that a function was for effect only, but also to prevent any implementation detail from leaking out. I also like m-v-l's behavior when receiving (values).
(I also confess that I haven't been consistent in this use.)
On the other hand, I agree with Peter that it can be somewhat ugly. Maybe some alternatives, based on (values)?
(defun f () (for-effect (setq *foo* 'bar)))
Or, how about:
(defeffect f () (setq *foo* 'bar))
for-effect and defeffect could have the added benefit of guaranteeing that *no* return path will return a value.
-David
On Fri, Dec 3, 2010 at 12:30 AM, David Owen dsowen@fugue88.ws wrote:
On the other hand, I agree with Peter that it can be somewhat ugly. Maybe some alternatives, based on (values)?
(defun f () (for-effect (setq *foo* 'bar)))
Actually your example hints to a case where I *do* want a for-effect function to return a value, because setq does - which is also a strictly for-effect function. Similar, I like methods to return the object they were called on in a Smalltalk-style, if there is nothing better to return. Only when there is absolutely nothing useful to return, I would consider something like (values)
Peter
On Thu, Dec 2, 2010 at 3:20 PM, Peter Seibel peter@gigamonkeys.com wrote:
My taste tells me that's an over-clever idiom and should not be used. If it's not clear that a function is for-effect without (values) you've already lost.
I can certainly see the argument that this information primarily belongs in the doc string, and the use of (values) must not become a substitute for specifying it there.
As long as that is kept in mind, the practice seems harmless to me.
-- Scott
I can certainly see the argument that this information primarily belongs in the doc string, and the use of (values) must not become a substitute for specifying it there.
i feel the need to counter this: i think it's bad practice to put anything in an informal documentation that could be formalized in the code with reasonable effort (e.g. a defun-void macro in this case).
(i would even argue that using literal strings for documentation is a bad idea, and the "docstring" should be an evaluated expression at compile time and the stored result should be a much more complex structure than a character string. but this amendment leads to a long and somewhat irrelevant discussion regarding the original statement...)
On Thu, Dec 2, 2010 at 3:00 PM, Daniel Weinreb dlw@itasoftware.com wrote:
From a purely emotional/historical point of view, I am not used to seeing these (values) forms, and they seem somewhat ugly and verbose. But that's just based on my own experience and should not carry much weight.
I'd like to write in our programming standards either that they should be used, or that they should not be used. I think it's suboptimal for them to be used in some places and not others, since the inconsistency could lead a reader of the code to draw wrong conclusions.
What do people think?
I haven't been in the habit of using them, but now you describe the practice, it seems like a good idea. Maybe I will start. I have the luxury of writing just for my own eyes, though; your situation is more complicated. It certainly seems unfortunate to tell people to take them out when they've gone to the trouble of putting them in.
I agree that a function that returns a value along any path should not use (values) anywhere. This seems consistent with the intent of the practice, which is, after all, clarity.
-- Scott
At least in LW, (values) returned to the REPL stops the repl from printing anything. I've used it when the value otherwise returned would print something big (and long).
I would expect to see it in (a) functions called at the top level and (b) in places where "nothing" returned vs. "something" returned has meaning, but not as an indicator of side-effects, i.e. I have not witnessed it being used often enough for it to feel like an idiom (convey information) to my eyes.
Hmm. Can (values) affect the optimizer or help the GC'er?
pt
On 3 December 2010 01:00, Daniel Weinreb dlw@itasoftware.com wrote:
The question is, is it good style? That is, ought we consider it something to be recommended?
CMUCL (and by extension SBCL) code does this quite a lot. I've never been a huge fan -- partially because the style subtly encourages side-effects where function approach would work, and partly because it tends to make debugging harder.
Most of the time there's thing you can sensibly return -- which makes output from TRACE more useful, even if 90% of the callers end up discarding it.
If there is no sensible return value beyond (VALUES) or NIL, then I do find (VALUES) a good obvious signal that the function is being used for effect only, and occasionally it _does_ make debugging easier by killing tail-calls.
So, a mixed bag for me.
Cheers,
-- Nikodemus
On Dec 2, 2010, at 6:00 PM, Daniel Weinreb wrote:
In case these terms are too old for anyone to know them, we used to use the phrase "for effect" to mean a function that was called for the sake of its side-effects, ...
In some code I have seen, the author of the code has written (values) at the end of an implied-progn body. The purpose, pretty clearly, is to signal the reader of the code that the function was purely for-effect, i.e. that the returned value does not mean anything.
We called this defun-void http://j.mp/hnqGuk in thinlisp. Our goal was to assure we could compile into a C function who's return type was void. But I came to like how it documented the intent, relieved readers of having to puzzle out the return value contract, etc. Our defun-void functions returned a single bogus value. This is the kind of thing I have always assumed i could do with declare. If only I was clever enough and patient enough to get it to work across implementations. But one of the reasons thinlisp isn't a going concern at this instant is the clever things we tried to do with declare. - ben
Daniel Weinreb wrote:
I'd like to write in our programming standards either that they should be used, or that they should not be used. I think it's suboptimal for them to be used in some places and not others, since the inconsistency could lead a reader of the code to draw wrong conclusions.
What do people think?
I've looked at some of my code, and it seems that the only places I use (values) are in for-effect generic functions'methods that are specialized to do nothing. I find it more readable than using an empty body or just say "nil" (because even "nil" suggests it /is/ a return value).
It seems to me that when a function or method actually /does/ something, you can always find a return value that would be potentially meaningful in the future, even if nobody uses it right now.
I think it is confusing to use (values) for that purpose, because "no values" is also a valid return value (e.g. for reader macro functions http://www.lispworks.com/documentation/HyperSpec/Body/02_add.htm).
I would make it a macro, called something like void.
OTOH, use of (values) or (void) will prevent tail call optimization, so may be undesirable.
On 3 Dec 2010, at 13:34, Martin Simmons wrote:
I think it is confusing to use (values) for that purpose, because "no values" is also a valid return value (e.g. for reader macro functions http://www.lispworks.com/documentation/HyperSpec/Body/02_add.htm).
I would make it a macro, called something like void.
OTOH, use of (values) or (void) will prevent tail call optimization, so may be undesirable.
I think this is the strongest argument in this thread: Most other arguments seem to point out only subjective and/or stylistic issues, while this one is a hard technical difference. Preventing tail call optimizations for stylistic issues is a bad idea, IMHO.
I have occasionally used the (values) idiom, but only in test situations, when I don't like seeing return values in the REPL. I seem to recall some uses of (values) in PCL.
Pascal
You mean PCL the CLOS implementation, right?
-Peter
On Tue, Dec 7, 2010 at 10:20 AM, Pascal Costanza pc@p-cos.net wrote:
On 3 Dec 2010, at 13:34, Martin Simmons wrote:
I think it is confusing to use (values) for that purpose, because "no values" is also a valid return value (e.g. for reader macro functions http://www.lispworks.com/documentation/HyperSpec/Body/02_add.htm).
I would make it a macro, called something like void.
OTOH, use of (values) or (void) will prevent tail call optimization, so may be undesirable.
I think this is the strongest argument in this thread: Most other arguments seem to point out only subjective and/or stylistic issues, while this one is a hard technical difference. Preventing tail call optimizations for stylistic issues is a bad idea, IMHO.
I have occasionally used the (values) idiom, but only in test situations, when I don't like seeing return values in the REPL. I seem to recall some uses of (values) in PCL.
Pascal
-- Pascal Costanza, mailto:pc@p-cos.net, http://p-cos.net Vrije Universiteit Brussel Software Languages Lab Pleinlaan 2, B-1050 Brussel, Belgium
pro mailing list pro@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/pro
Yes.
On 7 Dec 2010, at 19:36, Peter Seibel wrote:
You mean PCL the CLOS implementation, right?
-Peter
On Tue, Dec 7, 2010 at 10:20 AM, Pascal Costanza pc@p-cos.net wrote:
On 3 Dec 2010, at 13:34, Martin Simmons wrote:
I think it is confusing to use (values) for that purpose, because "no values" is also a valid return value (e.g. for reader macro functions http://www.lispworks.com/documentation/HyperSpec/Body/02_add.htm).
I would make it a macro, called something like void.
OTOH, use of (values) or (void) will prevent tail call optimization, so may be undesirable.
I think this is the strongest argument in this thread: Most other arguments seem to point out only subjective and/or stylistic issues, while this one is a hard technical difference. Preventing tail call optimizations for stylistic issues is a bad idea, IMHO.
I have occasionally used the (values) idiom, but only in test situations, when I don't like seeing return values in the REPL. I seem to recall some uses of (values) in PCL.
Pascal
-- Pascal Costanza, mailto:pc@p-cos.net, http://p-cos.net Vrije Universiteit Brussel Software Languages Lab Pleinlaan 2, B-1050 Brussel, Belgium
pro mailing list pro@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/pro
-- Peter Seibel http://www.codequarterly.com/
It looks like we do not have a concensus. Thanks to everybody for contributing!
-- Dan