Skip to content

Instantly share code, notes, and snippets.

@pakoito
Last active January 22, 2017 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pakoito/22a2ec849ff7e846566f36d5fc4a9d95 to your computer and use it in GitHub Desktop.
Save pakoito/22a2ec849ff7e846566f36d5fc4a9d95 to your computer and use it in GitHub Desktop.
Designing function returns on generic programming
## What does this function return?
Is it coupled in time? Is it synchronous?
YES
How many results are there?
NONE
Unit
ONE
Can it fail?
YES
Can it fail with a known value like Exception or String?
YES
Try<Value> or Either<String, Value>
NO
Optional<Value>
NO
Value
A COUPLE BUT I KNOW THE AMOUNT AND THE TYPES
Can it fail?
YES
Can one of them fail and the rest succeed?
YES
Can it fail with a known value like Exception or String?
YES
Tuple<Try<Value1>, Value2, Value3> or Tuple<Either<String, Value1>, Value2, Value3>
NO
Tuple<Optional<Value1>, Value2, Value3>
NO
Can it fail with a known value like Exception or String?
YES
Try<Tuple<Value1, Value2, Value3>> or Either<String, Tuple<Value1, Value2, Value3>>
NO
Optional<Tuple<Value1, Value2, Value3>>
NO
Tuple<Value1, Value2, Value3>
MANY
Can it fail?
YES
Can one of them fail and the rest succeed?
YES
Can it fail with a known value like Exception or String?
YES
Iterable<Try<Value>> or Iterable<Either<String, Value>>
NO
Iterable<Optional<Value>>
NO
Can it fail with a known value like Exception or String?
YES
Try<Iterable<Value>> or Either<String, Iterable<Value>>
NO
Optional<Iterable<Value>>
NO
How many results are there?
NONE
Can it fail?
YES
Can it fail with a known value like Exception or String?
YES
Single<Optional<Exception>> -- absence of exception is success
NO
Single<Optional<Unit>> -- absence is failure
NO
Completable
ONE
Can it fail?
YES
Can it fail with a known value like Exception or String?
YES
Single<Try<Value>> or Single<Either<String, Value>>
NO
Single<Optional<Value>>
NO
Single<Value>
MANY
Can it fail?
YES
Can one of them fail and the rest succeed?
YES
Can it fail with a known value like Exception or String?
YES
Observable<Try<Value>> or Observable<Either<String, Value>>
NO
Observable<Optional<Value>>
NO
Observable<Value> -- use onErrorResumeNext()
NO
Observable<Value>
## How does that Value look like?
How many possible value types or states can it contain? Failure cases like Exceptions or error Strings can also be rolled into the possible states
NONE
Unfeasable in Java or Void in Kotlin
ONE
Value
TWO
Either<Value1, Value2>
THREE TO NINE
Union3<Value1, Value2, Value3>
Union6<Value1, Value2, Value3, Value4, Value5, Value6>
Union9<Value1, Value2, Value3, Value4, Value5, Value6, Value7, Value8, Value9>
MORE THAN NINE
Look into Kotlin's sealed unions
## What does Value contain?
Is it?
NOTHING
Unit
PRIMITIVE OR DATA CLASS
Int, String, Boolean, User, DogDto...
FUNCTION
Function<InputValue, OutputValue>
OBSERVABLE, SINGLE, OR COMPLETABLE
You should be using a nested flatMap instead
ANOTHER CLASS
You're outside the paradigm so here be dragons
## Silly Types Time
A sequence of 3 integers that can completely fail without a reason
Optional<Iterable<Integer>>
A sequence of 3 groups of names to users that can fail individually with a reason. A reason can be either an Exception or a string
Iterable<Either<Either<Exception, String>, Tuple<String, User>> -- probably wrong
Iterable<Union3<Exception, String, Tuple<String, User>>>
A grouping of a map of string to user, a map of id to list of strings, and a list of ids. Users can be one of admin, luser, or guest. An id can be either a number or a string
Tuple<Map<String, Union3<Admin, Luser, Guest>, Map<Either<NumberId, StringId>, List<String>>, List<Either<NumberId, StringId>>>
An asynchronous sequence of N elements, some of which are a pair of an id to a user, a map of user ids to users, or a sequence of groupings of ids to their users. They can individually fail but only some give an Exception
Observable<Union4<Optional<Exception>, Pair<Either<NumberId, StringId>, Union3<Admin, Luser, Guest>>, Map<Either<NumberId, StringId>, Union3<Admin, Luser, Guest>>, Iterable<Pair<Either<NumberId, StringId>, Union3<Admin, Luser, Guest>>>>> -- this needs type aliases
typealias Id = Either<NumberId, StringId>
typealias User = Union3<Admin, Luser, Guest>
Observable<Union4<Optional<Exception>, Pair<Id, User>, Map<Id, User>, Iterable<Pair<Id, User>>>> -- can do better
typealias UserInfo = Pair<Id, User>
Observable<Union4<Optional<Exception>, UserInfo, Map<Id, User>, Iterable<UserInfo>>> -- hmmm
Observable<Union5<Unit, Exception, UserInfo, Map<Id, User>, Iterable<UserInfo>>>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment