You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Emmanuel Bourg <sm...@lfjr.net> on 2004/12/02 18:16:38 UTC

[collections] InvokerClosure

Hi all, I decided to play a bit with closures today and tried replacing 
a trivial loop in [configuration] :

for (Iterator i = configList.iterator(); i.hasNext();)
{
     Configuration config = (Configuration) i.next();
     config.clearProperty(key);
}

I thought a closure would help reducing the code, but actually I ended 
with something much longer :

CollectionUtils.forAllDo(configList, new TransformerClosure(new 
InvokerTransformer("clearProperty", new Class[] { String.class }, new 
Object[] { key })));

Then I found the invokerClosure method in ClosureUtils, the code turned 
into :

CollectionUtils.forAllDo(configList, 
ClosureUtils.invokerClosure("clearProperty", new Class[] { String.class 
}, new Object[] { key }));

Slightly better but still quite long. Why is there no InvokerClosure 
class ? This is the only closure in ClosureUtils that has no 
corresponding class, this could make the code a bit shorter:

CollectionUtils.forAllDo(configList, new InvokerClosure("clearProperty", 
new Class[] { String.class }, new Object[] { key }));

Also the Class[] and Object[] are quite cumbersome, that would be nice 
to add methods/constructors to invoke simple methods with only one or 
two parameters. Thus my example could look like this:

CollectionUtils.forAllDo(configList, new InvokerClosure("clearProperty", 
String.class, key));

which is much more readable.

What do you think ?

Emmanuel Bourg

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [collections] InvokerClosure

Posted by Chris Lambrou <ma...@chrislambrou.com>.
Emmanuel Bourg wrote:

> Also the Class[] and Object[] are quite cumbersome, that would be nice 
> to add methods/constructors to invoke simple methods with only one or 
> two parameters. Thus my example could look like this:
>
> CollectionUtils.forAllDo(configList, new 
> InvokerClosure("clearProperty", String.class, key));
>
> which is much more readable.
>
> What do you think ?


I think that we could go further.  How about being able to write the 
following?

new InvokerClosure("clearProperty", key);

Since we've already sacrificed type-safety and runtime performance by 
using reflection, why not go a little further with this and use some 
algorithm to infer the most appropriate method to invoke at runtime. If 
there's ambiguity over which method to invoke at runtime, just have the 
InvokerClosure throw a FunctorException.

Chris

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [collections] InvokerClosure

Posted by Chris Lambrou <ma...@chrislambrou.com>.
Actually, I misunderstood your original suggestion a little. It's quite 
late here in England!


Emmanuel Bourg wrote:

> What prevents the debugging of a library 1.3 compatible with a 1.5 
> source ? The line numbers don't match ?
>
Yeah, pretty much. But there are a number of other little things that 
either wouldn't work, or would work badly.  Consider an IDE that doesn't 
yet support Java 1.5 syntax (pretty common, at the moment). At best, the 
syntax highlighting would look awkward in places.  But an IDE's code 
parser could fail to the extent that code navigation would be impaired. 
i.e. the ability to browse to a item's declaration or usage would no 
longer function.  I admit it's not the end of the world. Actually, if 
implemented nicely, the tool could simply expand the 1.5 syntax clauses 
into 1.4 valid code, in which case the problems I've described would 
largely go away.  It could well be a useful tool.

In essence, we define a subset of the 1.5 language features to be 
supported, and provide a source code preprocessor that can convert this 
1.5 source back to valid 1.4 source, then compile as normal.  It could 
prove useful, but to be worthwhile it would have to tackle more than 
just the new for loop constructs. Okay, we might not go as far as 
supporting generics, but how about auto-boxing/unboxing and vararg 
method declarations?  It sounds like a potentially useful side project, 
run at SourceForge perhaps? My guess is that there are people out there 
working on this sort of thing already, so perhaps some hunting around is 
in order.

Chris



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [collections] InvokerClosure

Posted by Emmanuel Bourg <sm...@lfjr.net>.
Chris Lambrou wrote:

> On the other hand, if you're simply talking about borrowing some of the 
> 1.5 syntax, particularly the new for loop constructs, and somehow using 
> it in collections, are you really proposing the use of a source 
> preprocessing stage as part of the collections build process, simply to 
> allow this syntactic nicety?  If so, I don't think that its a goer - it 
> might break the development process of too many users of collections, 
> particularly with regard to IDE integration.  For example, anyone who's 
> defined a collections library in IDEA, that refers to both the 
> collections .zip source file and the binary jar file, would find that 
> their ability to step into the collections source during debugging will 
> have been screwed up.

I just digressed with a general suggestion, this was not specificaly 
targeted to [collections]. The idea is to use only the basic 1.5 syntax 
(foreach, autoboxing, varargs), not the new features such as 
annotations, enumerations, etc.

What prevents the debugging of a library 1.3 compatible with a 1.5 
source ? The line numbers don't match ?

Emmanuel Bourg


Re: [collections] InvokerClosure

Posted by Chris Lambrou <ma...@chrislambrou.com>.
Emmanuel Bourg wrote:

> for (Configuration config : configList)
> {
>     config.clearProperty();
> }
>
> That makes me think, couldn't we use the Java 1.5 syntax while 
> producing Java 1.3 compatible byte code ?
>
> Emmanuel Bourg
>

We've discussed a 1.5 version of collections some time ago.  The upshot 
was that we wouldn't be able to maintain backwards compatibility, 
primarily to the new language features.  Sadly, both 1.5 source and 1.5 
bytecode is not backwards compatible wit earlier java versions, so 
there's an ongoing effort to reimplement Collections in 1.5 (sadly, what 
with the job being awfully busy, my needing to get my bathroom refitted 
before Christmas and my recent computer upgrade failing miserably, I 
haven't progressed much over the last month or so - you can have a look 
at what there is at http://collections15.sourceforge.net).  There have 
been a number of discussions on the Sun forums about producing source 
processing tools that can convert 1.5 source to 1.4 source, but there 
are too many annoying incompatibilities for a general solution to work 
cleanly.

On the other hand, if you're simply talking about borrowing some of the 
1.5 syntax, particularly the new for loop constructs, and somehow using 
it in collections, are you really proposing the use of a source 
preprocessing stage as part of the collections build process, simply to 
allow this syntactic nicety?  If so, I don't think that its a goer - it 
might break the development process of too many users of collections, 
particularly with regard to IDE integration.  For example, anyone who's 
defined a collections library in IDEA, that refers to both the 
collections .zip source file and the binary jar file, would find that 
their ability to step into the collections source during debugging will 
have been screwed up.

If we really want such syntactic niceties, I reckon we just have to move 
wholesale to Java 1.5, and accept the break in backwards compatibility.

Chris Lambrou


P.S.  While I'm thinking about it, have there been any steps towards 
migrating commons-lang to Java 1.5?  Anyone?

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [collections] InvokerClosure

Posted by Emmanuel Bourg <sm...@lfjr.net>.
Eric Pugh wrote:

> Things like this are cool..  But..  within the context of java, they just
> seem more difficult to read..  Requiring the user to know what an
> InvokerClosure is and does.  It's neat..  I just haven't seen the use case
> that requires it...

Well the code is still readable imho, it reads almost naturally "for all 
elements in the collection invoke the clearProperty method". I 
personnally like the "do the same thing in one line" aspect, but I admit 
the syntax is surprising, that's what makes it cool I guess ;)

An alternative for reducing the code is the new foreach syntax, for this 
specific example it's certainly more readable than a closure :

for (Configuration config : configList)
{
     config.clearProperty();
}

That makes me think, couldn't we use the Java 1.5 syntax while producing 
Java 1.3 compatible byte code ?

Emmanuel Bourg


RE: [collections] InvokerClosure

Posted by Eric Pugh <ep...@upstate.com>.
Is the final result:

 CollectionUtils.forAllDo(configList, new InvokerClosure("clearProperty",
 String.class, key));

Compared to the original really that much cleaner?:
 for (Iterator i = configList.iterator(); i.hasNext();)
 {
      Configuration config = (Configuration) i.next();
      config.clearProperty(key);
 }

Things like this are cool..  But..  within the context of java, they just
seem more difficult to read..  Requiring the user to know what an
InvokerClosure is and does.  It's neat..  I just haven't seen the use case
that requires it...


Eric

> -----Original Message-----
> From: Emmanuel Bourg [mailto:smanux@lfjr.net]
> Sent: Thursday, December 02, 2004 6:17 PM
> To: Jakarta Commons Developers List
> Subject: [collections] InvokerClosure
>
>
> Hi all, I decided to play a bit with closures today and tried replacing
> a trivial loop in [configuration] :
>
> for (Iterator i = configList.iterator(); i.hasNext();)
> {
>      Configuration config = (Configuration) i.next();
>      config.clearProperty(key);
> }
>
> I thought a closure would help reducing the code, but actually I ended
> with something much longer :
>
> CollectionUtils.forAllDo(configList, new TransformerClosure(new
> InvokerTransformer("clearProperty", new Class[] { String.class }, new
> Object[] { key })));
>
> Then I found the invokerClosure method in ClosureUtils, the code turned
> into :
>
> CollectionUtils.forAllDo(configList,
> ClosureUtils.invokerClosure("clearProperty", new Class[] { String.class
> }, new Object[] { key }));
>
> Slightly better but still quite long. Why is there no InvokerClosure
> class ? This is the only closure in ClosureUtils that has no
> corresponding class, this could make the code a bit shorter:
>
> CollectionUtils.forAllDo(configList, new InvokerClosure("clearProperty",
> new Class[] { String.class }, new Object[] { key }));
>
> Also the Class[] and Object[] are quite cumbersome, that would be nice
> to add methods/constructors to invoke simple methods with only one or
> two parameters. Thus my example could look like this:
>
> CollectionUtils.forAllDo(configList, new InvokerClosure("clearProperty",
> String.class, key));
>
> which is much more readable.
>
> What do you think ?
>
> Emmanuel Bourg
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org