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