haxetink / tink_await

Haxe async/await
MIT License
58 stars 15 forks source link

Can't get started #2

Closed kevinresol closed 8 years ago

kevinresol commented 8 years ago
package;

using tink.CoreApi;

class Main implements await.Await{
    public static function main() {
        new Main();
    }

    public function new() {
        bar().handle(function(o) trace(o.sure()));
    }

    @:async function bar():Surprise<Null<Int>, Error> {
        var str = @:await foo();
        var i = Std.parseInt(str);
        return i;
    }
    function foo():Surprise<String, Error> return Future.sync(Success('1'));

}

I am trying this code but it fails with:

src/Main.hx:19: characters 48-58 : tink.core.Future<tink.core.Outcome<String, Unknown<1>>> should be tink.core.Future<tink.core.Outcome<tink.Surprise<String, tink.Error>, Unknown<0>>>
src/Main.hx:19: characters 48-58 : Type parameters are invariant
src/Main.hx:19: characters 48-58 : String should be tink.Surprise<String, tink.Error>
src/Main.hx:19: characters 48-58 : String should be tink.core.Surprise<String, tink.Error>
src/Main.hx:19: characters 48-58 : String should be tink.core.Future<tink.core.Outcome<String, tink.Error>>
src/Main.hx:16: characters 23-26 : tink.Surprise<String, tink.Error> should be String
src/Main.hx:16: characters 23-26 : tink.core.Surprise<String, tink.Error> should be String
src/Main.hx:16: characters 23-26 : tink.core.Future<tink.core.Outcome<String, tink.Error>> should be String
src/Main.hx:16: characters 23-26 : For function argument 'x'
Build failed
benmerckx commented 8 years ago

The type gets transformed as well. So this should work:

 @:async function bar(): Null<Int> {...}

Do you think the type transform is overkill here?

kevinresol commented 8 years ago

oops, I see! Hm... I think it is okay. Just missed that piece of doc 😛

kevinresol commented 8 years ago

Just got another problem, the following code fails to compile

package;

using tink.CoreApi;

class Main implements await.Await{
    public static function main() {
        new Main();
    }

    public function new() {
        bar().handle(function(o) trace(o.sure()));
    }

    @:async function bar():Int {
        var str:MyString = switch @:await foo() {
            case Success(str):
                str;

            default:
                "2";
        }
        return Std.parseInt(str);
    }
    @:async function foo() return Success('1');

}

abstract MyString(String) from String to String {}
benmerckx commented 8 years ago

Should be fixed in 0.0.4

kevinresol commented 8 years ago

Getting back to the return type issue, I am not sure if one day someone wants to explicitly specify the Failure type, maybe adding an optional meta @:throws(Error) which will become the type of Failure, how does it sound?

benmerckx commented 8 years ago

There's currently no way to guarantee the type of a failure. Because exceptions in other methods which are not caught are also passed down the line as failures. I was thinking of passing all failures as tink.core.Error, but it does makes catch() in an async method kind of useless for other types.

kevinresol commented 8 years ago

How about this:

try {...}
catch(e:Error) __return(Failure(e))
catch(e:Dynamic) __return(Failure(Error.withData('Other error', e)));
benmerckx commented 8 years ago

Yes, that's what I'd do, but I mean handling the error aftwards:

try
  @:await asyncMethod()
catch(e: Error)
  //...

You can't differentiate by throwing a different type, all would be of type Error. But on the other hand it's probably better than not knowing the type anyway.

kevinresol commented 8 years ago

I think I prefer having all failures typed as Error, that would preserve the error position and stack

benmerckx commented 8 years ago

Alright, I'll get this done in the next update.

benmerckx commented 8 years ago

Conversation continues here: https://github.com/haxetink/tink_await/issues/4