On Sat, Mar 10, 2018 at 6:42 AM, Carsten Haitzler <ras...@rasterman.com> wrote:
> On Fri, 9 Mar 2018 10:52:59 -0300 Gustavo Sverzut Barbieri 
> <barbi...@gmail.com>
> said:
>> On Thu, Mar 8, 2018 at 4:58 AM, Carsten Haitzler <ras...@rasterman.com> 
>> wrote:
>> > On Thu, 1 Mar 2018 14:11:26 -0300 Gustavo Sverzut Barbieri
>> > <barbi...@gmail.com> said:
>> >
>> >> On Wed, Feb 28, 2018 at 2:33 AM, Carsten Haitzler <ras...@rasterman.com>
>> >> wrote:
>> >> > On Tue, 27 Feb 2018 18:34:59 -0500 Cedric Bail <ced...@ddlm.me> said:
>> >> >
>> >> >> -------- Original Message --------
>> >> >>  On February 27, 2018 2:52 PM, Carsten Haitzler <ras...@rasterman.com>
>> >> >> wrote:
>> >> >>
>> >> >> >so I'm implementing a new efl.exe class (and efl.task and some others)
>> >> >> >and i
>> >> >> > WAS going to use a future as the return for run() ... but after just
>> >> >> > writing about 20 lines of code (get a scheduler, create a promise
>> >> >> > alloc promise data and all the checking in between) and i then
>> >> >> > realized... it's ballooning to an insane amount of code vs
>> >> >> > event_callback_call which is a 1 line func call when the event
>> >> >> > happens.
>> >> >> >
>> >> >> > let me just copy and paste the relevant lines i had sketched out (was
>> >> >> > not final or even compiling yet):
>> >> >> >
>> >> >> > typedef struct _Efl_Exe_Run_Data
>> >> >> > {
>> >> >> > Eo *obj;
>> >> >> > } Efl_Exe_Run_Data;
>> >>
>> >> not sure you need this
>> >
>> > i need to report the object the future is for with the future... and i 
>> > don't
>> > want to rely on people having to use the data ptr for that. this is 
>> > probably
>> > one of the most common needs/uses of a future - that it's a one off action
>> > FOR an object.
>> well, the thing is: promise is about a value, not anything else... if
>> we start to misuse, it start to become less useful.
> actually it's about calling success or failure at some point in the future and
> standardizing this so you can have those all/race things and chain a then b
> then c etc.
> value is actually secondary to this.

not really, value is core part of it :-)

>> for instance, with events rarely we carry payload info, usually one
>> queries from the object... like text changed on widgets.
>> however for promises, with the chaining idea, rarely you should be
>> getting the owner object... in the rare cases you need it, use "the
>> closure" (void *data), which BTW is specific for each future in the
>> chain, then you can chain multiple and "pass thru" the value if you
>> need multiple objects (ie: say you need to get a value and show it to
>> 2 label objects, you can connect 2 cb in a chain, each with a label
>> object.
> actually it's going to be incredibly common. example:
> file_set on an image object... what do you think people want to do? they want
> to then SHOW the object or emit a signal to it or something. they want to
> initiate some response.
> for exe's and threads the object will not be magically deleted if the exe
> exits or thread exits. the object has to exist firstly to collect the results
> (i/o, exit code results etc.) - it has fd's it has to listen on etc. etc. ...

not sure if you checked the efl_future (EFL, not EINA) version I told
you... the object goes there for you... no need for you, the promise
creator, to do that...

the promise create should only care about resolving a value or rejecting it.

> if the object is deleted the promise cannot "continue" and report success or
> failure. it won't know. all tracking of the child is deleted. i have chosen 
> for
> now at least that deletion doesn't block and wait for a child to exit nor
> initiate any exiting (of thread or exe).

this breaks promises completely. You need to pick a concept and stick
to it. For example, if we're allowing this. "detach" thing, then add a
new ERROR_DETACHED or the likes and use that in every promise that may
be disconnected.

However, as I wrote before, more than just doing that, allowing the
user to control the behavior would be nice, given the very rare cases
detach is expected could do 1 prop-set more to get desired results.

> but... once the thread or exe has exited... the object SHOULD then be deleted.
> otherwise it hangs around forever consuming memory for no reason other than to
> store an exit code and any other data the user may have attached to it.

here you're mixing things. It traces back to the other discussion
about invalidate x reference... the object should be invalidated,
sure... not deleted as refcounts shouldn't be messed up.

then check that discussion on "release ref on invalidate"

it's not particular of promise/future.

> thus the object should always be provided to the future (success or failure)
> because it is basically expected that you "do something about it" and delete
> the object. if you do not then it'll leak. if you manage to somehow chain
> things so you delete something else (a parent object etc.) and then this gets
> magically deleted along with that - great. but most of the time you have to
> handle the deletion manually because of autodel being bad for c++ etc.

that's because you're solving the wrong problem at the wrong layer.
See above, mixing invalidate x ref...

last but not least, if you read my examples above, a single future can
solve this in every case:

    eina_future_chain(obj_returns_a_future(obj), ...
        efl_future_unref_cb(obj)); // this returns Eina_Future_Desc
that efl_unref() obj once the future is resolved, can be the own obj
or another

Check how promises are used elsewhere, they are not "one big single
callback", rather small pieces that are chained together. It's not
"single-shot-event", as you're trying to do :-(

it would help if you do give it a try as an user... otherwise you're
creating an API intended for users you really don't know.

>> anyway, last but not least `efl_future` (not EINA) is bound to an
>> object and carries it automatically for you... so basically if the
>> user needs that behavior, just use that helper.
> does the promise cancel (and thus call the fail cb) automatically if the obj 
> is
> deleted?

YES, that's what efl_future does... it binds the future to the object
life... it will be the default for .eo, as eolian will generate these
calls for you (at wrapper layer, so you don't need to... that's why
it's marked in my code, so we can remove the manual calls). Some API
will be able to return unbounded future using some special attribute.

>> >> >> > static void
>> >> >> > _efl_exe_run_cancel(void *data, const Eina_Promise *dead_ptr
>> >> >> > EINA_UNUSED) {
>> >> >> > Efl_Exe_Run_Data *d = data;
>> >> >> >
>> >> >> > efl_task_end(d->obj);
>> >> >> >}
>> >> >> >
>> >> >> > Efl_Exe_Run_Data *d;
>> >> >> > Eina_Promise *p;
>> >> >> >
>> >> >> > d = calloc(1, sizeof(Efl_Exe_Run_Data));
>> >> >> > d->obj = obj;
>> >> >> >p = eina_promise_new(sched, _efl_exe_run_cancel, d);
>> >> >> > d->promise = p;
>> >> >> >d->run_future = efl_future_Eina_FutureXXX_then(obj,
>> >> >> >eina_future_new(p)); return d->run_future;
>> >> >>
>> >> >> You do not need to keep the future at all in your structure. You are
>> >> >> good to go with just :
>> >> >>
>> >> >> return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));
>> >> >
>> >> > then how do i trigger success or failure of the future if i don't have a
>> >> > handle on it - well promise/future... whatever. same thing to me. i
>> >> > dislike the whole division of promise vs future. to me it's an async
>> >> > task that at some point in the future triggers a success or failure then
>> >> > disappears after that.
>> >>
>> >> you just keep the write/send side: Eina_Promise: p... that's where you
>> >> send your results.
>> >
>> > well i need to keep a handle to something. that's my point.
>> for this particular case you shouldn't need "d". call
>> eina_promise_new() without any data OR with the handle used to
>> *cancel* the promise, that's it and only it :-)
> i need a handle so i can fulfil the promise later (or cancel on object
> deletion and thus fail). without that i can't pass on the result.

in your task case, since you can't run more than once, this can go
into the pd->promise...

>> also, don't keep the reference to d->run_future... it's wrong, you're
>> not supposed to ever touch it anymore, the ownership is passed to the
>> caller...
>> it's being misused... the one that creates the promise, only keep the
>> promise... you don't even need to store it in pd or obj in any way,
>> since efl_future (not EINA) will bind it to the object, whenever the
>> object dies the promise will be automatically cancelled.
> ok. that certainly wasn't clear. but i still need something so when the exit
> happens i trigger the promise success or failure (exit code 0 == success,
> anything else, failure)

note that this needs to be a convention. For instance, most HTTP
frameworks do NOT reject the promise on HTTP status not in
200-range... their convention is that it will return the promise with
the status. Rejection just occurs on network failures (ie: the HTTP
request didn't finish).

If you ask me, for processes, rejecting on status != 0 is bad since it
will be harder to pass the value (there is no standard for you to
convert that to an Eina_Error, or "Exception" or "Error" in other
languages). And some people do use return status as "0" (all right)
but others to indicate the kind of failure (ie: 1 = invalid params, 2
= failed resources, ...). These won't be able to use your promise.

that's the reason why the http/promise people use that, so 50x is
handled on way, 40x is another, etc. very similar proble.

>> all you need is to pass "p" (the promise!) to the task resolution...
>> once it's resolved/done, call eina_promise_resolve().
> yes - so i need to keep that around. either way i need to keep something. that
> is my point.

you'd need that anyway since you can't allow more than one run to exist...

>> if you have the full code for what you're doing, including when "it
>> should resolve", I can pinpoint how to do it. Maybe send a Phab ticket
>> and mark me.
> https://git.enlightenment.org/core/efl.git/tree/src/lib/ecore/efl_exe.c#n188

1) if you're using promise, why are you emitting an event? Remove that
2) there is no need to keep exit_called
3) there is no need to efl_ref
4) there is no need to efl_job, promises are already resolved in the
next mainloop iteration (clean context)

your _exit_eval should be:

if (pd->promise) {
   eina_promise_resolve(pd->promise, eina_value_int_init(status));
   pd->promise = NULL;

that's all. Also it seems you're trying to call exit_eval too early,
ie from broken pipe... shouldn't you let the process exit, be
collected by waitpid() and JUST THEN you call the promise resolve from
a single place?

> https://git.enlightenment.org/core/efl.git/tree/src/lib/ecore/efl_thread.c#n318
> those are an eventual result of the run() method.

like above, code is very similar.

>> >> >> > i got to 22 lines and i wasn't even done yet (need to do some more
>> >> >> > housekeeping)... vs 1 line for event_callback_call. i'm going with
>> >> >> > events until futures/promises are not a crazy amount of code compared
>> >> >> > to events. this is it with events:
>> >> >> >
>> >> >> > efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL);
>> >> >>
>> >> >> This is absolutely not doing what the future code is doing. You are not
>> >> >> detecting when a user has removed the handler and so call efl_task_end
>> >> >> accordingly. You are also not sending a structure with the exit code
>> >> >> either
>> >> >
>> >> > i don't need to send the data in a future - it's stored on the object
>> >> > anyway. you pick it up with a get from the object.
>> >>
>> >> well, that's misuse of the promise result... if you're running
>> >> something to get data, that's what you should get at the end, not the
>> >> object...
>> >
>> > the object represents the execution of that task (exe) d it survives the
>> > death of the exe or thread until its voluntarily deleted so data can be
>> > retrieved from it "at leisure". i don't think storing this data on the
>> > object is wrong at all because it does need to exist somewhere and storing
>> > it here is far more convenient. it's not transient data. it doesn't keep
>> > changing like i/o. it's stored once and stays.
>> I think you still don't get it, what's promises meant.
> i do. see above at the top of my replies.

reading what you wrote and the code you pointed me, you don't...

it would help immensely if you give it a try for real... before you
implement the promise side (provider), give it a try as an user... get
some js stuff, they are full of promise, then you use to implement
something, then you come back with your experience...

ie: https://github.com/axios/axios (http) + https://redux-saga.js.org
(state management) ?

>> When someone say "promise you'll run this exe and return me its
>> result". The promise is exactly that: run until it finishes, get me
>> its exit code.
>> In most systems, Promises are not cancellable. However in EFL we opted
>> to introduce the cancel behavior in order to be friendly with memory
>> handling (no garbage collectors and the likes) and resources (ie: why
>> keep working if that's to be ignored?).
>> Then eina_future_cancel(future) will cancel the whole chain. One can
>> use this, for instance, in a Race, where the winner continues and the
>> other promises are cancelled. Example: race a process execution
>> against a timeout, to automatically stop the process if the timeout
>> happens.
>> And note I mention the "chain", so you could have this written as:
>>   - race(
>>       - exe -> to_string -> text_set -> enable_button
>>       - timeout
>>     )
>> The exe would be executed, the exit code would be converted to a
>> string, displayed to a label and then a button would be enabled (ie:
>> "next").
>> If the timeout happens, none of those would happen.
>> That's the thing with chaining... while "to_string" already exists,
>> the others can be easily made into elm and code is simpler to write...
>> like lego blocks.
>> >> if the user needs the object, he can pass that as his future cb data.
>> >
>> > i disagree with this. the data should be THEIR data, not the object. since
>> > the object has to be deleted on exit or some point after that, the object
>> > is needed pretty much, so why use up the only data ptr just for that when
>> > its a necessity?
>> depending on how you do it, you don't need the object... see examples
>> above, the idea with chaining is that you can add more stuff easily.
>> So take my pipeline and add one more:
>>   - exe -> to_string -> text_set -> enable_button -> unref(obj)
>> the only place you need "obj" is at the end, *none* of the other
>> handlers would get it... and actually if it was passed, it would be
>> lost in the first conversion "to_string".
> the problem is they this is only if they manage to track that exe obj
> explicitly and track it down at the end of a chain of stuff... invariably 99%
> of the time i'd say they will want to clean it up right away when they get
> their exit code/result and not have to figure out how to pass it down
> themselves.

in such case, just invert the order, that's the beauty of it:

 exe -> unref(obj) -> to_string -> text_set -> enable_button

this still works, since to_string operates on the result (int), there
is no need to query the value from obj (exe). But say you needed, you
can still reorder:

 exe -> to_string -> unref(obj) -> text_set -> enable_button


>> > no. we can't auto-del the object no matter how much i'd love to. felipe
>> > would kill me. :) ...
>> i guess we're talking about different things here.
>> >> the idea is that these things can be chained, including transformations...
>> >> like:
>> >>
>> >>   bla.run().then(uppercase).then(console.log)
>> >>
>> >> we even offer some converters and a console future for such things.
>> >> Actually we should even do more,
>> >> like those exposed by http://reactivex.io, handling multiple wait,
>> >> debounce, etc.
>> >
>> > i know what they are for. :)
>> yes, so take that as inspiration when adding promises: what's the data
>> that should be passed. Don't see promises simply as "single call
>> events", that's wrong.
> they are actually both. they are single call events that follow a standard api
> etc. as above at the top.

then you miss a big part of its usefulness :-(

>> the idea with future is the chain-ability... if you ignore that, it's
>> almost useless as it's a sub-case of "events".
> and that's a nice thing about them - they standardize chaining etc. thus 
> making
> for nice syntax sugar etc. i know this.
> they are painful to DRIVE from code in C in objects which are running the show
> in terms of doing the i/o and finally feeding results to the promises.

Well, in the code I read they were painful because you overdid things.
The flag isn't needed, the job isn't needed, the ref isn't needed...
then of course, it's start to be cumbersome! :-D

if you ask me, the real PITA with promises in C is lack of lambda.
This is the real pain, having to declare the callbacks OUTSIDE of your
context, not being able to capture...

I had proposed to implement c++ lambdas in C as a pre-processor... but
nobody wanted to pay.

nonetheless, if we start to use promises for real and correctly, we
can start to add some "future cb" library to make that less painful.
We did some examples, like type-convert and "print to console"... but
linking to UI would be super-nice (ie: enable/disable, text-set,
focus, ...). Also some flow control (ie: call this parallel chain if
this condition is true, ie "value == 0") and merging multiple chains
(ie: wait button click AND data AND timeout... then emit a tuple).

and that's why I'm insisting so much on the value thing... if you do
have a proper value for exe, then you can get this. With that you can
even do some UI editor or save this as as part fo eet (ie: Gstreamer
offers "gst-launch" to test stuff, can load pipelines from xml...)

>> >> > oooh... no no no. first - i don;t need know now if the handler has been
>> >> > added or removed because callback_call handles that for me.
>> >> > and calling end() sent a
>> >> > signal to the child process to request it to end... it does not mean it
>> >> > has ended yet. so you would never sensibly call end from the exit event
>> >> > cb because that's sending end to a process that no longer exists... just
>> >> > the object representing it does still to store the results.
>> >> >
>> >> > so maybe you mean "del()" the object if the caller isn't listening for
>> >> > exit events... It'd LOVE to do that, but c++ people will hate autodel...
>> >> > which is exactly what that would be.
>> >>
>> >> well, that's exactly what the promise does, and to consider "match
>> >> behavior", that's what you should do.
>> >
>> > the promise is deleted.. the exe etc. object cant be. and that object has 
>> > to
>> > stay around because you need long term control like sending term/kill
>> > signals or handling i/o to and from it.
>> you're not deleting the object. you're cancelling the task,  no
>> refcnt(exe) is changed.
> the caller has to delete (or unref etc.) the object. see above. if they don't
> it'll stay around forever.

this is the invalidate x unref discussion from the other thread.

anyway, you can explicitly add the future to do that OUTSIDE, which
would enable things like this:


this would unref all 3 objects once the future dispatches... note
efl_future_cb_unref() doesn't exist, it need to be created like the
other helpers that returns Eina_Future_Desc...

>> cancelling the task = sending term/kill signals or i/o commands.
> which may eventually result in an exit from the process which then will result
> in the current exit event (or the promise success/cancel callbacks if those
> were used).

and isn't it the desired? Just note that since the promise is already
rejected with ECANCELLED, it won't be rejected anymore...

>> >> usually with regular events we'd just "forget" about it and leave the
>> >> task running, doing its process without cancelling... which is bad
>> >> most of the time.
>> >
>> > yes. that's why the object stays - it's not just a simple promise that
>> > fails or succeeds. there is an exit code, there is i/o etc. ...
>> >
>> > in theory if you don't care about the results you could delete the exe or
>> > even thread obj and thus lose your connection to it and control lines...
>> > but then never get a result. :)
>> ok, to allow "dangling" promise you'd need to make it unbounded to the
>> object...  so you delete the object and the promise would still remain
>> alive, not "auto kill" the task.
> that's just not sane to do (as above - object needed to drive the i/o and
> listening of the exit of a thread or exe). so deletion probably has to result
> in the promise failing.

here I'm talking about forcing dangling threads or processes... there
are cases for those, for them making a property... however they are
not the common cases, not even sure we should care to support these

> yes in theory i could separate the tracking out of the object and have the
> object just be a "view" into an internal tracker. that'd add a lot of extra
> code and complexity i'm not sure is a good thing.
>> While I see some usage for this behavior, most of the time this is
>> going to lead to incorrect behavior.
>> For the rare cases where this could be used, task could use the same
>> approach as I did for io.closer and define "auto stop on delete"
>> property. If true (default), once the object is deleted or the promise
>> is canceled, the task is stopped. If false, it's left running
>> dangling... with associated handlers (task/promise) freed.
> the problem with the former (stopping the task is a need to wait for a
> response to know what kind of exit happened. art this stage i dislike this. i
> did consider having it block and wait, but decided against it. you can even 
> see
> commented out code in efl_thread.c to do just this. this is the kind of thing 
> i
> wanted to have discussions on in that thread/exe etc. thread. not superficial
> stuff like args - i added the void *'s easily enough but everyone id 
> distracted
> by  things like that and not more core questions like this. should delete
> stop/kill a task ... and should it then wait for a response? the latter is the
> cleanest, but its is fragile if threads or exe's refuse to nicely exit.

not sure you got the idea, but if you cancel a promise/future-chain
you get a resolution ECANCELLED automatically... there is no reason
you should wait it synchronously to finish, basically:

exe_promise_cancel(void *data, const Eina_Promise *dead_promise EINA_UNUSED)
   Exe_Private_Data *pd = data;
   kill(pd->pid, SIGTERM);
   pd->promise = NULL;

that's all... the ECANCELLED is used automatically to reject, all you
need to do is to invalidate the promise pointer (thus it's given as
parameter, if you have more than one that could be the pointer to make
NULL, like in a list/array).

>> >> >> (and of course you are not describing it in the .eo file). I don't even
>> >> >> see how you can compare this two lines ? And we are not even looking at
>> >> >> the user of the API here which is what matter even more. How do you
>> >> >> make sure that the event is always delivered properly ? How often do
>> >> >> you generate the event (Every time someone register a callback) ? There
>> >> >> is a lot of open question with this kind of API that you are just
>> >> >> disregarding here.
>> >> >
>> >> > it's called when the parent process knows the child has exited and what
>> >> > the exit code is. there is no guarantee this happens during the life of
>> >> > the object at all. the process could become hung on a kernel syscall and
>> >> > never exit, ever. that's what the exit event is. when this happens. it's
>> >> > guaranteed to be called when this event occurs.
>> >> >
>> >> > my point is the event is 1 line. futures is a massive blob of code to
>> >> > achieve the same goal. i find them basically unusable to the point that
>> >> > i'm just avoiding them now. if they were "1 liners" too... then great.
>> >> > but they are not. (well they will be a line to create and store, a line
>> >> > in a destructor to cancel on destruction if still there and another line
>> >> > in the "where the event happens" to either call success or failure with
>> >> > the future data... but it needs to be far far far simpler than it is.
>> >>
>> >> you just realize that the code is always the same, right? there is no
>> >> magic, we're just doing something on behalf of users, in a clear and
>> >> standard way.
>> >
>> > ummm it's not the same. its far longer. even if its half of what i 
>> > described
>> > it's still far longer than an event.
>> I'll not even bother to explain it's doing more on user's behalf... I
>> tried, Cedric tried, seems you don't want to see.
> i know that.. i'm not talking about the outside api to users. i'm talking 
> about
> the inside api to efl to drive them.

let's start with fixing the code? Once it's correct we can think about
adding some helpers. the one efl_promise_new(), that creates a promise
using an efl_loop_provider object as argument looks like a good one to
start with.

>> but part of the extra work is due your misusage of the api.
> other storing run_future too.. i still need to store  SOME handle to this
> future/promise thing so i can trigger it with "it's done - here is the 
> result".

but flag isn't needed, job isn't needed, ref isn't needed...

>> >> so yes, you're doing bit more work so users don't have to. Like
>> >> keeping references, canceling, etc. Our hope is that core devs (that
>> >> usually deal with eina_promise part) will be more careful with
>> >> managements and the likes.
>> >
>> > a LOT more work. and the user doesn't do less.they still have to provide a
>> > function to call on exit.
>> what?
> the user of the api still provide a function to be called. in fact has to
> provide 2 (success and failure).

not really, this is the helper to auto-check for errors... the core is
only one function and you'd need to check the value (eina_error or
whatever you need).

>> >> users just pass one callback and *always* get called (even with
>> >> "ECANCELED").
>> >>
>> >> as for "lines of code", for sure we could offer a way to "add a
>> >> promise to this object", it would fetch the "loop" from a loop-user,
>> >> then fetch the scheduler... then create the promise and return.
>> >
>> > that's my point. that isn't there. and promises/futures code is just a
>> > hairball that figuring out how to add it is not something i want to spend
>> > time on. i've already fixed some things there, but i have gotten to the
>> > point where i now am going to work around them instead. i am not even using
>> > the timeout futures anymore as they crash (i decided to set null to the
>> > content to try and catch it more easily rather than have junk)...
>> >
>> > they are just not worth the pain IMHO as it stands.
>> as I commented in the other PR, it's a bug somewhere else, we couldn't
>> see the failing code, but even with that the promise should be
>> protected by mempool checks, if it's crashing at least the mempool
>> check is buggy (since it should say the memory isn't valid).
> the failing code happens in non-main loop loops it seems. :) i had it crash
> every single time. i gave up and used efl loop timer objects instead in my
> examples on the phab wiki page on exe/thread/task .... try replace them with
> timeout futures and see. :)
>> >> the "cancel the promise" part is already done by the efl_future (note:
>> >> "EFL", not "EINA"), which binds the future/promise to the object
>> >> life... on destruction they are automatically cleared. As Cedric said,
>> >> once old efl_future dies and Eolian gets future<x> mapping, this will
>> >> be generated for you.
>> >
>> > it's not there. it's not documented that well and certainly doesn't have 
>> > the
>> > helpers needed like above, and minimal good examples that are concise and
>> > simple.
>> ok, examples and docs may be missing indeed.
> so i go by what samples i can find and i base my code off them... and then as 
> i
> trace them more and i have  10 then 20 lines of code i stop and go "wtf?".
>> > so either make futures sane and sensible to use from within efl, or give
>> > up. i certainly am not writing a huge blob of code every time a future
>> > needs to be used. efl wax created originally to serve enlightenment and
>> > it's needs. e is in c. associated needs are too. futures do not make things
>> > simpler or easier there. it's some nicer syntax sugar in js etc. ... but
>> > this is just making code harder to use and worse for ourselves in the name
>> > of a currently non-existent js usersbase. if it came with "minimal effort
>> > beyond events" then fine. support this theoretical userbase and maybe it
>> > might happen. it's not minimal. that is my point. i don't see it moving
>> > anywhere either at this point. :(
>> time to step back and try to understand what's a promise, a future,
>> chaining and how to properly create and use a promise.
>> docs may be missing, indeed... I can't help with that right now (lack
>> of time), but for sure the concepts/theory part is broken in your
>> head... sorry :-(
> i know full well what they are. what i am pointing out is they are a pain to
> drive from the efl side.

if you try to drive a car like a motorcycle, you're going to have problems

> and there are bugs lurking in them to boot. hard to build anything on top.

no doubt can exist bugs, cedric spotted one that is with a
not-so-common case we're trying to solve (return a resolved promise
from a future, not common as you'd normally just return the result,
not a resolved future... but still a bug).

I can't test your example atm, not even a linux machine/vm hanging
around and time is short for me... but I hope others can give it a
try. If the bug is really on the promise/future I'll try to assign
someone to check it

Gustavo Sverzut Barbieri
Mobile: +55 (16) 99354-9890

Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
enlightenment-devel mailing list

Reply via email to