Open jimmydivvy opened 9 years ago
Generally I want to disable withFilter. Is that enough for this? https://github.com/puffnfresh/wartremover/issues/55
My understanding is that withFilter
is just a non-strict version of filter
, and in this context they'd both be valid or invalid together. (Although it sounds like there may be separate issues with withFilter
in #55?)
In Haskell terms filter/withFilter
is only relevant on a type with a MonadPlus instance. There is no valid mzero
possible for a Future, so Future#filter is (in my opinion) always incorrect and should be a compile failure.
Many other types (List, Vector, Seq, etc) do have valid mzero instances so filter
and withFilter
are valid.
The current behaviour of Future#filter
is to return a failed Future
containing NoSuchElementException: Future.filter predicate is not satisfied
. Due to trampolining the resulting stack trace has no meaningful information whatsoever.
This has actually tripped me up pretty severely in production, and the only way to track down the offending line was to write a custom rule for wartremover (Due to the lack of useful stack traces). I can throw this up in a PR if you'd like, although it was pretty much just a copy-paste-tweak on the rule for Option#get
tl;dr Not only is Future#filter inherently unsafe and always incorrect, but it fails in a way that's virtually impossible to figure out where in the codebase it actually happened, is very difficult to grep for, and looks completely innocuous on the surface, especially when de-sugared from if
in a for-comprehension.
@jimmydivvy sounds like filter
is broken, :+1: for a PR!
lot's of :+1: for this... my book covers all the horror of for
in chapter two https://leanpub.com/fp-scala-mortals
The
filter
andwithFilter
methods on scala.concurrent.Future simply cause the entire future to fail with an unhelpful error message and no meaningful stack trace.There doesn't appear to be any valid implementation of
filter
possible for this type - should this be added as a rule in WartRemover?