warning for unused return value

93 views
Skip to first unread message

Russ P.

unread,
Feb 29, 2012, 8:21:34 PM2/29/12
to scala-user
This topic came up a while ago, but I don't recall exactly how it
ended.

Just today, I had two separate bugs due to a failure to use (i.e.,
assign) a return value from a method of an immutable class. The return
value was a modified copy of the same class type.

A simple compiler warning could have saved me substantial debugging
time. I realize that such a warning could produce false alerts, but
perhaps it could be a compiler option. Also, perhaps the warning could
be restricted to certain cases, such as a return value that is not
"Unit" or "this." Could something like that be reasonable?

I sure hope so -- it is easy to forget that a method is returning a
modified copy rather than mutating the object.

--Russ P.

Vlad Patryshev

unread,
Feb 29, 2012, 9:15:32 PM2/29/12
to Russ P., scala-user
I'd rather make it an issue in a code revision tool, if there is such a thing for Scala.
Otherwise, it's a normal behavior, I believe, and adding a warning would mean that everybody would have to add... add what? An unnecessary val?

Thanks,
-Vlad

Russ P.

unread,
Feb 29, 2012, 10:02:24 PM2/29/12
to scala-user
I don't understand. Why would you need to add an unnecessary val? If
the return value is not used, then simply eliminate it and return
Unit.

If the return value is used in some cases and not in others, then
perhaps you need a design review. Why would that be? I'm probably
missing something, but I wonder if that is due to the C-style of
returning an error code (which is sometimes checked and sometimes
not).

If the warning is a compiler option, you always have an out anyway. If
it bothers you, just don't use it.

--Russ

Naftoli Gugenheim

unread,
Feb 29, 2012, 10:08:41 PM2/29/12
to Russ P., scala-user
What if a method performs a side effect and returns a value, but you don't care about the return value (like Buffer#remove)?

Vlad Patryshev

unread,
Feb 29, 2012, 10:47:21 PM2/29/12
to Russ P., scala-user
On Wed, Feb 29, 2012 at 7:02 PM, Russ P. <russ.p...@gmail.com> wrote:
I don't understand. Why would you need to add an unnecessary val? If
the return value is not used, then simply eliminate it and return
Unit.

How else do you call a function that returns something? I feel like you actually have a var whose value is being replaced. Is it so? Is not it the root of the problem? Or?

And basically, if you do no
 

If the return value is used in some cases and not in others, then
perhaps you need a design review. Why would that be? I'm probably
missing something, but I wonder if that is due to the C-style of
returning an error code (which is sometimes checked and sometimes
not).

If the warning is a compiler option, you always have an out anyway. If
it bothers you, just don't use it. 

I  believe warning points to something that is wrong to do. Downcasting to Unit is not wrong. I think.

Russ Paielli

unread,
Mar 1, 2012, 12:16:49 AM3/1/12
to Naftoli Gugenheim, scala-user
On Wed, Feb 29, 2012 at 7:08 PM, Naftoli Gugenheim <nafto...@gmail.com> wrote:
What if a method performs a side effect and returns a value, but you don't care about the return value (like Buffer#remove)?


I don't know. I'm just trying to suggest ways to prevent predictable bugs. Can the compiler determine whether a method returns a modified copy of an immutable class and has no side effects? If so, then there would be no reason to call the function other than to get the return value. So if the caller does not use the return value, chances are it's a bug.

As I said before, I just had two of these kinds of bugs today. I don't claim to be the worlds greatest programmer, but I'm not the worst either. It happens.

--Russ P.

--
http://RussP.us

Dennis Haupt

unread,
Mar 1, 2012, 3:50:58 AM3/1/12
to Russ P., scala...@googlegroups.com
i would suggest an annotation "@Pure" or something so the compiler knows the method has no side effect and refuses to compile if the result is unused

-------- Original-Nachricht --------
> Datum: Wed, 29 Feb 2012 17:21:34 -0800 (PST)
> Von: "Russ P." <russ.p...@gmail.com>
> An: scala-user <scala...@googlegroups.com>
> Betreff: [scala-user] warning for unused return value

√iktor Ҡlang

unread,
Mar 1, 2012, 3:55:10 AM3/1/12
to Dennis Haupt, Russ P., scala...@googlegroups.com
On Thu, Mar 1, 2012 at 9:50 AM, Dennis Haupt <h-s...@gmx.de> wrote:
i would suggest an annotation "@Pure" or something so the compiler knows the method has no side effect and refuses to compile if the result is unused

If it's pure, then the compiler can just eliminate the call if the result is not used. So just drop the call and issue a warning.
It's worse with impure calls with return values that are not used, as they cannot be elided.
 

-------- Original-Nachricht --------
> Datum: Wed, 29 Feb 2012 17:21:34 -0800 (PST)
> Von: "Russ P." <russ.p...@gmail.com>
> An: scala-user <scala...@googlegroups.com>
> Betreff: [scala-user] warning for unused return value

> This topic came up a while ago, but I don't recall exactly how it
> ended.
>
> Just today, I had two separate bugs due to a failure to use (i.e.,
> assign) a return value from a method of an immutable class. The return
> value was a modified copy of the same class type.
>
> A simple compiler warning could have saved me substantial debugging
> time. I realize that such a warning could produce false alerts, but
> perhaps it could be a compiler option. Also, perhaps the warning could
> be restricted to certain cases, such as a return value that is not
> "Unit" or "this." Could something like that be reasonable?
>
> I sure hope so -- it is easy to forget that a method is returning a
> modified copy rather than mutating the object.
>
> --Russ P.



--
Viktor Klang

Akka Tech Lead
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Dennis Haupt

unread,
Mar 1, 2012, 5:38:05 AM3/1/12
to "√iktor Ҡlang", scala...@googlegroups.com, russ.p...@gmail.com
why would you call a method that is pure and then not use its return value?
only for one: because you forgot to do it.

-------- Original-Nachricht --------
> Datum: Thu, 1 Mar 2012 09:55:10 +0100
> Von: "√iktor Ҡlang" <viktor...@gmail.com>
> An: Dennis Haupt <h-s...@gmx.de>
> CC: "Russ P." <russ.p...@gmail.com>, scala...@googlegroups.com
> Betreff: Re: [scala-user] warning for unused return value

> Typesafe <http://www.typesafe.com/> - The software stack for applications
> that scale
>
> Twitter: @viktorklang

√iktor Ҡlang

unread,
Mar 1, 2012, 5:41:47 AM3/1/12
to Dennis Haupt, scala...@googlegroups.com, russ.p...@gmail.com
On Thu, Mar 1, 2012 at 11:38 AM, Dennis Haupt <h-s...@gmx.de> wrote:
why would you call a method that is pure and then not use its return value?
only for one: because you forgot to do it.

So that's a warning.
Same as if you have a local variable / val that is unused.

You conveniently ignored my point on having side-effecting methods with return values that are not used.
So, I guess the conclusion is: Always deal with return values.



--
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Dennis Haupt

unread,
Mar 1, 2012, 5:55:50 AM3/1/12
to "√iktor Ҡlang", russ.p...@gmail.com, scala...@googlegroups.com
methods with side effects and return values are don't get a @pure, so no problem here

-------- Original-Nachricht --------
> Datum: Thu, 1 Mar 2012 11:41:47 +0100


> Von: "√iktor Ҡlang" <viktor...@gmail.com>
> An: Dennis Haupt <h-s...@gmx.de>

> CC: scala...@googlegroups.com, russ.p...@gmail.com

√iktor Ҡlang

unread,
Mar 1, 2012, 6:04:01 AM3/1/12
to Dennis Haupt, russ.p...@gmail.com, scala...@googlegroups.com
On Thu, Mar 1, 2012 at 11:55 AM, Dennis Haupt <h-s...@gmx.de> wrote:
methods with side effects and return values are don't get a @pure, so no problem here

def makePayment(order: Order, cash: Cash): Receipt = { sideEffectsGoHere() }

I'd definitely say that not grabbing the returned receipt from the payment might be troublesome.
Your "@pure" thing is actually not expressing what you want to express.

Purity and "user must deal with returned value" is two distinctly different things. Purity means that you can use referential transparency to memoize redundant calls, etc etc.

So, my point is, since there's reason to believe that there are use-cases where impure methods whose return values are not dealt with is a bug, there should be a separate functionality to express that, which is separate from the notion of purity.

Cheers,



--
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Matthew Pocock

unread,
Mar 1, 2012, 6:47:05 AM3/1/12
to Russ P., scala-user
I had a similar family of bugs yesterday. I have an immutable case class that models a complex counter. It has methods that return updated counters. I was calling these but not replacing the var containing the counter.

var counter = Counter()

// what I wrote
counter.seenBefore // returns new counter with the seenBefore ticker incremented
counter.newItem // returns new counter with the newItem ticker incremented

// what I should have written
counter = counter.seenBefore
counter = counter.newItem

It would have been nice if I'd been warned that my original code was not achieving anything - it would have given me a strong hint that I should have been doing something with these return values. I realise this requires some support from either explicit @Pure annotations or compiler smarts to track effects, but it would IMHO remove yet another class of available bugs.

Matthew
--
Dr Matthew Pocock
Integrative Bioinformatics Group, School of Computing Science, Newcastle University
skype: matthew.pocock
tel: (0191) 2566550

Dennis Haupt

unread,
Mar 1, 2012, 9:13:22 AM3/1/12
to "√iktor Ҡlang", scala...@googlegroups.com, russ.p...@gmail.com
we were talking about two different things then

-------- Original-Nachricht --------
> Datum: Thu, 1 Mar 2012 12:04:01 +0100


> Von: "√iktor Ҡlang" <viktor...@gmail.com>
> An: Dennis Haupt <h-s...@gmx.de>

> CC: russ.p...@gmail.com, scala...@googlegroups.com

√iktor Ҡlang

unread,
Mar 1, 2012, 9:17:16 AM3/1/12
to Dennis Haupt, scala...@googlegroups.com, russ.p...@gmail.com
No, I was just untangling your concept of purity from the concept of having to deal with return values.
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Russ Paielli

unread,
Mar 1, 2012, 10:46:42 AM3/1/12
to Matthew Pocock, scala-user
My bugs were of a similar nature. In one case, the cleared altitude of
a flight was not getting updated. (Fortunately, it's a long way from
my prototype ATC software to the field, where such a bug could be
disastrous!)

I had recently changed a case class from mutable to immutable, and at
one method call I neglected to reassign the return value. A warning
would have been very helpful.

This incident makes me wonder about the value of immutability. Yeah, I
realize that immutability is important for multi-threaded
applications, but how important is it for single-threaded applications
(yes, they still exist!). Without a warning about unused return
values, I honestly don't know if I increased or decreased the chance
of error by converting a mutable class to immutable.

What about some sort of annotation on a method or function stating
that the return value is important? Then the compiler could generate a
warning or perhaps even an error if the return value is not used.

Better yet, how about an annotation for the case where the return
value is *not* important? That would make more sense to me, since I
would guess that is the less common case for nominally functional
code.

--Russ P.


--
http://RussP.us

√iktor Ҡlang

unread,
Mar 1, 2012, 10:58:18 AM3/1/12
to Russ Paielli, Matthew Pocock, scala-user
On Thu, Mar 1, 2012 at 4:46 PM, Russ Paielli <russ.p...@gmail.com> wrote:
My bugs were of a similar nature. In one case, the cleared altitude of
a flight was not getting updated. (Fortunately, it's a long way from
my prototype ATC software to the field, where such a bug could be
disastrous!)

I had recently changed a case class from mutable to immutable, and at
one method call I neglected to reassign the return value. A warning
would have been very helpful.

This incident makes me wonder about the value of immutability. Yeah, I
realize that immutability is important for multi-threaded
applications, but how important is it for single-threaded applications
(yes, they still exist!). Without a warning about unused return
values, I honestly don't know if I increased or decreased the chance
of error by converting a mutable class to immutable.

What about some sort of annotation on a method or function stating
that the return value is important? Then the compiler could generate a
warning or perhaps even an error if the return value is not used.

Better yet, how about an annotation for the case where the return
value is *not* important? That would make more sense to me, since I
would guess that is the less common case for nominally functional
code.

Or, make it so that only Unit/void is ok to ignore, always issue a warning unless. And to silence:

def ignoreResult[T](t: T): Unit = ()

ignoreResult(makePaymentAndReturnReceipt)

Alec Zorab

unread,
Mar 1, 2012, 11:05:23 AM3/1/12
to √iktor Ҡlang, Russ Paielli, Matthew Pocock, scala-user
or take a leaf from f#'s book:

makePaymentAndReturnReceipt |> ignore


2012/3/1 √iktor Ҡlang <viktor...@gmail.com>:

Russ Paielli

unread,
Mar 1, 2012, 11:17:00 AM3/1/12
to √iktor Ҡlang, Matthew Pocock, scala-user

That seems like a great idea to me. A shorter name than "ignoreResult"
might be in order for the standard library, but that's another matter.

--Russ P.

√iktor Ҡlang

unread,
Mar 1, 2012, 11:18:15 AM3/1/12
to Russ Paielli, Matthew Pocock, scala-user


2012/3/1 Russ Paielli <russ.p...@gmail.com>
def meh(a: Any): Unit = ()
 

--Russ P.

Vlad Patryshev

unread,
Mar 2, 2012, 2:54:42 AM3/2/12
to Matthew Pocock, Russ P., scala-user
On Thu, Mar 1, 2012 at 3:47 AM, Matthew Pocock <turingate...@gmail.com> wrote:
I had a similar family of bugs yesterday. I have an immutable case class that models a complex counter. It has methods that return updated counters. I was calling these but not replacing the var containing the counter.

var counter = Counter()

// what I wrote
counter.seenBefore // returns new counter with the seenBefore ticker incremented
counter.newItem // returns new counter with the newItem ticker incremented

// what I should have written
counter = counter.seenBefore
counter = counter.newItem

Right. As expected. The problem is not with dropping results, the problem is that you have a var, and you do not modify it when necessary.ou
I somehow believe that if you did not have mutables, the problem would never occur.

Matthew Pocock

unread,
Mar 2, 2012, 2:02:38 PM3/2/12
to Vlad Patryshev, Russ P., scala-user

On Thu, Mar 1, 2012 at 3:47 AM, Matthew Pocock <turingate...@gmail.com> wrote:
I had a similar family of bugs yesterday. I have an immutable case class that models a complex counter. It has methods that return updated counters. I was calling these but not replacing the var containing the counter.
 
// what I should have written

counter = counter.seenBefore
counter = counter.newItem
 

Right. As expected. The problem is not with dropping results, the problem is that you have a var, and you do not modify it when necessary.ou
I somehow believe that if you did not have mutables, the problem would never occur.

The problem *was* that I was dropping the result. The problem would still have existed if I'd been using vals. It would simply have manifested as returning counter rather than counter.newItem from the function. Same fault with the same symptom, just mediated by an errant return value rather than missing an assignment to a var, and both would be caught by an 'unused pure return value' warning.

-- 

Vlad Patryshev

unread,
Mar 2, 2012, 10:17:22 PM3/2/12
to Matthew Pocock, Russ P., scala-user
On Fri, Mar 2, 2012 at 11:02 AM, Matthew Pocock <turingate...@gmail.com> wrote:

On Thu, Mar 1, 2012 at 3:47 AM, Matthew Pocock <turingate...@gmail.com> wrote:
I had a similar family of bugs yesterday. I have an immutable case class that models a complex counter. It has methods that return updated counters. I was calling these but not replacing the var containing the counter.
 
// what I should have written

counter = counter.seenBefore
counter = counter.newItem
 

Right. As expected. The problem is not with dropping results, the problem is that you have a var, and you do not modify it when necessary.ou
I somehow believe that if you did not have mutables, the problem would never occur.

The problem *was* that I was dropping the result. The problem would still have existed if I'd been using vals. It would simply have manifested as returning counter rather than counter.newItem from the function. Same fault with the same symptom, just mediated by an errant return value rather than missing an assignment to a var, and both would be caught by an 'unused pure return value' warning.

 Although today I was in a pretty much similar position... still I disagree.
Either you need the value, or a reaction to the value, or not.

Case 1. You actually need to react to the value because it means something special.
Then the whole function depends on specific values. How can we ensure it? Say, we return an integer, and then drop some bits of that integer. But they are meaningful.

Is there a good way to ensure that meaningful values are processed properly?

Looks like an open question to me.

Russ P.

unread,
Mar 2, 2012, 11:57:23 PM3/2/12
to scala-user
On Mar 2, 7:17 pm, Vlad Patryshev <vpatrys...@gmail.com> wrote:

>  Although today I was in a pretty much similar position... still I disagree.
> Either you need the value, or a reaction to the value, or not.
>
> Case 1. You actually need to react to the value because it means something
> special.
> Then the whole function depends on specific values. How can we ensure it?
> Say, we return an integer, and then drop some bits of that integer. But
> they are meaningful.

I'm not sure what you mean by "drop some bits of that integer."

The problem here is that, since Scala allows both mutable and
immutable objects, the difference between mutating an object in place
and returning a mutated copy of it is easy to overlook. For example,
given the line

aList.sorted

someone might mistakenly think that the List is sorted in place. Yeah,
we all know that a Scala List is immutable, but that is just a trivial
example. In many cases the error could be subtle and could lurk for a
long time or require a time-consuming debugging session. This sort of
thing happens all the time.

I say provide at least a compiler *option* to warn of any unused
return value other than "Unit." And provide a simple function in the
standard library to suppress the warning as Victor suggested
yesterday. Call it "drop", "discard", "ignore", or something like
that.

--Russ P.

Francois

unread,
Mar 3, 2012, 5:12:47 AM3/3/12
to Russ P., scala-user
On 03/03/2012 05:57, Russ P. wrote:
> [...]

> I say provide at least a compiler *option* to warn of any unused
> return value other than "Unit." And provide a simple function in the
> standard library to suppress the warning as Victor suggested
> yesterday. Call it "drop", "discard", "ignore", or something like
> that. --Russ P.

I, to, fall on that trap several times (at least two with a
corresponding painful debugging session). Well, perhaps in my case, it
also involves valued block whose value wasn't use and should have been
(I think it was due to bad formatting, i.e bad place for a return, or a
blank line where it should not have been).

If you open a ticket for that, I will +1 it (even if it's a virtual +1),

--
Francois ARMAND
http://fanf42.blogspot.com
http://www.normation.com

HamsterofDeath

unread,
Mar 3, 2012, 6:06:42 AM3/3/12
to scala...@googlegroups.com
i don't know about eclipse, but intellij (the free edition) can identify
all unused local values/variables. maybe using an ide instead of a pure
text editor is an option? even if it's just for inspecting the
code/debugging instead of coding (i must admit i do not understand why
one would not use an ide and prefer a text editor)

Francois

unread,
Mar 3, 2012, 6:46:18 AM3/3/12
to HamsterofDeath, scala...@googlegroups.com
On 03/03/2012 12:06, HamsterofDeath wrote:
[...]

> i don't know about eclipse, but intellij (the free edition) can identify
> all unused local values/variables. maybe using an ide instead of a pure
> text editor is an option? even if it's just for inspecting the
> code/debugging instead of coding (i must admit i do not understand why
> one would not use an ide and prefer a text editor)

AFAIK, Eclipse can't, at least in 2.0.
But infortunately, I just can't use IntelliJ, there is something in me
that make me want to throw my laptop each time I spend more than 5
minutes with IntelliJ, and neither doctors nor shamans know what it is.

HamsterofDeath

unread,
Mar 3, 2012, 7:16:35 AM3/3/12
to Francois, scala...@googlegroups.com
strange. just watching the intellij ui makes all my pain go away

Vlad Patryshev

unread,
Mar 3, 2012, 11:31:26 PM3/3/12
to Russ P., scala-user
On Fri, Mar 2, 2012 at 8:57 PM, Russ P. <russ.p...@gmail.com> wrote:
On Mar 2, 7:17 pm, Vlad Patryshev <vpatrys...@gmail.com> wrote:

>  Although today I was in a pretty much similar position... still I disagree.
> Either you need the value, or a reaction to the value, or not.
>
> Case 1. You actually need to react to the value because it means something
> special.
> Then the whole function depends on specific values. How can we ensure it?
> Say, we return an integer, and then drop some bits of that integer. But
> they are meaningful.

I'm not sure what you mean by "drop some bits of that integer."

There are many occasions when you can do this. Long to Int, drop the sign, anding with a mask to get only the bits we are interested in...

Oh, and also, say a function returns a tuple. Yes, we keep the tuple, but we only check one component.
 

The problem here is that, since Scala allows both mutable and
immutable objects, the difference between mutating an object in place
and returning a mutated copy of it is easy to overlook. For example,
given the line

aList.sorted

someone might mistakenly think that the List is sorted in place. Yeah,
we all know that a Scala List is immutable, but that is just a trivial
example. In many cases the error could be subtle and could lurk for a
long time or require a time-consuming debugging session. This sort of
thing happens all the time.

Yes, this can happen - but seems like again we are in the scary realm of mutables.
 

I say provide at least a compiler *option* to warn of any unused
return value other than "Unit." And provide a simple function in the
standard library to suppress the warning as Victor suggested
yesterday. Call it "drop", "discard", "ignore", or something like
that.

Well, I should agree now. Having optional additional checks, it may make sense.
-Vlad

Vlad Patryshev

unread,
Mar 3, 2012, 11:33:34 PM3/3/12
to Francois, HamsterofDeath, scala...@googlegroups.com
But infortunately, I just can't use IntelliJ, there is something in me that make me want to throw my laptop each time I spend more than 5 minutes with IntelliJ, and neither doctors nor shamans know what it is.

Russophobia?!

IntelliJ was made in St.Petersburg for the people of St.Petersburg. Personally I feel so at home with IJ, my fingers don't need any training, all the keys are in their historical places.

Francois

unread,
Mar 4, 2012, 12:30:45 PM3/4/12
to Vlad Patryshev, scala-user@googlegroups.com >> scala-user
I'm pretty sure the origin of the company behind IntelliJ has nothing to do with that. But clearly, I can't beer it's look'n'feel, and even when trying to use it for a long time, I feels... well, not for me.

Thanks,

Tony Morris

unread,
Mar 2, 2012, 10:18:46 PM3/2/12
to scala...@googlegroups.com
On 02/03/12 17:54, Vlad Patryshev wrote:
> the problem
> is that you have a var
Welcome.

--
Tony Morris
http://tmorris.net/


Reply all
Reply to author
Forward
0 new messages