Closed jb-gcx closed 1 week ago
Yes you are right, setValue
's parameter should be nonnull. For void futures, the version without parameter should be used.
@LiFengSC I'm happy to make a PR out of this.
One more question: is there any way to prevent calling setValue
without parameter for promises with non-optional values? Or to make setValue
take a nullable parameter if and only if the promises value is optional? DJPromise<nonnull Foo *>
doesn't compile and I'm not sure how powerful ObjC generics are in this regard 🤔
TBH I don't know. My understanding is ObjC generics is not as powerful as C++ templates that we can completely disable the undesirable form.
What is the problem
My understanding of the concept of djinnis Future/Promise implementation is that a future will always result in either a value of the given type or an exception. The
get
method waits for a result to be present and then either returns the value or throws the exception. So by the timeget
returns, a value must be present.This is already the case for the Cpp implementation of Future/Promise. If I want to have a nullable result, I must use
Future<std::optional<int>>
.The ObjC implementation allows calls to
setValue
with a nullable value, regardless of the value type. Thereforeget
also needs to return a nullable value. I would love to change this, because it doesn't match the implementation in other platforms and goes against my understanding of the concept. It also makes usage from Swift harder/weirder, because we always need to unwrap a value that is expected to be always present.Possible solution
I would most like to simply change
DJFuture::get
andDJPromise::setValue
to return and acceptnonnull
values.However, I'm guessing the value was originally made nullable for a reason. Namely: what if the user wants the future to return something nullable? In C++ this is easy to achieve with
Future<optional<...>>
. I lack ObjC knowledge here, but I'm guessing there is no way to dictate nullability via template arg in ObjC, which is why the value was madenullable
by default. Is this true? Is there no other way?Other observations
DJPromise::setValue
without parameters sets a different kind of null thanDJPromise::setValue:nil
nil
valueI've created this PR in my fork to showcase these issues, see the breaking tests in the CI. For reference, I'll copy the test code and CI output here as well:
Test code
CI output