On 28/09/16 13:42, Tom Hacohen wrote:
> On 21/09/16 03:35, Felipe Magno de Almeida wrote:
>> On Sun, Sep 18, 2016 at 3:35 AM, Davide Andreoli <[email protected]> 
>> wrote:
>>> 2016-09-18 4:30 GMT+02:00 Felipe Magno de Almeida <
>>> [email protected]>:
>>>> On Sep 17, 2016 3:53 AM, "Davide Andreoli" <[email protected]> wrote:
>>
>> [snip]
>>
>>>> The problem with callbacks is not difficult to implement, but difficult to
>>>> free the void* data. It needs two function pointers and the void* data to
>>>> implement correctly and generally. Not that I'm against per se, but
>>>> lifetime is the real problem.
>>>
>>> Indeed the lifetime of the *void data is the trickiest part, a free_data_cb
>>> seems to me the most "correct" way to handle this, not only for bindings
>>> but also for C code.
>>>
>>> Can you explain me how promises solve this problem? where the user is
>>> expected to free the *data in C? in both the success/failure callbacks?
>>
>> Promises are not generic, so their lifetime is known. The user frees it in
>> success/failure callback, yes.
>
> This is a bias to the promise solution, a bias that has been around ever
> since promises were introduced. Davide's idea could be implemented just
> as well if given the same assumptions.
>
> At the moment we have promises, they are manually handled by bindings
> and they, as you said, are not generic. More specifically, they die
> after success/failure is called.
>
> If you follow the same restrictions, you can easily just add a callback
> function and a data pointer to APIs. The data will be released by the
> caller after the call. Bindings can easily deal with that.
>
> And to put this in a more generic sense, we could allow "one-time"
> callbacks (of a shared signature) in Eolian to solve all of this class
> of problems without the overhead of promises.
>
> We could make the "event info" (I'd keep the same callback signature for
> consistency) of this callback indicate if it's been successful or not
> (i.e. then/catch) which will also let you easily create race/all. A code
> example (for race, all is almost identical):
>
> // API we provide
> struct {
>       func: cb;
>       void *: data;
> } promise_cb;
>
> typedef Promise_Race; // This needs a better name, as it's shared with all.
>
> promise_cb *promise_cb_get(Promise_Race *promise);
>
> // user code:
> Promise_Race *race = race_add();
> file_set(obj, promise_cb_get(race));
> image_load(obj, promise_cb_get(race));
> race_then({.func = user_race_finished_cb, .data = user_data});
>
> Race is then a very lightweight structure that needs no handling.
>

One clarification: the example above does not handle reuse of promises, 
that is, use the result of file_set() in both race and all (for 
example). This, I assume, is a more rare occasion. However, there's a 
simple solution to that too. You would explicitly create a new promise 
that supports multiple "then/catch".

This gets more similar to the original promise proposal, that just used 
basic structures and was passed as a parameter to some functions. This 
may be the better solution after all. I'm writing another email to 
clarify that stance.

>
> This comes back to what I've been saying for a year, there are many more
> ways to solve this problem, and if you ask me, most of which are much
> cleaner than promises, or at least the suggested handling.
>
> I like this one much better than I like the previously proposed promises
> solution.




------------------------------------------------------------------------------
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to