Return-Path: Mailing-List: contact commons-user-help@jakarta.apache.org; run by ezmlm Delivered-To: mailing list commons-user@jakarta.apache.org Received: (qmail 21005 invoked by uid 98); 14 Dec 2002 18:48:07 -0000 X-Antivirus: nagoya (v4218 created Aug 14 2002) Received: (qmail 20986 invoked from network); 14 Dec 2002 18:48:05 -0000 Received: from daedalus.apache.org (HELO apache.org) (63.251.56.142) by nagoya.betaversion.org with SMTP; 14 Dec 2002 18:48:05 -0000 Received: (qmail 53714 invoked by uid 500); 14 Dec 2002 18:46:53 -0000 Received: (qmail 53703 invoked from network); 14 Dec 2002 18:46:53 -0000 Received: from mail16.speakeasy.net (HELO mail.speakeasy.net) (216.254.0.216) by daedalus.apache.org with SMTP; 14 Dec 2002 18:46:53 -0000 Received: (qmail 29737 invoked from network); 14 Dec 2002 18:47:02 -0000 Received: from unknown (HELO [10.0.1.61]) (toddster@[66.93.60.224]) (envelope-sender ) by mail16.speakeasy.net (qmail-ldap-1.03) with SMTP for ; 14 Dec 2002 18:47:02 -0000 User-Agent: Microsoft-Entourage/10.1.1.2418 Date: Sat, 14 Dec 2002 13:47:03 -0500 Subject: Re: [Jelly] Towards Functional programming in Jelly scripts From: Todd Jonker To: Jakarta Commons Users List Message-ID: In-Reply-To: <045501c2a2bc$6ac56d30$9865fea9@spiritsoft.com> Mime-version: 1.0 Content-type: text/plain; charset="US-ASCII" Content-transfer-encoding: 7bit X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N Thanks for the feedback, Rodney and James. Rodney, your workaround code is quite similar to what I'm having to do, dut it's rather more complex than it would need to be if tags and scripts had return values. Regarding your suggested patch to TagSupport, yes that's a way to avoid changing subclasses. However, I don't feel it's the best long-term solution since it adds another facet of complexity and indirection. It's already difficult enough to trace the code through non-trivial tag libraries like JellySwing. James, your expression language would be a valuable addition, too. I believe others on the list have talked about making pluggable expression languages, and I agreed that it would be extremely useful. However, it doesn't solve my particular problem, so I hope you'll let me explain in more detail. At the moment, I find it very difficult to get values back from Jelly scripts after they have run. Jelly scripts and tags act in many ways like functions, but they cannot have return values, so they can only perform side-effects like JellyContext.setVariable(). I feel that this is a recipe for complex and fragile programs. I was drawn to Jelly specifically because of JellySwing, since it does 75% of what I need for my UI framework's configuration system. I need to write XML files that put together panels and frames, refactor and compose them, and access external components. However, each script must also return the window or panel to the framework so the WindowManager can latch onto it. The only way to do this currently is to write my Jelly scripts like: ... Where "result" is an externally-specified magic variable. I'm effectively shoving the value in a global because a Jelly script can't return a value like a "real" function. What I dislike about the FunctionalTagParent pattern is that it will be very hard to evolve and extend, because the child tags are tightly-coupled to specific types of parents. The functional approach lets each tag build up and directly return it's value, and the parent can be any class. As with a method call, it's up to the parent to determine what to do with the result. The child tags can be completely decoupled from their context, and therefore are much easier to reuse. To give a concrete example, consider JellySwing's frame/action nesting. Currently, an ActionTag code must be used inside a ComponentTag (without falling back to the var="result" workaround). I would like to be able to define sets of actions that are not bound to a particular component, so they can be used several places: As far as I can see, there's no clean way to do this in Jelly, without making ActionSetTag extend ComponentTag. Under a functional model, the sequence of child tags would evaluate to a sequence of values. ActionTag can be completely decoupled from any particular context. I'm envision something like: class ActionSetTag { public Object doTag(XMLOutput output) { List bodyResults = invokeBody(output); myActions.addAll(bodyResults); } private Set myActions; } (Note that type-safety can be ensured via an appropriate DTD, a very nice benefit.) For a parent tag like FrameTag, after calling invokeBody it can simply iterate through the results and handle each one appropriately to it's type. Of course, it would be nice to get the results as they occur, to allow short-circuiting, but that can also be added to the current framework quite easily. In short, adding return-values to Script and Tag provides the same benefits as having return values in normal functions and methods. As such, I believe it would open up Jelly to a much broader variety of XML tasks, while providing opportunities to reduce the coupling and complexity of Tag classes. Sincerely, .T.