-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Creating Observables in Scala #549
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@benjchristensen @headinthebox @jmhofer @phaller @retronym @vjovanov @xeno-by and everyone else, your comments are welcome ;-) |
Here is my 2 cents.
|
What about approach04: /*usecase01:*/ Observable.create(observer => {...})
/*usecase02:*/ Observable()
/*usecase03:*/ Observable(oneValue)
/*usecase04:*/ Observable(1, 2, 3)
/*usecase05:*/ Observable.from(myIterable)
/*usecase06:*/ Observable.from(myInfiniteIterable)
/*usecase07:*/ Observable.from(myFuture)
/*usecase08:*/ /* internally: */ new Observable(javaObservable) /* from outside: */ toScalaObservable(javaObservable)
/*usecase09:*/ Observable.error(new Exception())
/*usecase10:*/ Observable.from(1 to 10) // covered by usecase05
/*usecase11:*/ Observable.from(Future{ ... }) // for the moment Rationale:
|
Overloading is less dangerous in Java because you have to pass type arguments explicitly. Scala, on the other hand, will infer these. IMO, this sort of API is broken: def foo[A](as: A*)
def foo(a: X) The user thinks they are calling the second method, gets something wrong so they types don't line up, and they are silently funnelled into the first. You are robbing the users of type safety. |
BTW, I haven't been following this change closely enough to know if your proposal still falls afoul of my criteria, just take that as general advice... |
thanks, approach01 and approach02 suffer from exactly this problem, but approach03 and approach04 should be fine |
I think approach04 is the way to go, so I made a PR for it: #561 |
Quoting from an email by @headinthebox :
|
I'm fine with replacing But I would not like to have two names for the same method: |
I'd prefer |
I don't mind having two at all. If we start with one we can always add apply(...) back, but if we put it in it is hard to remove. |
Here's a trick by mentioned by @vjovanov which gives us more possibilities: Instead of having |
I did seriously think about this option, it does effectively introduces two ways for the same thing, which is why I picked “items”. On Dec 12, 2013, at 7:01 AM, samuelgruetter [email protected] wrote:
|
For the record, here's the what we currently have in master: approach05: /*usecase01:*/ Observable.create(observer => {...})
/*usecase02:*/ Observable.empty
/*usecase03:*/ Observable.items(oneValue), List(oneValue).toObservable
/*usecase04:*/ Observable.items(1, 2, 3), List(1, 2, 3).toObservable
/*usecase05:*/ Observable.from(myIterable), myIterable.toObservable
/*usecase06:*/ // infinite Iterables not yet supported by RxJava
/*usecase07:*/ Observable.from(myFuture)
/*usecase08:*/ toScalaObservable(javaObservable)
/*usecase09:*/ Observable.error(new Exception())
/*usecase10:*/ Observable.from(1 to 10) // covered by usecase05
/*usecase11:*/ Observable.from(Future{ ... }) // for the moment
|
Hi guys, first of all congrats on your hard work on this project. Could I ask you to update the readme to reflect the changes in the API? https://github.com/Netflix/RxJava/tree/master/language-adaptors/rxjava-scala The examples still seem to use the old apply() API; switching from 0.15.1 to 0.16.1 this changes. This can be quite confusing for somebody who's just starting out ... |
@headinthebox @samuelgruetter @zsxwing Anything to do here? Is this done? |
I think we can consider this done. Closing. |
Yup. |
Apologies for the late reply. The out-of-date file is the README.md under the rx-scala language adapter. It has some examples such as:
which still use the old constructors. No big deal. |
@lJoublanc Thanks for reporting it. Already updated it at #1239 |
The constructors for Observables in Scala have multiple problems. I'd like to start a systematic discussion about this, hoping to find a good solution.
First, a list of use cases that we eventually want to cover:
Note
Observable.apply
. Others, which have names everyone agrees on, such asdefer
,never
,interval
,generate
, etc, are not listed.Now a first approach01 would be to use the same names as Java does:
We decided against this because this has problem01:
Observable.apply
is not used, so we don't exploit a nice feature of Scala.That's why we implemented this approach02 (that's version 0.15.1):
But this also turned out to have problems:
problem02: If I write this:
Then I don't get an error, but
o
is anObservable[Observer[Int] => Unit]
.problem03:
Observable(new Exception, new Exception)
yields anObservable[Exception]
with 2 elements and is not the same asObservable(new Exception) ++ Observable(new Exception)
, which yields anObservable[Nothing]
with 0 elements, terminating withonError
. Coursera students got confused about this.problem04: The varargs apply and the OnSubscribeFunc apply clash in such a way that parameter type inference is lost:
problem05: Cannot easily construct an Observable emitting one Future, one Exception, or one Range.
problem06: It's possible to define both
but when I want to use it (eg
Observable(List(1, 2, 3))
), I getWe could also use implicit conversions, approach03:
List().toObservable
List(1).toObservable
List(1, 2, 3).toObservable
myIterable.toObservable
myIterable.toObservable
myFuture.toObservable
myJavaObservable.toObservable
Observable.error(new Exception)
(0 to 4).toObservable
Observable.async{ ... }
or something elseHere, usecases 02, 03, 04, 05, 06, and 10 would all be covered by one single implicit conversion from
Iterable[T]
toObservable[T]
.However, I'm not yet sure if this approach would lead to other problems.
I invite everyone to post new approaches, and to comment on existing ones. And please use increasing unique ids for usecase, approach and problem, to keep our discussion tidy ;-)
The text was updated successfully, but these errors were encountered: