commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Todd Jonker <...@pobox.com>
Subject Re: [Jelly] Towards Functional programming in Jelly scripts
Date Sat, 14 Dec 2002 18:47:03 GMT
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:

  <frame var="result">...</frame>

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:

  <actionSet>
    <action name="New Browser" ... />
    <action name="Quit" ... />
  <actionSet>

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.


Mime
View raw message