Ok, you've confused me now. You seem to be saying that you don't need events, and you've offered as proof an implementation of a constraint system in Python, similar to OpenLaszlo's, where you have used setters to implement a simple event system on which to build your constraints.
I think you just have a definition of "constraint" that is different than the accepted definition (and what OpenLaszlo implements). In OpenLaszlo, you can constrain an attribute to the value of an expression that involves other object's attributes. The contract of this constraint is to ensure that the constrained attribute always has the value that would be computed by that expression. Nothing in the contract of constraints says that there are events sent. That is an implementation detail. We could implement constraints using a completely different mechanism (and have several experimental ones that could significantly improve the performance of applications with many constraints). On 2009-12-22, at 12:43, jamesr wrote: > aye, and it's better confusion because i have a portable working model > in LZX that never needs events. even if it is implemented "under the > hood", i still have yet to encounter a single piece of code that needed > it, conceptually. so i'm confused, as some are, as to why the > distinction. Yes, i understand that events don't send state like > attributes do, so when i need a "pure" event i just send true, or some > ignored value, and i teach that pattern. > > Just for illustrative reasons, you'll appreciate this, In python it is > done with "setters" as well, but there is no event class. > > here's the excerpt copy (2 relavent methods) of the constrain and > setattr methods on a <node> in pyroglyph, a python runtime,, evaluating > constraints, it shows the two functions on node.py that set up a > constraint, and fire that constraint when values change. as you might > interpret, there is no setAttribute call here. > > def constrain(self, attr=None, func=None, set=False): > """ make a constraint, that is, add to _handlers on a target node a > pointer > to a function to call when it value changes. Setting set to > true (the default) also sets that value on the node. This is because > before the init is completed, there may not be value to set! > """ > > #place a pointer to this new function as a listener on the node > pointed to by the handler > if not self._handlers.has_key(attr): > self.__dict__['_handlers'][attr] = [] > self.__dict__['_handlers'][attr].append(func) > > #if the constraint is made after initialization, set its value > immediately from the target > if set: func(self[attr]) > > and > > def __setattr__(self, attr, value): > """ and.. the very heart of delegates, events, constraints, etc! """ > > #set the value > self.__dict__[attr] = value > > #set the canvas as being dirty - that is, something changed and we > need to redraw! > #this is an optimaztion that may be removed with runtimes other then > openGL. > self.canvas.__dict__['dirty'] = True > > #distribute this value to all other listeners for this attribute > if self._handlers.has_key(attr): > [listener(value) for listener in self._handlers[attr]] > > P T Withington wrote: >> James, I think you are conflating setters and constraints. OpenLaszlo has >> setters which are always invoked by setAttribute; this is similar to the >> other languages you mention. >> >> OpenLaszlo also has the ability to constrain attribute values. There are >> very few other languages that have this feature. Constraints in OpenLaszlo >> are implemented by setters and events, which may be the source of the >> confusion. >> >> On Dec 21, 2009, at 21:43, jamesr <[email protected]> wrote: >> >>> unfortunately, this side effect of the constraint system, bypassing events >>> in normal use, is not a side effect but an intended main effect in other >>> runtimes and part of a broader lzx concept i play with, so i'm conceptually >>> bound to support only using attributes for handlers. It is nice to find out >>> they are in use, although i've spoken with many lzx coders that don't know >>> anything about events, only attributes. >>> >>> " >>> >>> The constraint system uses a necessary, but not sufficient, condition for >>> sending events -- >>> " >>> >>> I have solved that problem here via explicit replication for some cases; it >>> doesn't remove the need for laszlo replication but compliments it. so i >>> can't really complain. Of course, anything using laszlo replication may not >>> be portable to other runtimes as-a-pattern, because they may not support >>> the laszlo datapathing as laszlo does it. That's by way of explaining why i >>> care so much. >>> >>> A while ago when i first found out about this i was unsure what to do, but >>> it is conveniently patched, so life can go on! more soon... >>> >>> >>> P T Withington wrote: >>>> Attributes _do_ define state in LZX. LZX has always had >>>> attributes/constraints _and_ events/handlers. It has always been the case >>>> that you could constrain the value of one attribute to an expression that >>>> depended on the values of other attributes and the constraint system would >>>> ensure that the constrained value was maintained. It has always been the >>>> case that you could listen for and send events. It _so_happens_ that the >>>> constraint system is implemented using events to signal when a dependent >>>> of a constraint has changed. As a side-effect, you can attach a handler >>>> to the implicit event associated with an attribute, and you are guaranteed >>>> to get invoked any time the value of that attribute changes. You are >>>> _not_ guaranteed to get an event if the attribute is set to the same >>>> value. By the same token, you are not guaranteed to _not_ get an event if >>>> the constraint is recalculated and doesn't change. The constraint system >>>> uses a necessary, but not sufficient, conditio! n for sending events -- that is, it sends enough events to maintain the constraints, but it does not send the minimum possible set of events. For this reason, if you actually want an event to be sent, you should use explicit events, not rely on a side-effect of the constraint system. >>>> >>>> On 2009-12-21, at 12:30, jamesr wrote: >>>> >>>>> Ah it makes so much sense now. For those that are not up with the >>>>> attribute-event-handler debate, it is a semantic discussion about the >>>>> appropriate way to design flexible laszlo components. There are two >>>>> dominant patterns: >>>>> >>>>> One: Attributes define state, and things respond to that state >>>>> Two: Events define interest, and things respond to that interest by >>>>> retrieving and using attributes >>>>> >>>>> I'll refer to them as events and attributes below >>>>> >>>>> The two seem almost interchangable but there is a difference in program >>>>> design. The biggest difference is that the attributes model is simpler to >>>>> teach and predict. The idea that there is a second event system which >>>>> attribute access almost covers leads to confusion. Another is that the >>>>> attribute model is simpler to implement in other more powerful languages >>>>> (python) where setattr and getattr remove the need for the .setAttribute >>>>> syntax altogether; writing LZX to the Attributes spec represents a more >>>>> portable codebase. Events are something pulled more from other languages >>>>> and less from the lzx model to begin with, so i would argue. When first >>>>> learning laszlo I was safely able to forget about the event tag, and i've >>>>> been 100% okay without it (but for one pitfall i hacked around using >>>>> getTime() to change values every time, which i'm okay with, for now) >>>>> >>>>> The more-recently introduced condition the cautionary note PT wrote >>>>> speaks about is that there is a case when attributes will fail to send >>>>> events, requiring the use of the event tag, in one edge case. I don't >>>>> know if everyone is following, but this is something we can choose, and >>>>> it was done for a reason. I'm hoping for a flag in future version to >>>>> allow a pure attribute model, as i don't have the event tag in _any_ of >>>>> production code! And also, because that characteristic seems like it >>>>> would be in a pure LZX implementation (i.e. not javascript but something >>>>> more powerful, like python or ruby) >>>>> >>>>> So, i have a question for the list at large, not PT or Henry who do >>>>> enough :) For anyone reading this, when was the last time a listmember >>>>> reading this used <event> so as to work with handlers, anywhere, in any >>>>> code base? Has anyone considered this perhaps, or like me, never thought >>>>> of it until it wasn't there? >>>>> >>>>> Kind regards, >>>>> j. >>>>> >>>>> P T Withington wrote: >>>>> >>>>>> Just to be clear, the idea proposed in >>>>>> http://jira.openlaszlo.org/jira/browse/LPP-7816 >>>>>> >>>>>> is not yet implemented. Currently, you can only use <handler> to >>>>>> connect to an event that is already declared (either explicitly using >>>>>> <event> or implicitly on an attribute). >>>>>> >>>>>> And one caution: If you create a handler on the implicit event >>>>>> associated with a constrained attribute, the handler will _only_ be >>>>>> invoked when the attribute changes value. Consider this example: >>>>>> >>>>>> <canvas> >>>>>> <view layout="axis: y; spacing: 5"> >>>>>> <attribute name="set" value="false" /> >>>>>> <attribute name="followset" value="${this.set}" /> >>>>>> <handler name="onset" args="newvalue"> >>>>>> Debug.info("set: %w", newvalue); >>>>>> </handler> >>>>>> <handler name="onfollowset" args="newvalue"> >>>>>> Debug.info("followset: %w", newvalue); >>>>>> </handler> >>>>>> <button onclick="parent.setAttribute('set', true)">setAttribute('set', >>>>>> true)</button> >>>>>> <button onclick="parent.setAttribute('set', new >>>>>> Date())">setAttribute('set', new Date())</button> >>>>>> >>>>>> <event name="send"/> >>>>>> <handler name="send" args="eventvalue"> >>>>>> Debug.info("sent: %w", eventvalue); >>>>>> </handler> >>>>>> <button onclick="parent.send.sendEvent(true)">sendEvent(true)</button> >>>>>> <button onclick="parent.send.sendEvent(new Date())">sendEvent(new >>>>>> Date())</button> >>>>>> </view> >>>>>> </canvas> >>>>>> >>>>>> Notice that although the handler "onset" is invoked every time you set >>>>>> the attribute, whether the value changes or not, the hander >>>>>> "onfollowset" is _only_ invoked when the value it is constrained to >>>>>> changes. Personally, if I want to send events, I prefer to be explicit >>>>>> about it, as shown in the second half of the example, and declare the >>>>>> <event> and <hander> and use `sendEvent`, rather than relying on the >>>>>> implicit events sent when attributes change. >>>>>> >>>>>> On 2009-12-18, at 17:23, cem sonmez wrote: >>>>>> >>>>>> >>>>>>> @P T Withington : I looked at your your solution for creating delegates. >>>>>>> When i need to use the delegates, i m going to use the way that you >>>>>>> mentioned. While looking at the developer documentation of openlaszlo, I >>>>>>> hadnT understand the meaning of delegates and the usage of it. it >>>>>>> seemed to >>>>>>> me a bit confused :) Now, i think know more about delegates than before, >>>>>>> thanks >>>>>>> >>>>>>> @jamesr : also thank you for the information. I worked out the problem. >>>>>>> I >>>>>>> used an attrbiute in the connection.lzx >>>>>>> >>>>>>> <attribute name="connectionOK" value="false" type="boolean"/> >>>>>>> >>>>>>> and in the case of "NetConnection.Connect.Success", i set it to true. >>>>>>> Then while creating an object of sharedObject, i used like that : >>>>>>> >>>>>>> <sharedObjectChat id="soChat"> >>>>>>> <handler name="onconnectionOK" reference="conn"> >>>>>>> Debug.info("connectionOK attribute operation, value >>>>>>> :%w",conn.connectionOK); >>>>>>> if (conn.connectionOK==true) { >>>>>>> //this.setAttribute("createSharedObject",true); >>>>>>> this.connect("chat", conn._conn, true); >>>>>>> this.so.client=this; >>>>>>> } >>>>>>> </handler> >>>>>>> </sharedObjectChat> >>>>>>> >>>>>>> So itS ok now. İt is impossible to learn something wihout making >>>>>>> mistakes :) >>>>>>> >>>>>>> Best regards. >>>>>>> >>>>>>> 2009/12/18 P T Withington <[email protected]> >>>>>>> >>>>>>> >>>>>>>> I have a proposed "solution" for the LZX programmer having to create >>>>>>>> delegates in script in: >>>>>>>> >>>>>>>> http://jira.openlaszlo.org/jira/browse/LPP-7816 >>>>>>>> >>>>>>>> Basically, I want you to be able to declare a handler without >>>>>>>> attaching it >>>>>>>> to an event at declaration time (and you would later use script to >>>>>>>> register >>>>>>>> the handler on the event it is to handle). The main purpose for this >>>>>>>> change >>>>>>>> is that <handler /> will automatically be managed, whereas delegates >>>>>>>> must be >>>>>>>> manually managed (and destroyed) or they can lead to memory leaks. >>>>>>>> >>>>>>>> On 2009-12-18, at 16:03, jamesr wrote: >>>>>>>> >>>>>>>> >>>>>>>>> for the record, the two use cases for making a delegate are >>>>>>>>> >>>>>>>>> 1) you want to compute what object to latch onto programmatically and >>>>>>>>> 2) you want to latch onto something that is not yet created at the >>>>>>>>> >>>>>>>> handler init phase. >>>>>>>> >>>>>>>>> don't see any other use, although the two above are obviously >>>>>>>>> important >>>>>>>>> >>>>>>>>> cem sonmez wrote: >>>>>>>>> >>>>>>>>>> you are exactly right. I want to make some operations when the >>>>>>>>>> >>>>>>>> netconnection successful event is fired. Actually i m trying to get the >>>>>>>> shared object on the server side, so at first i need a netconnection >>>>>>>> instance to do that. ThatS why i thought that i should try delegates. I >>>>>>>> havenT used delegates before, but i thought that this is the just one >>>>>>>> solution to handle the operations depend on the related event. >>>>>>>> >>>>>>>>>> The method you said, using an attribute in the connection class seems >>>>>>>>>> >>>>>>>> the better way. Till now, i havenT needed the delegates. I hope using >>>>>>>> connection status attribute in the connection class will fix the >>>>>>>> problem. >>>>>>>> >>>>>>>>>> I m going to post back the results here of course. >>>>>>>>>> Thanks for the reply J >>>>>>>>>> >>>>>>>>>> 2009/12/18 jamesr <[email protected] >>>>>>>>>> <mailto:[email protected] >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> I can tackle it. let's see; i'd write the following, after an >>>>>>>>>> introduction (all code is untested and represents a pattern, adapt >>>>>>>>>> it as you will) >>>>>>>>>> >>>>>>>>>> Your problem: You want to do is send a "connection successful" >>>>>>>>>> event that you can catch, signaling that a method is to be called >>>>>>>>>> to continue using the connection. You seem to be trying to do it >>>>>>>>>> by setting up the delegate manually, when i think, looking at your >>>>>>>>>> code, that you have hooks to fire events on laszlo nodes that can >>>>>>>>>> communicate this state change. >>>>>>>>>> >>>>>>>>>> Solution: An event is anytime you use x.setAttribute() by the way >>>>>>>>>> - that's what it does, makes sure that handlers are fired. That >>>>>>>>>> said, if you declare an attribute of any laszlo node and in your >>>>>>>>>> code, when you have success on your net connection, you say >>>>>>>>>> "somenode.setAttribute('success, true);" then in another node you >>>>>>>>>> can say, <handler name="onfoo" reference="somenode">...</handler> >>>>>>>>>> and in that code you can then do what ever other steps are >>>>>>>>>> required to use the connection. >>>>>>>>>> >>>>>>>>>> Further thought if i'm wrong: can you say why it is you decided to >>>>>>>>>> use manual delegates? it might make things clearer for me, i've >>>>>>>>>> not used the net connection code you have there but make guesses. >>>>>>>>>> >>>>>>>>>> .j. >>>>>>>>>> cem sonmez wrote: >>>>>>>>>> >>>>>>>>>> doesnT anyone have any idea. I got stuck here. Waiting for >>>>>>>>>> someones advices. >>>>>>>>>> Thanks >>>>>>>>>> >>>>>>>>>> 2009/12/18 cem sonmez <[email protected] >>>>>>>>>> <mailto:[email protected]> <mailto:[email protected] >>>>>>>>>> <mailto:[email protected]>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> hi >>>>>>>>>> when i try do use the delegate such like : >>>>>>>>>> >>>>>>>>>> if( typeof this.del == "undefined" ) { >>>>>>>>>> this.del = new LzDelegate(this, "connect('chat', >>>>>>>>>> >>>>>>>> conn, >>>>>>>> >>>>>>>>>> true)" ); >>>>>>>>>> } this.del.register(conn, >>>>>>>>>> "netStatusHandler('NetConnection.Connect.Success')" ); >>>>>>>>>> } >>>>>>>>>> >>>>>>>>>> I m getting the error on the debug like : >>>>>>>>>> >>>>>>>>>> *soChat.connect('chat', conn, true) => (void 0) (must be a >>>>>>>>>> function)* >>>>>>>>>> >>>>>>>>>> Actually i want to do this : call the *connect* method on the >>>>>>>>>> class when the netStatusHandler method of the *conn* object >>>>>>>>>> >>>>>>>> has >>>>>>>> >>>>>>>>>> been completed. I m not sure that am i using the delegate >>>>>>>>>> correctly (as i m getting the error, of course not :)). >>>>>>>>>> >>>>>>>>>> I have attached the relevant files. >>>>>>>>>> Can anyone help me what i m missing to do. >>>>>>>>>> >>>>>>>>>> Kind regards. >>>>>>>>>> >>>>>>>>>> -- Cem SONMEZ >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- Cem SONMEZ >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Cem SONMEZ >>>>>>>>>> >>>>>>>> >>>>>>> -- >>>>>>> Cem SONMEZ >>>>>>> >>>>>> >>>> >>>> >>>
