-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
Observable.just(T value)
and Observable.from(T t1)
are confusing
#1563
Comments
In RxScala, we call it |
I'm not a fan of removing 'from(T)' this late in the game (almost to 1.0). Most of the time it is desired to itemize an Iterable. The 'just' operator is there for when it shouldn't be itemized. /cc @headinthebox |
If we do pursue this change I'd probably do ...
The thing I don't like about this is it will break most uses of 'from(Iterable)' that itemizes as most people want it to. |
By the way, the reason why it is designed the way it currently is is because an Observable is intended for itemized sequences of data. It is rare that the desired output is Observable<Iterable> instead of Observable. Thus in the Foo case it would correctly convert T into an itemized sequence, which is what "from" is for. If a scalar response is desired that is what "just" is for. So if Foo should emit Observable<List> then use Observable.just rather than the more common Observable.from. |
Any further comments or discussion on this? The key deterrent to changes here are:
|
I support a change. Methods that do different things should have different names. It's currently ambiguous if the call
and maybe 😃
|
I personally don't like |
I also don't like I agree that the current semantics are somewhat awkward and could have been designed better. However, the cost of changing this is not worth the massive break on almost all existing applications since I don't think this change should be made right before hitting 1.0. Eventually when 2.x is done (not anytime soon) this could be cleaned up, but in well over a year of usage by many people, this issue is the first time I'm aware of this issue being been brought up, thus I don't think the confusion is significant enough to warrant a breaking change. |
I would refer to Item 41 in Effective Java by Josh Bloch. Bloch warns to use overloading judiciously for this specific reason. Josh's advice would be to create methods such as @abersnaze suggested. Overloading in Java is broken. |
I don't buy "appeal to authority figure" arguments. Just saying. |
My 2c - The current design is not correct, as described above. In particular, it's definitely surprising for a user that However, this seems like a severe cost in terms of migration for moderate-at-best benefit. I've been involved with keeping a large multi-language codebase up-to-date with RxJava as it evolves, and this migration would be a painful one. My vote is to leave it as-is, and document the |
@headinthebox I'm not against overloads. Just overloads that do different things. There will still be plenty of overloads in my proposal:
@benjchristensen, @mattrjacobs: could 0.20 depreciate |
It is not the design I'm disputing, it's how badly this breaks almost all apps. Is this problem (that no one has complained about for over a year) really so bad as to warrant the breakage? Whether the methods are deleted in 0.20 or 1.0 doesn't matter, whenever it happens the break happens (though if we do this we'd deprecated in 0.20 and delete in 1.0). |
If we do make a change .... Current: from(Future<? extends T>);
from(Future<? extends T>, long, TimeUnit);
from(Future<? extends T>, Scheduler);
from(Iterable<? extends T>);
from(Iterable<? extends T>, Scheduler);
from(T);
from(T, T);
from(T, T, T);
from(T, T, T, T);
from(T, T, T, T, T);
from(T, T, T, T, T, T);
from(T, T, T, T, T, T, T);
from(T, T, T, T, T, T, T, T);
from(T, T, T, T, T, T, T, T, T);
from(T, T, T, T, T, T, T, T, T, T);
from(T...);
from(T[], Scheduler);
just(T);
just(T, Scheduler); I would delete the fromFuture(Future<? extends T>);
fromFuture(Future<? extends T>, long, TimeUnit);
fromIterable(Iterable<? extends T>);
fromArray(T[]);
from(T);
from(T, T);
from(T, T, T);
from(T, T, T, T);
from(T, T, T, T, T);
from(T, T, T, T, T, T);
from(T, T, T, T, T, T, T);
from(T, T, T, T, T, T, T, T);
from(T, T, T, T, T, T, T, T, T);
from(T, T, T, T, T, T, T, T, T, T); or maybe: from(Future<? extends T>);
from(Future<? extends T>, long, TimeUnit);
from(Iterable<? extends T>);
from(T[]);
items(T);
items(T, T);
items(T, T, T);
items(T, T, T, T);
items(T, T, T, T, T);
items(T, T, T, T, T, T);
items(T, T, T, T, T, T, T);
items(T, T, T, T, T, T, T, T);
items(T, T, T, T, T, T, T, T, T);
items(T, T, T, T, T, T, T, T, T, T); or: from(Future<? extends T>);
from(Future<? extends T>, long, TimeUnit);
from(Iterable<? extends T>);
from(T[]);
fromItems(T);
fromItems(T, T);
fromItems(T, T, T);
fromItems(T, T, T, T);
fromItems(T, T, T, T, T);
fromItems(T, T, T, T, T, T);
fromItems(T, T, T, T, T, T, T);
fromItems(T, T, T, T, T, T, T, T);
fromItems(T, T, T, T, T, T, T, T, T);
fromItems(T, T, T, T, T, T, T, T, T, T); |
I'm not fond of changing this, but if there are good reasons I'm okay with it. In my whole codebase I never ran across an issue with that, and sometimes I even explicitly use the "just" instead of a from(T) to make it clear I'm returning just one item, basically. I'm good if we get to something more clear, but on the other hand as @benjchristensen said it will break a good deal of libraries I'm sure (fixing it is not very hard, though). @benjchristensen strictly speaking, are we done with cleaning the API yet with 0.20 or is there still opportunity for 1.0? SUBJ: in my opinion we gain too less and risk too much annoyance with breaking this, since its just very minor API nuances? |
Not a big deal for Clojure-land. We'd just change |
After 0.20 we will immediately move to 1.0-RC1 with the only change being the deletion of deprecated methods/types. Therefore, API cleaning and changing should be done, with only outstanding work shown here: https://github.com/Netflix/RxJava/issues?q=is%3Aopen+is%3Aissue+milestone%3A0.20 Some small breaking changes have been done in 0.20, but nothing on major APIs (removal of |
I'd take @benjchristensen's second proposal, but keep the from(Future<? extends T>);
from(Future<? extends T>, long, TimeUnit);
from(Iterable<? extends T>);
from(T[]);
items(T);
items(T, T);
items(T, T, T);
items(T, T, T, T);
items(T, T, T, T, T);
items(T, T, T, T, T, T);
items(T, T, T, T, T, T, T);
items(T, T, T, T, T, T, T, T);
items(T, T, T, T, T, T, T, T, T);
items(T, T, T, T, T, T, T, T, T, T);
just(T);
just(T, Scheduler); So the only change would be |
I think we should keep To summarize: |
I also like @benjchristensen's second proposal but would suggest that |
I don't like the ambiguity of |
My $0.02 The current design is certainly confusing and could be changed. However, the tax on users that this backward incompatible change would bring because of the shear intrusiveness of I would vote for keeping the current API at this point. |
See ReactiveX#1563 for discussion.
Please review proposed changes in #1576. Ignore the deluge of unit test changes and focus on Observable.java. I deprecated the Nothing should break in 0.20 with this. The deprecated methods will be removed in 1.0RC1 with all other deprecated methods. If there are naming or signature changes to debate, let's make sure to get it correct now so please review and speak up. |
I do like these changes. I think it will be less confusing for users. However, I think it is a bit confusing to keep the This could also be fixed by changing the JavaDoc to say that |
What is better for a single item, Observable.just(T) or Observable.item(T)? For multiple should it be Observable.just(T, T) or Observable.items(T, T) |
I would prefer |
I think I do too. It would mean we stick with 'from' and 'just' instead of introducing yet another name to discover. The 'just' name also conveys it will emit "just" what it is given. |
I like the consistency of item and items. 'just' for multiple seems odd.
|
Currentfrom(Future<? extends T>);
from(Future<? extends T>, long, TimeUnit);
from(Future<? extends T>, Scheduler);
from(Iterable<? extends T>);
from(Iterable<? extends T>, Scheduler);
from(T);
from(T, T);
from(T, T, T);
from(T, T, T, T);
from(T, T, T, T, T);
from(T, T, T, T, T, T);
from(T, T, T, T, T, T, T);
from(T, T, T, T, T, T, T, T);
from(T, T, T, T, T, T, T, T, T);
from(T, T, T, T, T, T, T, T, T, T);
from(T...);
from(T[], Scheduler);
just(T);
just(T, Scheduler); Proposal ANOTE: This will break from(Future<? extends T>)
from(Future<? extends T>, long, TimeUnit)
from(Future<? extends T>, Scheduler)
from(Iterable<? extends T>)
from(T[])
item(T)
items(T, T)
items(T, T, T)
items(T, T, T, T)
items(T, T, T, T, T)
items(T, T, T, T, T, T)
items(T, T, T, T, T, T, T)
items(T, T, T, T, T, T, T, T)
items(T, T, T, T, T, T, T, T, T)
items(T, T, T, T, T, T, T, T, T, T)
just(T) Proposal BNOTE: This will break from(Future<? extends T>)
from(Future<? extends T>, long, TimeUnit)
from(Future<? extends T>, Scheduler)
from(Iterable<? extends T>)
from(T[])
just(T)
just(T, T)
just(T, T, T)
just(T, T, T, T)
just(T, T, T, T, T)
just(T, T, T, T, T, T)
just(T, T, T, T, T, T, T)
just(T, T, T, T, T, T, T, T)
just(T, T, T, T, T, T, T, T, T)
just(T, T, T, T, T, T, T, T, T, T) Proposal CNOTE: This will break from(Future<? extends T>)
from(Future<? extends T>, long, TimeUnit)
from(Future<? extends T>, Scheduler)
from(Iterable<? extends T>)
from(T[])
item(T)
items(T, T)
items(T, T, T)
items(T, T, T, T)
items(T, T, T, T, T)
items(T, T, T, T, T, T)
items(T, T, T, T, T, T, T)
items(T, T, T, T, T, T, T, T)
items(T, T, T, T, T, T, T, T, T)
items(T, T, T, T, T, T, T, T, T, T) I prefer B as I find the Any other proposals? I'd like to make a decision on this within the next 24 hours so I can release the next RC. Please weigh in ... |
+1 for B (agree item/items is super awkward) |
See ReactiveX#1563 for discussion.
See ReactiveX#1563 for discussion.
+2 for B |
+3 for B |
+1 for B |
+1 B |
B |
Thanks everyone for your votes. I'm merging the pull request with option B. |
Merged #1576. The ambiguity will still exist in 0.20 due to the deprecated methods. In 1.0 the deprecated methods will be deleted. |
In light of this change, would it make sense to rename RxScala's items(T_) to just(T_) as well? |
Go ahead. |
Done in #1586 |
Having
Observable.just(T value)
andObservable.from(T t1)
is confusing to users of the API. It looks like callingObservable.from(T t1)
callsObservable.just(T value)
internally. The problem is that this method also exists:Observable.from(Iterable<? extends T> iterable)
. I found myself accidentally passing a list in toObservable.from(T t1)
only to find that it took each item in that list and emitted it separately.This becomes especially confusing when using generics. For example, suppose I have a class
Foo<T>
which callsObservable.from(T t1)
internally. If I create classFoo
likeFoo<List<Bar>>
what happens when it callsObservable.from(T t1)
internally? Does it callObservable.from(T t1)
orObservable.from(Iterable<? extends T> iterable)
?I suggest removing
Observable.from(T t1)
or renamingObservable.from(Iterable<? extends T> iterable)
toObservable.fromIterable(Iterable<? extends T> iterable)
.The text was updated successfully, but these errors were encountered: