Comments (13)
In the example, the issue is that your block is longer than one line, so its type is not inferred. Via the readme:
As long as the block you pass to then is one line long, its type signature will be inferred, which will make Promises much easier to read and work with.
from promise.
I wonder if this is because of the type inference on the value 3
. It doesn't know if it's an Int, UInt, CGfloat, Int8, etc. Can you try it with an empty struct like struct MyStruct { }
?
from promise.
@khanlou oh no no, Int
and 3
are just for reference
Here's a snippet from an actual project
var giftController: Promise<GiftIntroductionController> {
imagePromise.then { userImage in
return GiftIntroductionControllerBackend.make(for: gift, image: userImage)
}.then { backend -> GiftIntroductionController in // Here, type will not be inferred if not specified explicitly
let controller = UIStoryboard.main.instantiate(GiftIntroductionController.self)
controller.prepare(for: backend)
return controller
}
}
N.B.: the return type of closure in then
is not necessarily the same as the one and only parameter type, it just happened to be so in the snippet.
from promise.
@isaac-weisberg is this good to close now or is there still an issue?
from promise.
Still an issue, planned to try to dig more this weekend, if you don't mind :)
from promise.
🤔🤔🤔 I am struggling trying to replicate this behavior with Swift 4.1 on Linux
from promise.
Alright, evidently, the issue is not with version of Swift, I have tuned test up a bit and it started to appear
from promise.
Alright, so first wave of experiments is to be referred to as "done".
The compiler was ultimately confused by the following construct.
let promise = Promise { fulfill, reject in
fulfill(SomeStuff())
}.then { value in
return Promise { fulfill, reject in
fulfill(Apple(str: "Heoooo"))
}
}.then { apple in
return Bapple.make()
}.then { bapple in
print("Bapple is \(bapple)")
return bapple
}
About the last then
closure, the output is.
PromiseTypeInferringTests.swift:49:20: error: unexpected non-void return value in void function
return bapple
Observation 1: so we've got 3 then
methods. One of them is generic with closure returning a Promise
, another - generic with closure returning a value, creating a Promise
itself, and third one - non-generic with closure returning Void
. Since Void
is a first-class type in Swift, just like functions, a set containing Void
type is a strict subset of a set containing all possible types satisfying unconstrained generic type specifier.
Observation 2: third then
method features an optional onRejected
parameter (that has a default value), while the rest of the then
methods don't feature such capabilities. From a logical standpoint, as well as the majority of use cases, a then
method with onRejected
handler is a done
method. With the background of previous observation, this may or may not play some role in compiler's decisions, and if so, the implementations must especially be available both ways.
from promise.
So, possible solution:
- Start treating
Void
as NewValue - Remove
then
with callback that returnsVoid
- Make the old
then
with two callbacks the newdone
, optionally, for internal usage only.
from promise.
Lol so I tried it
Good thing:
- it compiles.
Bad thing:
- If you had a
Promise<Int>
and then applied athen
handler that returnedVoid
, the type of returned promise is transformed toPromise<Void>
Extract from PromiseTests.swift
let promise = Promise(value: "someString").then({ string in
return string.count
}).then({ count in
return count*2
}).then({ doubled in
XCTAssertEqual(doubled, 20)
expectation?.fulfill()
})
Before the changes, type of promise
is Promise<Int>
, after - Promise<Void>
, cause it chains.
@khanlou, I imagine, this is not the desired behavior but wait, it is in fact the desired behavior, obviously, because what we are actually doing is applying not a then
handler, but the done
handler; in other words, we explicitly specify that we are not chaining another action.
P.S.: one might be wondering "Hey, Isaac, but did this resolve your issue that you had with type inferring?". Answer is no 😂
from promise.
So obviously, with this change to API, all usages of not-chaining then
must be changed to done
.
And, naturally, done must be public.
from promise.
I have done this and it looks concise and beautiful but this did not resolve the issue. I will fiddle with is just a bit more, maybe it will work, but there is no reason to presume something is going to get fixed eventually in that regard.
from promise.
let promise = Promise { fulfill, reject in
fulfill(SomeStuff())
}.then { value in
return Promise { fulfill, reject in
fulfill(Apple(str: "Heoooo"))
}
}.then { apple in
return Bapple.make()
}.then { bapple in
print("Bapple is \(bapple)")
return bapple
}
produces
PromiseTypeInferringTests.swift:47:16: error: unable to infer complex closure return type; add explicit type to disambiguate
}.then { bapple in
^
-> (PromiseTypeInferringTests.Bapple)
Well, that was fun while it lasted :)
P.S.: Just in case, @khanlou, I understand the dramatic nature of changes that I used to propose and I have no hard feelings about the idea of having my PR rejected :) I can guess, the project wouldn't like to have such a drastic change to the API :)
from promise.
Related Issues (20)
- Difficulty understanding tapping version of "then" HOT 1
- error: invalid target name at 'PromiseTests'; name of non-test targets cannot end in 'Tests' HOT 3
- TravisCI making it look like it works HOT 6
- Tests while in SPM HOT 10
- Promise chaining after `catch` is lacking HOT 2
- As of #43, the project might be incompatible with Xcode prior to 9.3 GM and Swift prior to 4.1 HOT 3
- Add Xcode 9.2 deployment in Travis CI.
- What about 2.0.2 ? HOT 2
- Static libs now support Swift - Promise should support static libs :) HOT 2
- Update Podspec HOT 6
- Callback threading problems HOT 3
- How to switch catches on error types? HOT 9
- Require only App-Extension-Safe API HOT 2
- No issue, just a THANK YOU HOT 1
- Suggestion: AllSettled implementation HOT 5
- Race condition when chaining a promise after being fulfilled? HOT 1
- Conflict with State enum and @State in SwiftUI HOT 3
- Not sure how to return Void promise HOT 3
- Catch Clause Not Invoked HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from promise.