Re: Failure should probably extend Try[Nothing], as shown in first lecture of Principles of Reactive Programming

Rex Kerr <[email protected]>
Newsgroups gmane.comp.lang.scala
Message-ID <CAP_xLa1FW1+QOR32WfzpkXc-=+taehOxT3r1RCdoa2J+fRBmiA@mail.gmail.com>
Failure right now is an example of #2.

  scala> val fail = scala.util.Failure[Long](new Exception)
  fail: scala.util.Failure[Long] = Failure(java.lang.Exception)

This can be handy because when you have methods like

  def orDefault[A](t: Try[A]) = t match { case Success(a) => a; case _ =>
null.asInstanceOf[A] }

you can pass `fail` right in without having to specify what the default
type was supposed to be:

  scala> orDefault(fail)
  res2: Long = 0

This is less useful, I think, than not having to worry about the correct
type when you already know you're in the wrong branch, but it's not
completely useless.

(It would be even more useful if there were more easy ways to end up with a
properly typed Failure.  After all, this really should work; the compiler
knows everything it needs to so that it does:

  Try(2) match {
    case s: Success => 0
    case f: Failure => orDefault(f)
  }

but alas, it insists on making you fill in the [Int] for both Success and
Failure (though it's happy to do it for you on the unapply).)

  --Rex


On Tue, May 12, 2015 at 12:21 PM, Naftoli Gugenheim <[email protected]>
wrote:

> Can you give an example of 2?
>
> On Tue, May 12, 2015 at 2:02 PM Rex Kerr <[email protected]> wrote:
>
>> I basically agree with you, but note that there are three concepts that
>> are useful:
>>   1. Try[A]  --  I might have an A, or I might have a failure
>>   2. Failure[A]  --  I tried to get an A, but I have a failure instead
>>   3. Failure  --  I don't know or care what I tried to get, but I know it
>> didn't work
>>
>> The current implementation gives you 1. and 2., but not 3.; I agree,
>> especially given the covariance of Try and the methods on Try, that 1. and
>> 3. are the more useful pair.  But occasionally it's nice to know what the
>> success type should have been (e.g. because you want to dispatch on it with
>> a type class), even though you're in the failure case.  (Refactoring is
>> possible, but it shifts work from the compiler to the programmer.)
>>
>> So I agree that the other choice would have been better, but there is at
>> least _some_ advantage to the way it is.
>>
>>   --Rex
>>
>>
>>
>> On Tue, May 12, 2015 at 8:34 AM, Christoph Neijenhuis <
>> [email protected]> wrote:
>>
>>> In the lecture Monads (slide 22), Try with Success and Failure was
>>> introduced. In particular, Failure was defined as:
>>>
>>> case class Failure(ex: Exception) extends *Try[Nothing]*
>>>
>>> However, in scala.util it is actually defined this way:
>>>
>>> final case class Failure[+T](exception: Throwable) extends *Try[T]*
>>>
>>> I tried to figure out why Failure would remain a generic class while
>>> e.g. None doesn't, but I couldn't come up with an explanation. In fact, I'd
>>> argue Failure, like None, should use the bottom type for two reasons:
>>>
>>> 1. When dealing with a Failure, one doesn't have to worry about a
>>> generic type that doesn't make any difference anyway. E.g. when pattern
>>> matching:
>>>
>>> case None => ... // Compiles
>>> case Failure => ... // Does not compile: "pattern type is incompatible
>>> with expected type"
>>> case Failure[_] => ... // Compiles, but is unintuitive when working
>>> with None previously
>>>
>>> Or when passing a failure along, one has to cast to the "correct"
>>> generic type (seen in the implementation of Failure itself, but this
>>> example is from the implementation of Future)
>>>
>>> case f: Failure[_] => p complete f.asInstanceOf[Failure[(T, U)]]
>>>
>>> When using the bottom type, this simply becomes:
>>>
>>> case f: Failure => p complete f
>>>
>>> 2. The method signatures and the generated scaladoc are more obvious.
>>> E.g. the get method of None is defined as:
>>>
>>> def get: Nothing
>>>
>>> whereas the get method of Failure is:
>>>
>>> def get: T
>>>
>>> I'd argue in the case of None, it's much easier to figure out one
>>> shouldn't use the get method based on the signature.
>>>
>>>
>>> I did go forward and changed the implementation of Failure:
>>> https://github.com/cneijenhuis/scala/commit/e03c6bda9d6c92b764f540278d718098e7778791#diff-a2cc47b875d07181ae9e71681fb3f07dL211
>>> But the resulting class is obviously not compatible with the previous
>>> version. I fixed the resulting errors in Future and JavapClass as well -
>>> these changes also show nicely why I think it's benificial to use Nothing.
>>>
>>> Anyway, my questions are:
>>> Is there a reason I missed why Failure should really be a generic class
>>> and not extend Try[Nothing]?
>>> If not - is there any chance I can submit a pull request with this?
>>> After all, it's a breaking change... but I do see those are scheduled for
>>> "Aida", and, while Try isn't a collection, this change would fit with the
>>> theme of "we want to make them even easier to use" :-)
>>>
>>> Best,
>>> Christoph
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "scala-language" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>  --
>> You received this message because you are subscribed to the Google Groups
>> "scala-language" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>  --
> You received this message because you are subscribed to the Google Groups
> "scala-language" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.