<div dir="ltr">without examining the details, i am not sure if this achieves the same thing but this reminds me somewhat of the promises and deferreds in the javascript dojo library: <a href="http://dojotoolkit.org/reference-guide/1.9/dojo/Deferred.html">http://dojotoolkit.org/reference-guide/1.9/dojo/Deferred.html</a>.<div>
<br></div><div>e.g. i use this in:</div><div><br></div><div><div>        getObject: function(way, path, callback){</div><div>            return xhr.get("/object/"+way+"/"+path, {</div><div>                handleAs:"json"</div>
<div>            })<b>.then</b>(function(json_object){ </div><div>                callback(json_object);</div><div>            }, function(err){</div><div>                console.error(err); </div><div>            });</div>
<div>        },</div></div><div><br></div><div>xhr.get() is an AJAX call and the result of the call is handeled async in the then() method. I have no idea how this is implemented in js, but i like the api as being intuitive.</div>
<div><br></div><div>You can also chain these so called promises: some_func_returning_promise().then().then().then()  </div><div><br></div><div>Cheers, Lars</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Wed, Sep 4, 2013 at 12:52 AM, Richard Tew <span dir="ltr"><<a href="mailto:richard.m.tew@gmail.com" target="_blank">richard.m.tew@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I think that unless you are intentionally presenting an identical API,<br>
using classes as a namespacing extension as they do in C# and Java is<br>
probably avoided.  When I program in C# and Java, I often get the<br>
feeling that they do things some ways because they have to, because<br>
they don't have better fitting alternatives.<br>
<br>
I do not find function names beginning with "when" intuitive, and find<br>
it hard to suggest better alternatives as they just confuse me and I<br>
am not quite sure what they are supposed to do.<br>
<br>
Whether you are polling to see if things are ready, or getting what<br>
they have made ready, deciding on the best function name seems like<br>
something best considered with  all things in mind.  Like whether you<br>
want the call to wait with a timeout.  Whether exceptions are raised<br>
or returned.<br>
<br>
The C# exception wrapping has always seemed like an approach they have<br>
adopted because of architectural limitations.<br>
<br>
I would rather the following was done:<br>
<br>
  for task in tasks:<br>
    try:<br>
        result = task.invoke_result()<br>
    except:<br>
        # handle<br>
<br>
I chose invoke rather than get, because it is more evocative of the<br>
result also reasonably being an exception.<br>
<br>
Other approaches could force complexity in order to be able to provide<br>
"helper" methods, when it might be worth considering whether it is<br>
possible to avoid them in the first place.<br>
<br>
Or:<br>
<br>
  try:<br>
    result = async.invoke_one_result_picked_out_at_random(tasks)<br>
  except:<br>
    # handle<br>
<br>
.. where a task with a result or error returns or raises respectively,<br>
as a successful result of a call choosing that task.<br>
<br>
Then there are your decorators in your original post.  I look at them,<br>
and I don't quite feel they are the right approach.  Firstly, when you<br>
wrap a function with them, if that function is general purpose, then<br>
isn't it now locked into the async system and no longer suitable for<br>
calls made from outside of it?  And secondly, the functions they wrap<br>
look like synchronous functions when actually called, despite now<br>
being magicked into some magical task creation that works on in the<br>
background while returning to the original function.<br>
<br>
I'm still not clear on why indexes are returned, rather than tasks directly.<br>
<br>
For a lot of this, I think that best choices can be made in view of a<br>
complete list of intended functionality.  Something like:<br>
<br>
Lists of tasks:<br>
- Get all results for a list of tasks, whether returned or exceptions raised.<br>
- Get one result from a list of tasks, whether returned or exceptions raised.<br>
- Get the set of completed tasks from a list of tasks.<br>
<br>
Per-task:<br>
- Get the result, whether returned or exception raised.<br>
<br>
Does there have to be timeout functionality for these calls?  I think<br>
there does.  How is that handled?<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
On Wed, Sep 4, 2013 at 1:25 AM, Kristján Valur Jónsson<br>
<<a href="mailto:kristjan@ccpgames.com">kristjan@ccpgames.com</a>> wrote:<br>
> Thanks for your feedback.<br>
> The original "Task" interface in C# is perhaps not something we need to closely follow.<br>
> As I understand it, "task based asynchronous programming" came before the "await" semantics.<br>
> It makes a distinction between waiting for a result, and returning its value.  Although Wait will throw an exception if task execution throws an exception....<br>
> So anyway, I _think_ that in C# you<br>
> t.Wait()<br>
> return t.Result<br>
><br>
> which separates these things awkwardly.<br>
><br>
> In my implementation of async.Task, I added a get_result() which combines the two.<br>
><br>
> I think it makes sense to create a module function, get_all_results() which operates on an iterable of Tasks. and returns a list of actual values, or raises an exception<br>
> This can be augmented with a "when_all_results()" function which returns a Task object.<br>
> Simlilarly "get_any_result()" returning an index and value, and "when_any_result"<br>
><br>
> This could then be used in preference to the Task-like WaitAll or WaitAny et al.<br>
><br>
> I also think I prefer module global functions to class methods, what do you think?<br>
><br>
> One interesting thing that .NET does, and these functions, is that they throw "AggregateException" wrapping the original error.  "await" does not.<br>
> Do you have any thought on that?<br>
><br>
> See:<br>
><br>
> <a href="http://stackoverflow.com/questions/18314961/i-want-await-to-throw-aggregateexception-not-just-the-first-exception" target="_blank">http://stackoverflow.com/questions/18314961/i-want-await-to-throw-aggregateexception-not-just-the-first-exception</a><br>

><br>
><br>
><br>
>> -----Original Message-----<br>
>> From: <a href="mailto:stackless-bounces@stackless.com">stackless-bounces@stackless.com</a> [mailto:<a href="mailto:stackless-">stackless-</a><br>
>> <a href="mailto:bounces@stackless.com">bounces@stackless.com</a>] On Behalf Of Richard Tew<br>
>> Sent: 2. september 2013 23:06<br>
>> To: The Stackless Python Mailing List<br>
>> Subject: Re: [Stackless] stacklesslib.async<br>
>><br>
>> I think this general sort of functionality has long been needed in Stackless,<br>
>> and it brings up the old sawhorse of why are we not including stacklesslib in<br>
>> Stackless distribution.  But let's ignore that for now.<br>
>><br>
>> I like the idea of having a standard well received API from another popular<br>
>> language, that people can just pick up and use with approximately same<br>
>> namespace - even if the coding standards for this specific API conflict with<br>
>> the rest of the package.<br>
>><br>
>> That said I don't get the API.  It seems badly designed.<br>
>><br>
>> To me, not having looked at the C# API much, I expect waitAll and waitAny<br>
>> should return the result of the tasks that completed with the index of each in<br>
>> the list.<br>
>><br>
>> [ (0, text), ] = x.waitAny([ t1, t2 ])<br>
>><br>
>> And whenAll and whenAny should imply there's a result, but not pull it.<br>
>><br>
>> [ 0 ] = async.whenAny([ t1, t2 ])<br>
>><br>
>> Then again, why return indexes.  That just means you have to waste time<br>
>> holding onto the original list, if you do not have a permanent one.<br>
>><br>
>> But I think that this should not just handle tasklet completion, it should also<br>
>> handle tasklets producing results via channels.  In that case, it is useful to poll<br>
>> whether any tasklets have results, rather than waitX with a minimum<br>
>> timeout.<br>
>><br>
>> I think that this should be in, but there surely can be a more natural fit.  And<br>
>> this might mean a requirement for lower level support.<br>
>><br>
>> And having written all this, the elephant in the room is that I believe CSP,<br>
>> which Andrew Francis has long been advocating, is closer to what I think we<br>
>> need.  However, I've long had problems with using it ad hoc, as I think it is not<br>
>> that user friendly and is more theoretically balanced than functionally<br>
>> balanced.<br>
>><br>
>> Cheers,<br>
>> Richard.<br>
>><br>
>> _______________________________________________<br>
>> Stackless mailing list<br>
>> <a href="mailto:Stackless@stackless.com">Stackless@stackless.com</a><br>
>> <a href="http://www.stackless.com/mailman/listinfo/stackless" target="_blank">http://www.stackless.com/mailman/listinfo/stackless</a><br>
><br>
><br>
><br>
> _______________________________________________<br>
> Stackless mailing list<br>
> <a href="mailto:Stackless@stackless.com">Stackless@stackless.com</a><br>
> <a href="http://www.stackless.com/mailman/listinfo/stackless" target="_blank">http://www.stackless.com/mailman/listinfo/stackless</a><br>
<br>
_______________________________________________<br>
Stackless mailing list<br>
<a href="mailto:Stackless@stackless.com">Stackless@stackless.com</a><br>
<a href="http://www.stackless.com/mailman/listinfo/stackless" target="_blank">http://www.stackless.com/mailman/listinfo/stackless</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>====================================<br>Lars van Gemerden<br><a href="mailto:lars@rational-it.com">lars@rational-it.com</a><br>+31 6 26 88 55 39<br>
====================================
</div>