duemunk / Async

Syntactic sugar in Swift for asynchronous dispatches in Grand Central Dispatch
MIT License
4.59k stars 316 forks source link

Arguments and return values to blocks #3

Closed duemunk closed 8 years ago

duemunk commented 10 years ago

Currently Async supports passing parameters through an external var like:

var date: NSDate?
Async.background {
    date = NSDate()
}.main {
    // Access date 
}

Possible syntax for a better solution:

Async.background {
    let date = NSDate()
}.main(date) {
    // Access date
}

I have no idea if or how this is possible – please let me know if you do!

pketh commented 10 years ago

:+1: seems handy

technomage commented 9 years ago

The proposed syntax is not possible in Swift. The block passed to background can return a value, but the argument to the following main block is resolved in the static lexical scope. The following would be possible, but might require all blocks to take an argument, not just those that are preceded by one returning a value (static typing). More experimentation is required, but something should be possible given that the block passed to main is actually invoked by the main function which can have the result of the prior block.

Async.background {
    NSData()
}.main{data in
   // access data
}
duemunk commented 9 years ago

Thanks for the feedback @technomage. It's nice to see some ideas on how to expand Async.

Let me know if you get anything like this to work. I'll do my experimentation on how to get something like this to work.

I think it is necessary that it should work without adding to many new functions and without lose type like AnyObject. Or it should be possible to easily extend Async with project-specific closures that take a certain type or tuple of types.

josephlord commented 9 years ago

Have you seen the stuff I have in this https://github.com/josephlord/Async.legacy/pull/6 branch of the Async.legacy. Generics are used to chain arguments and returns in a type safe way including the empty tuple. I didn't get round to doing enough tests and didn't make the decision to stop being a strict subset of the main project Async project. Note that I haven't actually tested on recent Swift releases. I'll trigger a retest in a minute by making a trivial change.

duemunk commented 9 years ago

@josephlord I've been looking at it and will try to steal some ideas :) I still don't have enough insight to decide what I want. I still need to do quite a few trials to see how it can work best without too much magic (magic being my lack of understanding).

Letting Async.legacy not being a strict subset of Async is probably a good idea. We probably have different opinions on the purpose of the goals and means, and Async really haven't been growing/improving as fast as I wanted. It's very nice to see the progress you make on Async.legacy!

duemunk commented 9 years ago

https://github.com/duemunk/Async/tree/feature/ArgumentAndReturn is my initial take on having arguments to closures + return values.

chriseidhof commented 9 years ago

Ah cool! This definitely seems like a big step in the right direction =). Looks great!

cloud-hot commented 9 years ago

Nice work! Waiting for your progress!

rosskimes commented 9 years ago

Any thoughts on bringing this into the more current branches?

irace commented 8 years ago

Any update on this?

duemunk commented 8 years ago

I've sort of hit a dead end with any of my attempts. This was with previous version of swift (1.0-1.2), so definitely have a go at another try!

Ewg777 commented 8 years ago

Now it works

Async.background {
    let date = NSDate()
    Async.main {
        // Access date
    }
} 
rosskimes commented 8 years ago

That works (that is the same path I have used to libdispatch in the past). The idea was to have a syntax that didn't require nesting of blocks.

Juice805 commented 8 years ago

Is there any update on this? This project gives a way to do asynchronous URLrequests in order while using the previous tasks output, however the syntax is not as friendly as this project.

Possibly have one dictionary variable which gets passed through each block? Any user defined information can simply be get and set through the dictionary between blocks

Async.background {
    data in
    data["test"] = "Hello"

}.main{data in
   // access data
    print(data["test"]!)
    // prints Hello
}
duemunk commented 8 years ago

This has actually been implemented in the Swift 3.0 branch.

Huge thanks to @BrunoMazzo for taking the big steps in making this work!!