HaxeFoundation / haxe-evolution

Repository for maintaining proposal for changes to the Haxe programming language
111 stars 58 forks source link

Promises #58

Closed Aurel300 closed 5 years ago

Aurel300 commented 5 years ago

Stepping-stone for reworking the system APIs.

Rendered version

nanjizal commented 5 years ago

I think
haxe.async.Promise Might be better. Then any tools related to async programming could be added at a later date, I believe swift and nodejs are quite async focused so it's feasible that Haxe would add some platform abstraction to provide more consistant journey in future revisions.

nanjizal commented 5 years ago

My reasoning is that a Promise is like data structures - ie: non essential more advanced feature, so even haxe package is a bit high. For instance if some form of Future was added or async loading approach or async variables then a package signifiies haxe's future intent to support some forms of async development flow.

"Promises in the standard library will allow providing asynchronous alternatives to various sys APIs, on par with standard libraries such as the one of node.js.

Library authors and programmers in general will also benefit from being able to easily create asynchronous APIs."

Makes sense to start an async package for future related tools.

Aurel300 commented 5 years ago

I believe swift and nodejs are quite async focused so it's feasible that Haxe would add some platform abstraction to provide more consistant journey in future revisions.

I am working on that at this very moment (sys.async), since that is the topic of my Haxe internship :)

As for the haxe.async package, it may be a good idea, although I'd like to see what other people think as well.

nanjizal commented 5 years ago

Yer yer just adding the idea into the mix.

RealyUniqueName commented 5 years ago

I don't like to follow JS here. We had plenty of problems with JS promises. Maybe we need to try and design something specific for the rich Haxe type system.

E.g. what about Promise<Void>?

new Promise<Void>((resolve,reject) -> {
    //how to pass Void value to resolve?
    resolve(); //Error: Not enough arguments, expected value:Void
})
    .then(() -> trace('wat'));

And I don't like to be forced to return a promise from public function then<U>(onFulfilled:T->Promise<U> as most of the time I just want to handle a promise result without producing another promise.

promise.then(result -> {
  trace(result); //Error: Missing return : Promise<U>
});

Also, would be great to have an error strictly typed. But then, what if some unexpected exception is thrown - how would it be handled by a promise if the exception type does not match the error type?

markknol commented 5 years ago

Please consider Promise and Future of tink_core. No need to reinvent the wheel. Also tink_core is really good, well thought.

Aurel300 commented 5 years ago

No need to reinvent the wheel.

Isn't that what tink_core did though? :)

But, in all seriousness – the reasons I chose to propose an A+ promise-like interface for the Haxe standard library:

From what I can see tink_core promises are built on top of tink_core futures and tink_core "surprises", etc etc. However well thought-out these classes are, they are not designed to be taken individually.

@RealyUniqueName I agree there are some problems with typing Void promises. Ideally, we would have void values, i.e. function foo(bar:Void) trace("ok"); could be called with some sort of foo(voidValue). This is most definitely the subject for a separate proposal though.

tink_core promises solve this issue with a workaround of a Noise type (enum Noise { Noise; }). Even if we went for tink_core-style promises, we would not solve this problem; so that is not an argument in favour of tink_core, rather it is an argument in favour of void-values and/or having a Noise type in the standard library.

kevinresol commented 5 years ago

My 2 cents about the async api in std: Please use callbacks.

Reasons:

nadako commented 5 years ago

I also think simple callbacks is a good option for standard library. They can be easily mapped to whatever async operation abstraction the user prefers (which can also depend on the target and interop requirements).

That said I think we should put some thought into whether these callbacks can already be used as "continuations" for our current coroutine design. It would be great if they could, without any further wrapping!

nadako commented 5 years ago

Was there already discussion about operation cancellation? I find the "cancellation token" approach quite nice for this.

Aurel300 commented 5 years ago

Well then, after further thought and discussions here and on Slack, I do agree that callbacks are the way to go for the APIs in the standard library. A promisified version of the API may be added as part of a promise implementation later, since it is a question of wrapping the callbacks into promises.

Target-consistent promises would still be a useful addition to the standard library. Maybe almost A+ is not the way to go if we actually want to get rid of some of the A+ problems. I'll close this for now.