Compiler warnings on discarded expressions?

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Compiler warnings on discarded expressions?

Adam Warski
Hello,

the compiler flag -Ywarn-value-discard (+ fatal warnings) is very helpful in avoiding quite subtle bugs which can occur due to the to-unit value coercion (a "classical" example in my case is doing a `map` instead of a `flatMap` when the result is `Future[Unit]`).

However, what about discarded expressions/values? E.g. this causes a warning:

scala> def g(): Int = 42
g: ()Int

scala> def h(): Unit = { g() }
<console>:8: warning: discarded non-Unit value
       def h(): Unit = { g() }
                          ^
h: ()Unit

But this doesn't:

scala> def h(): Unit = { g(); () }
h: ()Unit

Especially when doing more "functional"-style Scala, when most of the methods are pure, a discarded expression or value is usually a bug.
A less abstract example of what *might* be a bug is discarding a created future:

def f(): String = {
  Future { /* computation */ }
  "ok"
}

While this might be perfectly ok, I would say that usually in "production" code you would want to do something with the future, even if it's logging a potential error in onComplete.
When moving to more "functional" structures, such as scalaz/fs2's Task, this gets even worse:

def f(): String {
  Task { /* computation */ }
  "ok"
}

Now this definitely is a bug - there's no point in creating a Task which is never run. And so on ...

I expected this to be a well-discussed problem, but I only found a relatively unpopular SO question (http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value) and a half-finished compiler plugin created by a friend which performs such a check. 

Question is: is adding discarded expression warnings a fundamentally bad idea? Maybe it would cause a flood of warnings in regular Scala code (though I don't think I see this happening)? 
Or should I get to work and finish the plugin? ;)

-- 
Adam Warski

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Compiler warnings on discarded expressions?

Jed Wesley-Smith
yeah, the warning is very inconsistent and doesn't catch a number of important cases. It is better than nothing, but not as good as it could be.

On 3 December 2016 at 07:07, Adam Warski <[hidden email]> wrote:
Hello,

the compiler flag -Ywarn-value-discard (+ fatal warnings) is very helpful in avoiding quite subtle bugs which can occur due to the to-unit value coercion (a "classical" example in my case is doing a `map` instead of a `flatMap` when the result is `Future[Unit]`).

However, what about discarded expressions/values? E.g. this causes a warning:

scala> def g(): Int = 42
g: ()Int

scala> def h(): Unit = { g() }
<console>:8: warning: discarded non-Unit value
       def h(): Unit = { g() }
                          ^
h: ()Unit

But this doesn't:

scala> def h(): Unit = { g(); () }
h: ()Unit

Especially when doing more "functional"-style Scala, when most of the methods are pure, a discarded expression or value is usually a bug.
A less abstract example of what *might* be a bug is discarding a created future:

def f(): String = {
  Future { /* computation */ }
  "ok"
}

While this might be perfectly ok, I would say that usually in "production" code you would want to do something with the future, even if it's logging a potential error in onComplete.
When moving to more "functional" structures, such as scalaz/fs2's Task, this gets even worse:

def f(): String {
  Task { /* computation */ }
  "ok"
}

Now this definitely is a bug - there's no point in creating a Task which is never run. And so on ...

I expected this to be a well-discussed problem, but I only found a relatively unpopular SO question (http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value) and a half-finished compiler plugin created by a friend which performs such a check. 

Question is: is adding discarded expression warnings a fundamentally bad idea? Maybe it would cause a flood of warnings in regular Scala code (though I don't think I see this happening)? 
Or should I get to work and finish the plugin? ;)

-- 
Adam Warski

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Compiler warnings on discarded expressions?

som-snytt
In reply to this post by Adam Warski

Someone has suggested an annotation for types of values that must be consumed, such as you describe.

Current thinking is that warnings belong in a tool like scala-abide. The reason is that they are difficult to tune just right. (That makes them a maintenance issue and also tied to the compiler release cycle.)

For example, someone asked that -Ywarn-value-discard not warn for the following:

def add(x: X): Unit = listBuffer += x

Otherwise, that particular warning is very narrowly scoped and therefore consistent.

The following warns ordinarily, when it can feebly detect a pure expression:

scala> def f(): Unit = { 42 ;() }
<console>:11: warning: a pure expression does nothing in statement position
def f(): Unit = { 42 ;() }
^
f: ()Unit

I have a PR for improving -Ywarn-unused so you can tell it what to warn about (imports, params, implicits, etc):

https://github.com/scala/scala/pull/5402/files

Under that regime (where you can turn it off), it's not unreasonable to -Ywarn-unused:value. Maybe create a ticket for it.

I have not heard if they want to accept that PR or push all warning out to Abide.

On Friday, December 2, 2016 at 12:07:13 PM UTC-8, Adam Warski wrote:
Hello,

the compiler flag -Ywarn-value-discard (+ fatal warnings) is very helpful in avoiding quite subtle bugs which can occur due to the to-unit value coercion (a "classical" example in my case is doing a `map` instead of a `flatMap` when the result is `Future[Unit]`).

However, what about discarded expressions/values? E.g. this causes a warning:

scala> def g(): Int = 42
g: ()Int

scala> def h(): Unit = { g() }
<console>:8: warning: discarded non-Unit value
       def h(): Unit = { g() }
                          ^
h: ()Unit

But this doesn't:

scala> def h(): Unit = { g(); () }
h: ()Unit

Especially when doing more "functional"-style Scala, when most of the methods are pure, a discarded expression or value is usually a bug.
A less abstract example of what *might* be a bug is discarding a created future:

def f(): String = {
  Future { /* computation */ }
  "ok"
}

While this might be perfectly ok, I would say that usually in "production" code you would want to do something with the future, even if it's logging a potential error in onComplete.
When moving to more "functional" structures, such as scalaz/fs2's Task, this gets even worse:

def f(): String {
  Task { /* computation */ }
  "ok"
}

Now this definitely is a bug - there's no point in creating a Task which is never run. And so on ...

I expected this to be a well-discussed problem, but I only found a relatively unpopular SO question (<a href="http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fstackoverflow.com%2Fquestions%2F17691487%2Fscala-does-not-warn-about-unused-computation-or-value\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEMMEpLOWDLdRLowMj_IwObgEr7WQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fstackoverflow.com%2Fquestions%2F17691487%2Fscala-does-not-warn-about-unused-computation-or-value\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEMMEpLOWDLdRLowMj_IwObgEr7WQ&#39;;return true;">http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value) and a half-finished compiler plugin created by a friend which performs such a check. 

Question is: is adding discarded expression warnings a fundamentally bad idea? Maybe it would cause a flood of warnings in regular Scala code (though I don't think I see this happening)? 
Or should I get to work and finish the plugin? ;)

-- 
Adam Warski

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Compiler warnings on discarded expressions?

Adriaan Moors-7
Until abide takes off, we will take PRs in scala/scala for improvements of these compiler warnings. One might say that as long as we take such PRs, abide won't gain traction, but I think that's selling it short (I mean, with a name like that, how can you resist?).

On Mon, Dec 5, 2016 at 8:44 AM som-snytt <[hidden email]> wrote:

Someone has suggested an annotation for types of values that must be consumed, such as you describe.

Current thinking is that warnings belong in a tool like scala-abide. The reason is that they are difficult to tune just right. (That makes them a maintenance issue and also tied to the compiler release cycle.)

For example, someone asked that -Ywarn-value-discard not warn for the following:

def add(x: X): Unit = listBuffer += x

Otherwise, that particular warning is very narrowly scoped and therefore consistent.

The following warns ordinarily, when it can feebly detect a pure expression:

scala> def f(): Unit = { 42 ;() }
<console>:11: warning: a pure expression does nothing in statement position
def f(): Unit = { 42 ;() }
^
f: ()Unit

I have a PR for improving -Ywarn-unused so you can tell it what to warn about (imports, params, implicits, etc):

https://github.com/scala/scala/pull/5402/files

Under that regime (where you can turn it off), it's not unreasonable to -Ywarn-unused:value. Maybe create a ticket for it.

I have not heard if they want to accept that PR or push all warning out to Abide.


On Friday, December 2, 2016 at 12:07:13 PM UTC-8, Adam Warski wrote:
Hello,

the compiler flag -Ywarn-value-discard (+ fatal warnings) is very helpful in avoiding quite subtle bugs which can occur due to the to-unit value coercion (a "classical" example in my case is doing a `map` instead of a `flatMap` when the result is `Future[Unit]`).

However, what about discarded expressions/values? E.g. this causes a warning:

scala> def g(): Int = 42
g: ()Int

scala> def h(): Unit = { g() }
<console>:8: warning: discarded non-Unit value
       def h(): Unit = { g() }
                          ^
h: ()Unit

But this doesn't:

scala> def h(): Unit = { g(); () }
h: ()Unit

Especially when doing more "functional"-style Scala, when most of the methods are pure, a discarded expression or value is usually a bug.
A less abstract example of what *might* be a bug is discarding a created future:

def f(): String = {
  Future { /* computation */ }
  "ok"
}

While this might be perfectly ok, I would say that usually in "production" code you would want to do something with the future, even if it's logging a potential error in onComplete.
When moving to more "functional" structures, such as scalaz/fs2's Task, this gets even worse:

def f(): String {
  Task { /* computation */ }
  "ok"
}

Now this definitely is a bug - there's no point in creating a Task which is never run. And so on ...

I expected this to be a well-discussed problem, but I only found a relatively unpopular SO question (http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value) and a half-finished compiler plugin created by a friend which performs such a check. 

Question is: is adding discarded expression warnings a fundamentally bad idea? Maybe it would cause a flood of warnings in regular Scala code (though I don't think I see this happening)? 
Or should I get to work and finish the plugin? ;)

-- 
Adam Warski

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Compiler warnings on discarded expressions?

Oliver Ruebenacker
In reply to this post by Adam Warski

     Hello,

  What kind of reasoning would the compiler use to know that creating a Task without doing anything with it is a a bad thing?

     Best, Oliver

On Fri, Dec 2, 2016 at 3:07 PM, Adam Warski <[hidden email]> wrote:
Hello,

the compiler flag -Ywarn-value-discard (+ fatal warnings) is very helpful in avoiding quite subtle bugs which can occur due to the to-unit value coercion (a "classical" example in my case is doing a `map` instead of a `flatMap` when the result is `Future[Unit]`).

However, what about discarded expressions/values? E.g. this causes a warning:

scala> def g(): Int = 42
g: ()Int

scala> def h(): Unit = { g() }
<console>:8: warning: discarded non-Unit value
       def h(): Unit = { g() }
                          ^
h: ()Unit

But this doesn't:

scala> def h(): Unit = { g(); () }
h: ()Unit

Especially when doing more "functional"-style Scala, when most of the methods are pure, a discarded expression or value is usually a bug.
A less abstract example of what *might* be a bug is discarding a created future:

def f(): String = {
  Future { /* computation */ }
  "ok"
}

While this might be perfectly ok, I would say that usually in "production" code you would want to do something with the future, even if it's logging a potential error in onComplete.
When moving to more "functional" structures, such as scalaz/fs2's Task, this gets even worse:

def f(): String {
  Task { /* computation */ }
  "ok"
}

Now this definitely is a bug - there's no point in creating a Task which is never run. And so on ...

I expected this to be a well-discussed problem, but I only found a relatively unpopular SO question (http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value) and a half-finished compiler plugin created by a friend which performs such a check. 

Question is: is adding discarded expression warnings a fundamentally bad idea? Maybe it would cause a flood of warnings in regular Scala code (though I don't think I see this happening)? 
Or should I get to work and finish the plugin? ;)

-- 
Adam Warski

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.



--
Oliver Ruebenacker
Senior Software Engineer, Diabetes Portal, Broad Institute

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Compiler warnings on discarded expressions?

Oliver Ruebenacker
In reply to this post by Adam Warski

     Hello,

  Two or three years ago, I was pointed to some Scala library as proof that you could do GUIs in functional style. Unfortunately, I forgot how it was called and have not been able to find it quickly on Google.

  In that library, if you wanted some GUI element to appear, you just created an object that represented that element. No need to do anything with that object.

     Best, Oliver

On Fri, Dec 2, 2016 at 3:07 PM, Adam Warski <[hidden email]> wrote:
Hello,

the compiler flag -Ywarn-value-discard (+ fatal warnings) is very helpful in avoiding quite subtle bugs which can occur due to the to-unit value coercion (a "classical" example in my case is doing a `map` instead of a `flatMap` when the result is `Future[Unit]`).

However, what about discarded expressions/values? E.g. this causes a warning:

scala> def g(): Int = 42
g: ()Int

scala> def h(): Unit = { g() }
<console>:8: warning: discarded non-Unit value
       def h(): Unit = { g() }
                          ^
h: ()Unit

But this doesn't:

scala> def h(): Unit = { g(); () }
h: ()Unit

Especially when doing more "functional"-style Scala, when most of the methods are pure, a discarded expression or value is usually a bug.
A less abstract example of what *might* be a bug is discarding a created future:

def f(): String = {
  Future { /* computation */ }
  "ok"
}

While this might be perfectly ok, I would say that usually in "production" code you would want to do something with the future, even if it's logging a potential error in onComplete.
When moving to more "functional" structures, such as scalaz/fs2's Task, this gets even worse:

def f(): String {
  Task { /* computation */ }
  "ok"
}

Now this definitely is a bug - there's no point in creating a Task which is never run. And so on ...

I expected this to be a well-discussed problem, but I only found a relatively unpopular SO question (http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value) and a half-finished compiler plugin created by a friend which performs such a check. 

Question is: is adding discarded expression warnings a fundamentally bad idea? Maybe it would cause a flood of warnings in regular Scala code (though I don't think I see this happening)? 
Or should I get to work and finish the plugin? ;)

-- 
Adam Warski

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.



--
Oliver Ruebenacker
Senior Software Engineer, Diabetes Portal, Broad Institute

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Compiler warnings on discarded expressions?

Adam Warski
In reply to this post by som-snytt
Thanks for the pointer to abide! This looks more like a meta-plugin which can be customised using specific rules, so maybe one can create rules to detect discarded expressions - I'll take a look into that.

But having warnings separated from the compiler definitely makes sense - esp if it would be an "offical" tool.

I can definitely see some situations where you would want the value-discard warning to be disabled, but that could be probably tuned with an annotation? Or maybe the abide rules could be created only so that "known" pure values (e.g. probably everything in scalaz.* or cats.*) would trigger warnings.

Adam

On Monday, December 5, 2016 at 8:44:36 AM UTC+1, som-snytt wrote:

Someone has suggested an annotation for types of values that must be consumed, such as you describe.

Current thinking is that warnings belong in a tool like scala-abide. The reason is that they are difficult to tune just right. (That makes them a maintenance issue and also tied to the compiler release cycle.)

For example, someone asked that -Ywarn-value-discard not warn for the following:

def add(x: X): Unit = listBuffer += x

Otherwise, that particular warning is very narrowly scoped and therefore consistent.

The following warns ordinarily, when it can feebly detect a pure expression:

scala> def f(): Unit = { 42 ;() }
<console>:11: warning: a pure expression does nothing in statement position
def f(): Unit = { 42 ;() }
^
f: ()Unit

I have a PR for improving -Ywarn-unused so you can tell it what to warn about (imports, params, implicits, etc):

<a href="https://github.com/scala/scala/pull/5402/files" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fscala%2Fscala%2Fpull%2F5402%2Ffiles\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFPW9lXiexzCO1079-FNzhmHkDKig&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fscala%2Fscala%2Fpull%2F5402%2Ffiles\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFPW9lXiexzCO1079-FNzhmHkDKig&#39;;return true;">https://github.com/scala/scala/pull/5402/files

Under that regime (where you can turn it off), it's not unreasonable to -Ywarn-unused:value. Maybe create a ticket for it.

I have not heard if they want to accept that PR or push all warning out to Abide.

On Friday, December 2, 2016 at 12:07:13 PM UTC-8, Adam Warski wrote:
Hello,

the compiler flag -Ywarn-value-discard (+ fatal warnings) is very helpful in avoiding quite subtle bugs which can occur due to the to-unit value coercion (a "classical" example in my case is doing a `map` instead of a `flatMap` when the result is `Future[Unit]`).

However, what about discarded expressions/values? E.g. this causes a warning:

scala> def g(): Int = 42
g: ()Int

scala> def h(): Unit = { g() }
<console>:8: warning: discarded non-Unit value
       def h(): Unit = { g() }
                          ^
h: ()Unit

But this doesn't:

scala> def h(): Unit = { g(); () }
h: ()Unit

Especially when doing more "functional"-style Scala, when most of the methods are pure, a discarded expression or value is usually a bug.
A less abstract example of what *might* be a bug is discarding a created future:

def f(): String = {
  Future { /* computation */ }
  "ok"
}

While this might be perfectly ok, I would say that usually in "production" code you would want to do something with the future, even if it's logging a potential error in onComplete.
When moving to more "functional" structures, such as scalaz/fs2's Task, this gets even worse:

def f(): String {
  Task { /* computation */ }
  "ok"
}

Now this definitely is a bug - there's no point in creating a Task which is never run. And so on ...

I expected this to be a well-discussed problem, but I only found a relatively unpopular SO question (<a href="http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fstackoverflow.com%2Fquestions%2F17691487%2Fscala-does-not-warn-about-unused-computation-or-value\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEMMEpLOWDLdRLowMj_IwObgEr7WQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fstackoverflow.com%2Fquestions%2F17691487%2Fscala-does-not-warn-about-unused-computation-or-value\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEMMEpLOWDLdRLowMj_IwObgEr7WQ&#39;;return true;">http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value) and a half-finished compiler plugin created by a friend which performs such a check. 

Question is: is adding discarded expression warnings a fundamentally bad idea? Maybe it would cause a flood of warnings in regular Scala code (though I don't think I see this happening)? 
Or should I get to work and finish the plugin? ;)

-- 
Adam Warski

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Compiler warnings on discarded expressions?

Adam Warski
In reply to this post by Oliver Ruebenacker
In general it's not possible for the compiler to know that. It could make good guesses ... but as I wrote in another post, it would probably make sense to selectively enable or disable the value-discard warning.

The choice is of course what should be the default - enabled or disabled; and that might differ per-project. A project written in FP-mostly style would choose a default "enabled". A project which uses a lot of mutables values would probably by default disable the warning.

Adam

On Monday, December 5, 2016 at 4:38:49 PM UTC+1, Oliver Ruebenacker wrote:

     Hello,

  What kind of reasoning would the compiler use to know that creating a Task without doing anything with it is a a bad thing?

     Best, Oliver

On Fri, Dec 2, 2016 at 3:07 PM, Adam Warski <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="7JKtKJjsBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">ad...@...> wrote:
Hello,

the compiler flag -Ywarn-value-discard (+ fatal warnings) is very helpful in avoiding quite subtle bugs which can occur due to the to-unit value coercion (a "classical" example in my case is doing a `map` instead of a `flatMap` when the result is `Future[Unit]`).

However, what about discarded expressions/values? E.g. this causes a warning:

scala> def g(): Int = 42
g: ()Int

scala> def h(): Unit = { g() }
<console>:8: warning: discarded non-Unit value
       def h(): Unit = { g() }
                          ^
h: ()Unit

But this doesn't:

scala> def h(): Unit = { g(); () }
h: ()Unit

Especially when doing more "functional"-style Scala, when most of the methods are pure, a discarded expression or value is usually a bug.
A less abstract example of what *might* be a bug is discarding a created future:

def f(): String = {
  Future { /* computation */ }
  "ok"
}

While this might be perfectly ok, I would say that usually in "production" code you would want to do something with the future, even if it's logging a potential error in onComplete.
When moving to more "functional" structures, such as scalaz/fs2's Task, this gets even worse:

def f(): String {
  Task { /* computation */ }
  "ok"
}

Now this definitely is a bug - there's no point in creating a Task which is never run. And so on ...

I expected this to be a well-discussed problem, but I only found a relatively unpopular SO question (<a href="http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fstackoverflow.com%2Fquestions%2F17691487%2Fscala-does-not-warn-about-unused-computation-or-value\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEMMEpLOWDLdRLowMj_IwObgEr7WQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fstackoverflow.com%2Fquestions%2F17691487%2Fscala-does-not-warn-about-unused-computation-or-value\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEMMEpLOWDLdRLowMj_IwObgEr7WQ&#39;;return true;">http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value) and a half-finished compiler plugin created by a friend which performs such a check. 

Question is: is adding discarded expression warnings a fundamentally bad idea? Maybe it would cause a flood of warnings in regular Scala code (though I don't think I see this happening)? 
Or should I get to work and finish the plugin? ;)

-- 
Adam Warski

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="7JKtKJjsBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">scala-user+...@googlegroups.com.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.



--
Oliver Ruebenacker
Senior Software Engineer, <a href="http://www.type2diabetesgenetics.org/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.type2diabetesgenetics.org%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVE8xTGqlzANyuan2sVDo75uy-vA&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.type2diabetesgenetics.org%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVE8xTGqlzANyuan2sVDo75uy-vA&#39;;return true;">Diabetes Portal, <a href="http://www.broadinstitute.org/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.broadinstitute.org%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHloBLjHUP5Yhb6LyVOZ-JE5b4Y5A&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.broadinstitute.org%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHloBLjHUP5Yhb6LyVOZ-JE5b4Y5A&#39;;return true;">Broad Institute

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Compiler warnings on discarded expressions?

mikael.staldal
In reply to this post by Adam Warski
Such warning would be useful, but then we need a way to explicitly discard a value/expression and avoid the warning.

Currently { g(); () } is a way to explicitly discard and avoid the warning.


On Friday, December 2, 2016 at 9:07:13 PM UTC+1, Adam Warski wrote:
Hello,

the compiler flag -Ywarn-value-discard (+ fatal warnings) is very helpful in avoiding quite subtle bugs which can occur due to the to-unit value coercion (a "classical" example in my case is doing a `map` instead of a `flatMap` when the result is `Future[Unit]`).

However, what about discarded expressions/values? E.g. this causes a warning:

scala> def g(): Int = 42
g: ()Int

scala> def h(): Unit = { g() }
<console>:8: warning: discarded non-Unit value
       def h(): Unit = { g() }
                          ^
h: ()Unit

But this doesn't:

scala> def h(): Unit = { g(); () }
h: ()Unit

Especially when doing more "functional"-style Scala, when most of the methods are pure, a discarded expression or value is usually a bug.
A less abstract example of what *might* be a bug is discarding a created future:

def f(): String = {
  Future { /* computation */ }
  "ok"
}

While this might be perfectly ok, I would say that usually in "production" code you would want to do something with the future, even if it's logging a potential error in onComplete.
When moving to more "functional" structures, such as scalaz/fs2's Task, this gets even worse:

def f(): String {
  Task { /* computation */ }
  "ok"
}

Now this definitely is a bug - there's no point in creating a Task which is never run. And so on ...

I expected this to be a well-discussed problem, but I only found a relatively unpopular SO question (<a href="http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fstackoverflow.com%2Fquestions%2F17691487%2Fscala-does-not-warn-about-unused-computation-or-value\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEMMEpLOWDLdRLowMj_IwObgEr7WQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fstackoverflow.com%2Fquestions%2F17691487%2Fscala-does-not-warn-about-unused-computation-or-value\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEMMEpLOWDLdRLowMj_IwObgEr7WQ&#39;;return true;">http://stackoverflow.com/questions/17691487/scala-does-not-warn-about-unused-computation-or-value) and a half-finished compiler plugin created by a friend which performs such a check. 

Question is: is adding discarded expression warnings a fundamentally bad idea? Maybe it would cause a flood of warnings in regular Scala code (though I don't think I see this happening)? 
Or should I get to work and finish the plugin? ;)

-- 
Adam Warski

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.