Skip to main content

Applying Generics and Functors for Object Realization

15 replies [Last post]
rameshgupta
Offline
Joined: 2004-06-04

I just looked at David Hall's abstract for JavaOne session on "Applying Generics and Functors to Desktop JavaTM Programming" (TS-3802) at http://www.javaone04.com/catalog/catalog/sessionDetail.jsp?hd=true&SESSI..., and found the following:

"In desktop programming, there are often large numbers of small, frequently anonymous classes that implement trivially simple interfaces. By replacing these classes with functor-based aggregates, hundreds of classes can be eliminated from the runtime."

This pretty much describes the situation with Assimilator and Applier interfaces in OpenMarkup, and how the JDNC tag library implements these interfaces with hundreds of anonymous classes.

At this point I haven't seen David's code, the JavaDocs, or the J1 session slides. So, I don't know if or how his approach will improve things, but the possibility is very intriguing.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
rameshgupta
Offline
Joined: 2004-06-04

>> I understand that JDNC filters currently do not use functors,
>> and could benefit from them. But have you looked at JDNC's
>> element assimilators and attribute appliers? Aren't they
>> already function objects? Or, am I missing something?
>
> I don't think you're missing anything ... I think both qualify ... [but]
>
> When I look at the two classes you mentioned, the
> first thing that jumps out at me is that they are fairly tightly
> coupled to be working in particular roles within JDNC.
> For example, the apply method of AttributeApplier
> takes four arguments, which suggests to me that
> they're tightly bound to a particular role within the
> markup parser(?).

AttributeAppliers process information in attributes, whereas ElementAssimilators process information in elements, including the parent/child relationship between elements.

They have particular roles within the object realizer, and they get invoked at different times during the object realization process, but they perform the same fundamental task, which is, to sculpt a Realizable object using element or attribute information from an XML document.

> A number of them seem to be a single line of code [effectively].
> In a number of cases, though, the implementation is
> quite a bit more complicated.
>

A very interesting property of applier and assimilator implementations is that they give an excellent indication of the tools-friendliness of the underlying Java apis for the objects being realized.

While complex appliers and assimilators are not necessarily symptomatic of poorly designed Java apis for the realized objects, the converse is probably true. Generally speaking, the simpler the appliers and assimilators are, the more strongly they indicate that the underlying Java api is amenable to tooling. As such, one of our goals is to turn as many appliers and assimilators into single-line implementations as possible, and justify the ones that can't be.

> [snip] One of the premises of my session at JavaOne was that
> pretty much any single line of exectuable java code could be
> translated into a functor (with some reasonable cavaets).
> It's the set of combining functors ... that
> allows the primitives to be assembled in such a way as to take
> the place of single lines of code.** To the extent that what you
> have classes whose implementation can be boiled down to a single line,
> then we're at least in the right ballpark.
>
> One of the things that I brought up in my speech is that the
> Comparator class... is also a functor. ... If you accept the idea of
> using functors in a design, then Comparator illustrates an interesting
> design point: When do you create a specific interface and
> when to you use a general functor?
> For Comparator, there're good reasons to make it an interface:
>
> 1) the semantics associated with the result need to
> to be described somewhere, and describing them once in the
> Comparator class makes more sense than describing them at all the
> the places where they're used
>
> 2) it is potentially so widely used that giving it
> it a name allows much easier description of the algorithms in
> ms in which it is used
>
> 3) the name is simple and descriptive enough that
> at its intent is fairly clear
>
> On the other hand, even though Comparator stands on
> its own as a design idea worthy of naming, I know that I could
> implement 75-90% of all the Comparator implementations I've ever seen
> with a few simple primitives, and eliminate the implementation class
> with an aggregate of objects of pre-existing classes.

Very well explained ;-)

>
> In the case of AttributeAppliers, you've got a basic
> interface that takes fairly specific arguments with fairly specific
> meanings. That would tend to suggest that the base interface has
> enough semantic weight to stand on its own.

Yes, for reasons (1) and (3) you mentioned above.

> You might be able to
> create one implementation that uses a functor for implementation
> and use that to replace a number of the existing classes, but you'll
> probably still find yourself with a number of implementations that
> are more complicated than what a single functor is good for.
> You'd be able to reduce your classcount somewhat, and you'd have a
> place in the design to attach a lot of functionality that you haven't
> thought of yet, but it's not going to simplify things greatly.

JDNC does not use this technique yet, but the eNode ObjectRealizer has a bunch of dynamic invokers (dynamic attribute appliers and element assimilators) that can be reused in a number of places. They dramatically reduce the number of anonymous classes that are used to implement the named interfaces. The eNode implementation also uses chained appliers and assimilators to assemble more complex logic from basic building blocks. While not using generic functors, this does realize 80% of the vision -- There is always room for improvement ;-)

>
> The ElementAssimilators look much simpler (at least
> the few that I've glanced at). It's more likely that there are a lot
> more of them that boil down to a single line implementation,
> particularly since many of them seem to be descriptions of the
> relationship between some graphical parent object and
> an associated child element.
>

FWIW, the objects are mostly graphical components because, in the case of JDNC, the domain is specifically rich visualization clients. When processing a markup language from another domain, the element assimilators would still exhibit similar properties, but the objects themselves would not necessarily be graphical.

Ramesh

dhall
Offline
Joined: 2006-02-17

Ramesh:

In case you're still interested in pursuing this, I thought I'd let you know that I got the latest release out last night (I finally got back online this week: hopefully its after the hurricane and not between the hurricanes).

http://www.javadesktop.org/forums/thread.jspa?threadID=4991&tstart=0

I'm going to try and get a few examples put together in the next couple of weeks of some of the simpler areas where functors may be useful. I'll be looking at JDNC in a lot more depth as a break from jga for a short while before I get back to making the spreadsheet engine allow users to enter formulas.

Dave

rameshgupta
Offline
Joined: 2004-06-04

> Ramesh:
>
> In case you're still interested in pursuing this, I
> thought I'd let you know that I got the latest
> release out last night (I finally got back online
> this week: hopefully its after the hurricane and not
> between the hurricanes).
>
> http://www.javadesktop.org/forums/thread.jspa?threadID
> =4991&tstart=0

Of course, I am interested in this! I am currently defining the detailed JDNC Roadmap for the next year, and functors are prominantly featured in it.

>
> I'm going to try and get a few examples put together
> in the next couple of weeks of some of the simpler
> areas where functors may be useful. I'll be looking
> at JDNC in a lot more depth as a break from jga for a
> short while before I get back to making the
> spreadsheet engine allow users to enter formulas.
>
> Dave

This is another interesting topic that the JDNC team has been discussing.

Ramesh

Patrick Wright

>> areas where functors may be useful. I'll be looking
>> at JDNC in a lot more depth as a break from jga for a
>> short while before I get back to making the
>> spreadsheet engine allow users to enter formulas.
>>
> This is another interesting topic that the JDNC team has been discussing.

FYI--there are a number of OSS/FS spreadsheet packages for Java based on
Swing that might provide ideas or might save time if the authors can
contribute

Just a quick search on Google and Sourceforge brings:
http://www.eteks.com/jeks/en/ (GPL)
http://sourceforge.net/projects/jeppers/ (LGPL)
http://sourceforge.net/projects/sharptools/ (GPL)
http://sourceforge.net/projects/javaspreadsheet/

There are probably more

Patrick

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

dhall
Offline
Joined: 2006-02-17

Patrick:

Those links you provided are an interesting mix of approaches, from what
I can see by the web-sites. I had seen a couple of those before, but a
couple were new to me.

In my case, writing a spreadsheet isn't my primary goal, but a reasonably
functional spreadsheet is a short step from one of my intermediate goals.
I'm working toward that as much as an example of the premise behind jga
and as a logical place to wrap up a round of development for the purposes
of an interim release. I really don't expect to try and be excel feature
complete, or even excel feature compatable. That said, I would be
interested in assisting if anyone wants to build an excel-ish tool on top
of the jga spreadsheet capability.

Dave

zander
Offline
Joined: 2003-06-13

> Perhaps the most convincing reason for the JCA is to force contributors to acknowledge that they have the
> authority to contribute whatever it is they are contributing.

Ehm; as soon as I sent a file to you with my copyright notice in the header I already did acknowledge exactly that. Since even email is 'writing' legally there is legally no need to share copyright.

I can't help but wonder if Sun just wants to avoid requests from the people that actually did the hard work to be able to have a say in how Sun uses their work.

rameshgupta
Offline
Joined: 2004-06-04

> This sorta brings up the discussion issues that I
> mentioned in the 'Is anyone else bothered by the
> JCA?' thread.

Personally, I too am bothered by the JCA, and I have raised issues surrounding this within Sun. But, I can't help agree with many of the points made in the Wired article, a link to which was posted by Mark Davidson in a separate thread: http://www.wired.com/wired/archive/12.07/linux.html?pg=6

Perhaps the most convincing reason for the JCA is to force contributors to acknowledge that they have the authority to contribute whatever it is they are contributing, and to hold the accepting party harmless from claims by a third party.

> I think that what I spoke on could
> have benefit to JDNC and if Sun decides that it would
> like to incorporate my ideas, I'll be willing to
> hammer out a copyright assignment that meets
> everyone's needs.

Great! Are there other areas besides Appliers and Assimilators where we could leverage your work? The idea of Swing models that take advantage of predicates and functors sounds tantalizing!

Ramesh

dhall
Offline
Joined: 2006-02-17

>> Are there other areas besides Appliers and Assimilators where we could leverage your work?

Well, as long as you're asking ;) Filters, Validators, and Computed Values.

Filters should be any expression that yields a boolean value. For example, one of the functors that I've implemented is CompareProperty, which gets the value of a named property of its argument, and compares it to a constant value.

Validators could work much the same way: they could be implemented as an arbitrary boolean expression. I know there's an issue in how you can then describe the validation to provide UI feedback, but this is certainly a solvable problem.

I have computed values working already -- one of the changes that I want to make to the examples is to include a computed column in the GenericTableModel example. After I heard Amy say in her session that y'all were looking at adding it to the table, I almost added it to one of my slides.

Additionally, I've got a Spreadsheet control that is semi-functional in that it supports arbitrary computations with inter-cell references (you have to pull down the head revision to get that -- the last release had a placeholder for this). The semi-functional Spreadsheet control will be included in the next release [[now that I have a couple of pointers to it, I really want to try and get the release out quickly]]

rameshgupta
Offline
Joined: 2004-06-04

> >> Are there other areas besides Appliers and
> Assimilators where we could leverage your work?
>
> Well, as long as you're asking ;) Filters,
> Validators, and Computed Values.
>
> Filters should be any expression that yields a
> boolean value. For example, one of the functors that
> I've implemented is CompareProperty, which gets the
> value of a named property of its argument, and
> compares it to a constant value.

This makes total sense. Currently, filtering is implemented by the test() method in the Filter class. This means that you need to subclass Filter to provide your own filtering behavior. Brian Beck (JDNC team member) did just that for the JavaOne Keynote Demo. If we had the ability to pass a boolean expression instead, subclassing could be avoided.

>
> Validators could work much the same way: they could
> be implemented as an arbitrary boolean expression. I
> know there's an issue in how you can then describe
> the validation to provide UI feedback, but this is
> certainly a solvable problem.
>
> I have computed values working already -- one of the
> changes that I want to make to the examples is to
> include a computed column in the GenericTableModel
> example. After I heard Amy say in her session that
> y'all were looking at adding it to the table, I
> almost added it to one of my slides.
>
> Additionally, I've got a Spreadsheet control that is
> semi-functional in that it supports arbitrary
> computations with inter-cell references (you have to
> pull down the head revision to get that -- the last
> release had a placeholder for this). The
> semi-functional Spreadsheet control will be included
> in the next release [[now that I have a couple of
> pointers to it, I really want to try and get the
> release out quickly]]

Very cool ;-)

Ramesh

rameshgupta
Offline
Joined: 2004-06-04

David,

I understand that JDNC filters currently do not use functors, and could benefit from them. But have you looked at JDNC's element assimilators and attribute appliers? Aren't they already function objects? Or, am I missing something?

Ramesh

dhall
Offline
Joined: 2006-02-17

First of all, I've only now pulled down the JDNC source, so I'm not as
familiar with it as I hope to be. All that follows is really based on
cursory glances at the classes that you're referring to.

>> I understand that JDNC filters currently do not use functors, and
>> could benefit from them. But have you looked at JDNC's element
>> assimilators and attribute appliers? Aren't they already function
>> objects? Or, am I missing something?

I don't think you're missing anything. I think of the definition of a
functor as an Object that encapsulates a single function, and in a
language like Java where everything is an Object, that can cover a lot
of ground. I think both qualify in a broad sense, in that they are
each single-method interfaces, and that you're storing and passing
implementations around somewhat interchangably. That's pretty much
the spirit of what functors are.

When I look at the two classes you mentioned, the first thing that
jumps out at me is that they are fairly tightly coupled to be working
in particular roles within JDNC. For example, the apply method of
AttributeApplier takes four arguments, which suggests to me that
they're tightly bound to a particular role within the markup
parser(?). A number of them seem to be a single effective line of
code (many times the single line is broken up for readability into a
few lines, where subexpressions are broken out into local variable
declarations). In a number of cases, though, the implementation is
quite a bit more complicated.

The functors I spoke about were much more primitive, but much more
universally useful. Many cover a single operation (logical,
arithmetic, comparison, etc), and there's a set of functors that do
nothing but combine other functors into compound structures. One of
the premises of my session at JavaOne was that pretty much any single
line of exectuable java code could be translated into a functor (with
some reasonable cavaets). Its the set of combining functors (in jga,
they're in the net.sf.jga.fn.adaptor package) that allows the
primitives to be assembled in such a way as to take the place of
single lines of code.** To the extent that what you have classes whose
implementation can be boiled down to a single line, then we're at
least in the right ballpark.

One of the things that I brought up in my speech is that the
Comparator class, with which most of us are fairly familiar, is also a
functor. If you look at STL, there isn't a named object that does
what the Comparator does, but its interface is mentioned in a number
of algorithms. If you accept the idea of using functors in a design,
then Comparator illustrates an interesting design point: when do you
create a specific interface and when to you use a general functor?
For Comparator, there're good reasons to make it an interface:

1) the semantics associated with the result need to be described
somewhere, and describing them once in the Comparator class
makes more sense than describing them at all the places where
they're used

2) it is potentially so widely used that giving it a name allows
much easier description of the algorithms in which it is used

3) the name is simple and descriptive enough that its intent is
fairly clear

On the other hand, even though Comparator stands on its own as a
design idea worthy of naming, I know that I could implement 75-90% of
all the Comparator implementations I've ever seen with a few simple
primitives, and eliminate the implementation class with an aggregate
of objects of pre-existing classes.

In the case of AttributeAppliers, you've got a basic interface that
takes fairly specific arguments with fairly specific meanings. That
would tend to suggest that the base interface has enough semantic
weight to stand on its own. You might be able to create one
implementation that uses a functor for implementation and use that to
replace a number of the existing classes, but you'll probably still
find yourself with a number of implementations that are more
complicated than what a single functor is good for. You'd be able to
reduce your classcount somewhat, and you'd have a place in the design
to attach a lot of functionality that you haven't thought of yet, but
it's not going to simplify things greatly.

The ElementAssimilators look much simpler (at least the few that I've
glanced at). It's more likely that there are a lot more of them that
boil down to a single line implementation, particularly since many of
them seem to be descriptions of the relationship between some graphical
parent object and an associated child element.

---

**
Note that there's still work to do with the functors themselves. I
maintain that single lines of java can be translated into functors,
but I have to admit that learning how to do it can be daunting. The
combining functors take a little time to get the hang of, and
complicated java expressions will of course yield complicated compound
functors. This is the major problem that I've been gearing up to
attack in the jga project.

gphilipp
Offline
Joined: 2003-06-10

David,

I've used some functors from the jakarta-commons packages myself (Transformer, Function, etc...), and i found the code using them although powerful quite difficult to debug too...

Gilles Philippart

dhall
Offline
Joined: 2006-02-17

>> I've used some functors from the jakarta-commons packages myself (Transformer, Function, etc...), and i found the code using them although powerful quite difficult to debug too...

I know -- I had the same issue with functors in JGL a number of years ago. Once you get the hang of them, they're very powerful, but in a way its like using powertools with the safety features off.

I've done a couple of things in JGA that help, and I'm working on a couple of significant extensions. First thing is that JGA uses generics, and the big benefit is that its a lot harder to put the combinations together wrong. Using generics lets the compiler check that you've got the compound structures assembled correctly -- all of the arg-types and return-types are checked at compile time. Also, if you do it wrong and the compiler catches it, the error message you get, while still somewhat cryptic, is a lot better in identifying the problem.

The other thing I've done a little differently is in how the combination functors are typically used. I wrapped the adaptors in methods defined in the abstract base classes of the various types of functors. This lets you focus on the functors you need to describe the functionality you want and less on which specific functor you need in order to plug the compound structure together. There's an example of this in the change log, which can be found at http://jga.sourceforge.net/changes.shtml -- I don't have a link to the specific part of that document, so you have to scroll down to the changes from 0.2.1 to 0.3, point #2.

What I want to get working, tho, is something that takes advantage of the annotation processing capabilities in java 1.5: I want to declare the functor with a string that gets parsed at compile time in order to build the structure correctly and insert it into the code for later compilation. I believe that the syntax of the string passed to the annotation processor could be pretty much anything, but that making it closely resemble java syntax will be a very powerful addition. That's the main reason I'm working on spreadsheet control -- the code necessary to allow the user to enter formulas in a spreadsheet will be reused to make the annotation processor work. If I can get that to work, then most people will never see the complex code necessary to get compound functors configured correctly.

dhall
Offline
Joined: 2006-02-17

This sorta brings up the discussion issues that I mentioned in the 'Is anyone else bothered by the JCA?' thread. I think that what I spoke on could have benefit to JDNC and if Sun decides that it would like to incorporate my ideas, I'll be willing to hammer out a copyright assignment that meets everyone's needs.

The homepage of the project from which I built the session is

http://jga.sf.net

and it has links to both the complete CVS tree and to the slides from my 2002 JavaOne BOF. I don't believe that I am allowed to post the 2004 slides, so I haven't put them anywhere, yet. Last time I tried to get onto JavaOne Online, I was turned away -- I thought that speakers weren't going to get access, but then I heard that regular attendees hadn't been able to get access either.

I'd intended to get a release out prior to JavaOne, but I needed the time to make sure that I didn't embarass myself too badly up on stage. I'm pushing now to get a couple more examples built and hope to get a release up in the next week or two.

David Hall
http://jga.sf.net/

dhall
Offline
Joined: 2006-02-17

Right after I posted the previous message, I clicked over to the java.net homepage and was very pleasantly suprised to see that the JavaPatterns story link at the top of the page currently points to the jga project as well!