scala / docs.scala-lang

The Scala Documentation website
http://docs.scala-lang.org
559 stars 1.02k forks source link

[Doc] recover and recoverWith overview needs more differentiation #2297

Open plouj opened 2 years ago

plouj commented 2 years ago

Right now https://github.com/scala/docs.scala-lang/blob/6ef51ab1677fa1f7c311d06db164911d08bedc5c/_overviews/core/futures.md?plain=1#L628 starts the same for both recover and recoverWith:

The recover combinator creates a new future which holds the same result as the original future if it completed successfully

vs

The recoverWith combinator creates a new future which holds the same result as the original future if it completed successfully

which is rather confusing to beginners.

The first real differentiation appears in the middle of the paragraphs:

If it maps the Throwable to some value, then the new future is successfully completed with that value.

vs

If it maps the Throwable to some future, then this future is completed with the result of that future.

which took me a while to find and I personally struggled to parse because I couldn't tell if there is a typo somewhere of text is precisely correct and needs to be interpreted as such.

Assuming the text is correct, perhaps it would help if the first sentence of the second paragraph would say something like:

The recoverWith combinator also creates a new future which ...

and later on in the same paragraph, something like

If it maps the Throwable to some future, then, unlike what happens with recover, this future is completed with the result of that future.

Or perhaps someone can come up with a much more clear wording than I can :) https://stackoverflow.com/a/36585703/1517753 ?

Thank you for this documentation!

preveen-stack commented 1 year ago

I guess a bit more context is useful here from https://github.com/scala/docs.scala-lang/blob/6ef51ab1677fa1f7c311d06db164911d08bedc5c/_overviews/core/futures.md?plain=1#L620

The recover combinator creates a new future which holds the same result as the original future if it completed successfully. If it did not then the partial function argument is applied to the Throwable which failed the original future. If it maps the Throwable to some value, then the new future is successfully completed with that value. If the partial function is not defined on that Throwable, then the resulting future is failed with the same Throwable.

The recoverWith combinator creates a new future which holds the same result as the original future if it completed successfully. Otherwise, the partial function is applied to the Throwable which failed the original future. If it maps the Throwable to some future, then this future is completed with the result of that future. Its relation to recover is similar to that of flatMap to map.

Thanks for posting this. Had a nice read seeing functional programming principles in action.

However, I feel the effort the somebody would spend understanding the difference here, will get them much further in solidifying their knowledge how functional programming is getting applied to real scenarios.

julienrf commented 1 year ago

Thank you @plouj for the report. I agree it would be good to highlight the differences between recover and recoverWith in their documentation. Would you be interested in submitting a PR?

preveen-stack commented 1 year ago

@plouj pls go ahead with aPR