Description
Changes are being done in #770 as a result of discussion in #746 that add a new bind
operator and change the create
signature to inject a Subscription
instead of returning it. The reasons for this change can be seen at #746.
The names have thus far been left as is or as raw functions while achieving the right functionality. Before releasing and becoming part of the published API I'd like to finalize the names (some of which have been disputed).
1) "source" Function
Action1<Operator<? super T>>
This is the single function that exists inside an Observable
that is executed upon subscription (when subscribe
is invoked).
The previous function was called OnSubscribeFunc<T>
.
We could just keep the Action1
signature but the generics are obnoxious to remember, type and code-complete. Having a specific type is for ease of use.
This will be the most used of the types discussed in this issue as all Observable.create
usage will involve this type. Most users of RxJava will use Observable.create
.
A possibility is:
public static interface OnSubscribe<T> extends Action1<Operator<? super T>>
or it could more explicitly (and like OnSubscribeFunc
) be:
public static interface OnSubscribe<T> extends Function {
public void onSubscribe(Operator<? super T> op);
}
What other names could this be?
2) "bind" or "lift" Method
The new method added to Observable
has a name and signature like this:
public <R> Observable<R> bind(final Func1<Operator<? super R>, Operator<? super T>> bind)
The intent is to perform function composition and return a new Observable
representing the composition.
Since my computer science, lambda calculus etc is not the greatest, I was calling this bind
but after discussion with others it seems this is probably better called lift
as per functional programming principles.
That said, there is nothing requiring us to use names such as these.
The intent of this method is to chain together operators for transforming, combining, filtering and operating on data flowing through an Observable
and each time it's chained it returns a new Observable
.
For example:
Observable<U> ou = Observable<T>.chain(operatorA);
Observable<V> ov = Observable<U>.chain(operatorB);
Observable<W> ow = Observable<V>.chain(operatorC);
Typically this would be used like this:
Observable<W> ow = Observable<T>.chain(operatorA).chain(operatorB).chain(operatorC);
Here are possible names:
public <R> Observable<R> bind(Function<T, R> f)
public <R> Observable<R> lift(Function<T, R> f)
public <R> Observable<R> compose(Function<T, R> f)
What is the correct name for this?
3) "bind" or "lift" Function
The function that the currently named bind
takes is:
Func1<Operator<? super R>, Operator<? super T>>
This could be left as is and will generally only be used by people implementing operators. Thus, it is not in the "common path" for using Rx.
However, it could benefit from the clearer communication of a specific type and name.
Possibilities include:
OnBind<R, T>
OnLift<R, T>
BindFunction<R, T>
LiftFunction<R, T>
Composition<R, T>
Should we give this a specific type and name? If so, what should it be?
4) Operator class
As part of the new bind
and create
functionality that injects Subscriptions
into the source function, a new type Operator
was created that combines Observer
and Subscription
.
public abstract class Operator<T> implements Observer<T>, Subscription
Is Operator
the correct name? If not, what should it be called?
Possible Outcomes
// use `OnSubscribe` for the "source" function
public final static <T> Observable<T> create(final OnSubscribe<T> f);
// use `compose` and `Composition` as user friendly representations for the `bind`/`lift` functionality
public <R> Observable<R> compose(final Composition<R, T> cf);
// leave `Operator` as is
public abstract class Operator<T> implements Observer<T>, Subscription
or
// use `OnSubscribe` for the "source" function
public final static <T> Observable<T> create(final OnSubscribe<T> f);
// use `compose` for the name but leave the function
public <R> Observable<R> compose(final Func1<Operator<? super R>, Operator<? super T>> cf);
// leave `Operator` as is
public abstract class Operator<T> implements Observer<T>, Subscription
or
// use `OnSubscribe` for the "source" function
public final static <T> Observable<T> create(final OnSubscribe<T> f);
// use `lift`
public <R> Observable<R> lift(final Func1<Operator<? super R>, Operator<? super T>> cf);
// leave `Operator` as is
public abstract class Operator<T> implements Observer<T>, Subscription
etc
My intent is to solidify the naming before releasing 0.17.0 as these are not easy to change once released.
Please provide your suggestions and reasoning either to support one of the options above or for something new.
Thank you!