On Sat, Jun 18, 2016 at 10:56 PM, Carsten Haitzler <ras...@rasterman.com> wrote:
> On Fri, 17 Jun 2016 11:12:51 -0300 Felipe Magno de Almeida
> <felipe.m.alme...@gmail.com> said:
>
> felipe - look at eina promises then loo at stdc++ promise and futures. they
> dont even match. js promises cant be canceled. lua doesn't even have the idea
> of a promise. what we have in eina_promise doesn't translate to any language
> native future/promise thing. it's very specifically an efl thing and if we do
> it we need to embrace it as such and that's how it goes. it LOOKs like many
> language native promise things but it's extended and efl specific. that's the
> on;y way to use promises we have, otherwise we should drop them entirely and 
> do
> things only by obj + event cb's because this problem space is just too
> fragmented with the lowest common denominator not being even good enough for 
> us
> (no cancel) but not even being enough for other langs (c++ has wait - we 
> don't)

I have explained in the email exactly how they would be translated to C++,
JS and Lua by _not_ being a object used directly by the user translated
automatically by Eolian. So I don't know what you mean. JS will be used
exactly as JavaScript developers are used to, but they will have the option
to cancel as well, and C++ will be able to wait on it or register a callback
function. And for Lua exactly how I explained in the email below. Maybe you
missed my answer to your reply in the bottom of the email,after my answer
to Tom?

> so as you said - then make promises full efl supported objects and they appear
> so in every language and work the same way, as the only other option is to
> drop them entirely.

I neveer said that. And for the reasons I explained below.

>> So, JP asked my opinion privately and he thought it would
>> be better for me to paste what I replied here. I  didn't want
>> to make this discussion longer, however I have to make
>> these points explicit so we can move on. Sorry in advance
>> for the huge email. So I'll paste my answer here and then
>> make some considerations of other points afterwards:
>>
>> ""
>> Hello JP,
>>
>> Now I see I should've voiced myself more in the discussion. But it has been
>> too lengthy and too much things to do before and during the feature freeze,
>> so I kinda absteined myself from it. Which was probably an error because
>> now nobody knows my opinion on the matter.
>>
>> My personal stance on promises being Eo objects is that we're hammering
>> things to be OOP more than it should. IMO, Promises are nothing more
>> than a one-element-containers that warns when the value is available.
>>
>> It is not too much different from Eina_List/Eina_Array, etc. Could we
>> make Eina containers Eo objects? We can, would it have benefits?
>> It would. However, it is always a trade-off and the problems it brings
>> would bigger than the benefits. Java does it and it works, but it slow
>> and invites people to inherit classes in ways they can't possibly do
>> because they, inadvertadly, break the class invariants by changing
>> how the user interacts with the class (by overriding methods).
>>
>> I'm sure in C++, JavaScript and Lua they won't be used as an Eolian
>> class at all, that's even why Kolesa has suggested that it should
>> not even be an Eolian class (but be a Eo class implemented directly),
>> that way people can't inherit from it and bindings don't have to
>> special case the class, like we have to do for Eo.Base.
>>
>> Now, why classes shouldn't generate Promise as an Eolian class?
>> Because it makes no sense and it is _not_ convenient to users.
>> Registering events? What does event have to do with anything?
>> And how do you chain promises like in JavaScript with events?
>> Well, you don't. And how about Lua? Why should Lua even
>> generate a Promise object? In Lua I'd expect the Promise
>> to be used to connect the Lua event loop with co-routines,
>> so the current execution would just get scheduled-out and
>> return execution when the Promise is now fulfilled.
>>
>> The idea that we're going to create the _uber_super_ Promise
>> class for all languages is, IMO, completely impossible. Each
>> language will have its own asynchronous-way to deal with
>> how values are going to be available in the future and which
>> syntax better conveys that concept. Promises in our API,
>> OTH, allow us to _talk_ about asynchronous operations
>> in a way that is well-defined and which bindings can rely
>> enough to do proper code generation without knowing
>> specific semantics of each asynchronous operations. That
>> is not possible with events per se, because bindings
>> don't know anything about them.
>>
>> However, making promises an Eo object is not a problem
>> per se, as long as we have _very_well_defined_
>> semantics for everything, it works exactly the same,
>> but, at the same time, to have very well defined
>> semantics we need to limit on how extensible everything
>> is, otherwise we just get normal events again and
>> that is not well-defined enough to be translatable
>> properly to every language.
>>
>> So, in the end, if we make Promises an Eo/Eolian
>> object with very well defined semantics, we get
>> a "normal class"* that works the same as an
>> Eina_Promise, but uses the Eo syntax
>> for things on C (only on C!), and with that we
>> start paying for things that doesn't seem
>> to make sense IMO, such as the cost of
>> late binding in Eo; the cost of allocating
>> and instantiating a Eo object; etc. Without
>> reaping any benefits. And, IMO, if asynchronous
>> operations are to be _really_ used in EFL, we
>> need promises to be _fast_. Asynchronous
>> operations already have a inherent cost of
>> having to use heap memory where synchronous
>> operations can just use stack allocation, if
>> we make the cost considerably bigger, then
>> asynchronous operations becomes way too
>> costly to be useful for more and more
>> scenarios, and then it just won't be as useful.
>> Or maybe worse, each sub-component
>> start creating its own way of doing asynchronous,
>> because promises now are too expensive.
>>
>> We can optimize things other ways ofc, like
>> caching and etc. But I fear this becomes
>> another eo_do, where we want to be
>> faster than C++ and end up creating a
>> huge infrastructure to make it faster,
>> and end up being even slower.
>>
>> * not so normal, because we need to be able
>> to mark the type information statically when
>> used, as we do for containers, but that is only
>> on usage, so not a huge problem.
>>
>> So, tl;dr; I think we need to have fast
>> promises so we can use it in more places,
>> have a proper C API that is convenient
>> to use and remove any frivelous features
>> that aren't extremely necessary for
>> normal asynchronous operations. And
>> let bindings deal with asynchronous their
>> own way by being users to EFL Promises,
>> and not necessarily expose EFL Promises
>> directly.
>> ""
>>
>> On Fri, Jun 17, 2016 at 9:38 AM, Tom Hacohen <t...@osg.samsung.com> wrote:
>> > On 16/06/16 22:55, Cedric BAIL wrote:
>> >> Being against promise, is only advocating for no asynchrone behavior
>> >> in Efl. This is a position we can't take. So either you have a better
>> >> pattern to handle asynchronous behavior and synchronisation or we have
>> >> to provide promise. Objecting to promise is clearly not helping
>> >> anything here.
>> >
>> > This is FUD and raster called you out on it a few times already, please
>> > stop stating it as fact all over the place, because it's anything but.
>> > You can say "in my opinion it's better to use promises", but that's as
>> > far as I'll go.
>>
>> It is not FUD, making asynchronous operations ad-hoc with events
>> is not just a huge _pain in the ass_ to implement and use in C, but
>> also makes it impossible to translate that into anything that
>> would properly ressemble asynchronous operations in any
>> other language. Just simply ignoring the relationship that is
>> intrinsic on the asynchronous action and the events that
>> are bound to happen and in which order and how many times
>> they do makes it impossible to convey the information to bindings
>> as an asynchronous operation. All you can do is document things
>> and say, hey, you want to have an asynchronous operation?
>> Then first register events here, here and here first, then make
>> a seeming synchronous operation. This is awful for any language
>> and is even worse for Lua for the point I made about on top
>> and to which I'll get in deeper details below.
>>
>> Asynchronous operations _must_be_well_defined_to_be_useful
>> and be consistent. It _doesn't_ have to translate to the same
>> thing everywhere and should not translate to the same thing.
>>
>> We should not Eolize everything just to get automatic generation,
>> this is being super lazy. We need to offer good bindings and
>> that means translating concepts. What we really need is
>> a simple Promise/Future/Simple-Callback (the simple-callback
>> being the harder one to implement) so we can have actual
>> asynchronous operations and not just some events that
>> happen to return data as result from some operation that
>> looks synchronous.
>>
>> You could @tag the s*** out of operations so bindings can
>> understand things so it is translatable, however, doing so,
>> doesn't remove the ad-hoc-ness of using events(without
>> a well-defined Promise concept). Which means that
>> 1.  every class will do it differently; 2. Events are racy
>> by nature, overriding eo_event_callback_add to do
>> something completely different can solve the raceness,
>> but you can't just change documentation/expectations
>> from calling a function that behaves someway in
>> every other class. You're simply breaking the
>> function behavior for Promises and would be doing
>> even worse for several classes without a Promise
>> concept. So code that used to work one way for
>> _all_ Eo.Base classes, now only work for non-Promise
>> ones. Polymorphism is not about changing pre-conditions
>> and post-conditions of functions, but about extending
>> and interoperating with code.
>>
>> So, Promises have to exist some way or another for
>> us to have asynchronous operations, otherwise
>> it will be a huge mess, it actually already is. We had
>> _at_least_ two ways to do async, one by setting
>> a property (which actually suffers from the same
>> problem as your proposal of overriding
>> eo_event_callback_add) which makes another
>> function to behave bizarrely different and which
>> any user of such function must now track. This is
>> not dynamic polymorphism, this is not even a
>> quack-is-a-duck dynamic typing, this is asking a duck to
>> quack and a dinosaur eating your computer instead.
>> And another was efl.model which wasn't even
>> asynchronous at all, it just had a function that asked
>> the data to be cached, there was nothing really
>> asynchronous about it, you just _couldn't_ have
>> asynchronous calculations because all calculations
>> had to be ready for fetching synchronously, all
>> it had was two-phase construction, basically.
>>
>> On Fri, 3 Jun 2016 15:42:00 +0900 Carsten Haitzler (The Rasterman)
>> <ras...@rasterman.com> said:
>> >
>> > here's a rundown of efl promises vs other languages. basically our promises
>> > don't match any other languages. we can't just convert them to js promises
>> > or c+
>> > + promise+futures... and lua just has NOTHING there in the language. so 
>> > here
>> > is a table:
>> >
>> > FEATURE        | EFL | C++ | JS  | LUA |
>> > ---------------+-----+-----+-----+-----+
>> > create         |  X  |  X  |  X  |     |
>> > destroy        |  X  |  X  |  X  |     |
>> > then/else      |  X  |  X  |  X  |     |
>> > value          |  X  |  X  |  X  |     |
>> > cancel         |  X  |     |     |     |
>> > all            |  X  |     |  X  |     |
>> > race           |  X  |     |  X  |     |
>> > progress       |  X  |     |     |     |
>> > get status     |  X  |     |     |     |
>> > poll value     |  X  |     |     |     |
>> > wait           |     |  X  |     |     |
>> > wait+timeout   |     |  X  |     |     |
>> > ---------------+-----+-----+-----+-----+
>> >
>> > c++ futures/promises have features we don't. ti read up and they don't say
>> > wait/wait_for/until are optional and may not work. they seem to be
>> > requirements. so we can't map promises to c++ futures. it's not possible
>> > because we basically break how they work.
>> >
>> > we can't map them to js because js has no ability to cancel promises. also
>> > no progress too. so these features in core api's break then in js.
>> >
>> > it seems you can't ask if a promise or a future is done yet (without then
>> > blocking and waiting) in c++ or js, nor poll/get the value. (fyi in java 
>> > you
>> > can poll the state to see if a future is done yet... for example - java not
>> > included above).
>> >
>> > lua has NOTHING AT ALL to map to.
>>
>> I'm not developing the lua bindings so I can't say what is really going
>> to be mapped to. But I can say what I expect it to be by having used
>> Lua in a while and specially in a very asynchronous context (distributed
>> systems). Lua should map to co-routines! It will be the most beautiful
>> binding we will have!
>>
>> You just write normal code, it stops and is descheduled (the binding
>> will use the Promise for that) and it is rescheduled when
>> the callback on promise_then is executed.
>>
>> This is why I'm saying on the beggining of the email that we shouldn't
>> think of promises as our uber-asynchronous-communication-class that
>> will be exposed to everybody. We just need well-defined semantics
>> for asynchronous operations so we can translate it to every binding
>> in the most fucking nice way. People will likely _wow_ at our
>> co-routines in Lua! I'm sure I could at least make the lab that
>> created Lua in Brazil to wow at creating GUI interfaces with
>> co-routines.
>>
>> For C++ I'll just implement wait, no big deal. Can it deadlock? Yes,
>> but this is C++, you can deadlock a future anyway, you must know
>> what you're doing. It will only be really usable in a threading
>> context. The other parts is just new member functions or free
>> functions on the efl::eina::future<T>. We use templates in C++,
>> not OO to represent most polymorphisms, this is exactly what
>> we did for efl::eina::list, efl::eina::array, etc. This is
>> expected for C++.
>>
>> For JS, we will just implement a new class with the normal
>> Promise API with just a few more functions as well, people don't
>> care this is not a "standard" Promise as long as it is a
>> thenable. This works exactly like C++ but it is dynamic.
>>
>> So, no problem at all for bindings, as long as we have a proper
>> Promise concept.
>>
>> For all creation "problems" we just pass a efl::eina::promise<X>
>> to C++, in JS we pass two functions (probably three in our case):
>> a success, an error and a progress function that is called
>> by the code that wants to instantiate a promise. That's
>> the way to create promises in JS.
>>
>> For Lua, it could be integrated to yield.
>>
>> The All/Race composition in C++ can just be a free function
>> that gets multiple futures and return another future with
>> a tuple of all values, no big deal. It would work very nicely.
>>
>> For Lua, you probably won't use all very much because a
>> coroutine is a promise_all instrinsically. The race thing
>> would be a composition on co-routines.
>>
>> All problems can be solved if we define promises as a properly
>> defined concept that can be used by bindings and are not
>> intended to be used by binding users directly.
>>
>> > --
>> > Tom.
>>
>> Kind regards,
>> --
>> Felipe Magno de Almeida
>>
>> ------------------------------------------------------------------------------
>> What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
>> patterns at an interface-level. Reveals which users, apps, and protocols are
>> consuming the most bandwidth. Provides multi-vendor support for NetFlow,
>> J-Flow, sFlow and other flows. Make informed decisions using capacity 
>> planning
>> reports. http://sdm.link/zohomanageengine
>> _______________________________________________
>> enlightenment-devel mailing list
>> enlightenment-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
>>
>
>
> --
> ------------- Codito, ergo sum - "I code, therefore I am" --------------
> The Rasterman (Carsten Haitzler)    ras...@rasterman.com
>



-- 
Felipe Magno de Almeida

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports. http://sdm.link/zohomanageengine
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to