> The base idea behind functor is to create large and complex behaviors by
> composing small and simple (and generally stateless) ones.
>
> Part of this is the same as the mathematical notion of the composition of
> functionsbuild a composite function c out of simpler functions. For
> example:
>
> c(x) := f(g(x))
>
> or,
>
> c(x,y) := h(f(x),g(y))
>
> or,
>
> c(x,y) := f(x) when g(x) is true
> f(y) otherwise
> etc.
>
> Another part of this is the composition of arbitrary functions into
> "templated" algorithms, similar to the GangofFour's "Template Method"
> pattern, except generally using composition instead of inheritance/method
> overloading. For example, a function like "inject" or "fold":
>
> Object inject(Iterator iter, Object seed, BinaryFunction f) {
> while(iter.hasNext()) {
> seed = func.evaluate(seed,iter.next());
> }
> return seed;
> }
>
> can be used for a very large number of things. For instance, ((x<y)?y:x))
> makes inject into a "max" function, (x+y) makes inject into a "sum"
> function, ((x*count)+y)/++count) makes inject into an "average" function,
> etc. When combined with the first notion of composition, this becomes a
> very powerful technique.
>
> I think this strategy is quite applicable to mathematics and commonsmath
> in particular.
I agree. The question is when to bring this kind of machinery in (see
comments below).
>
> Mark also wrote (I think this was Mark anyway):
>
>
>>b.) Which design strategy is of more interest
>>to the project? Small compact classes used to
>>complete one specific task, where the programming
>>is primarily OOD in nature? or Feature rich
>>interfaces that encapsulate full ranges of
>>functionality, where programming is primarily
>>"procedural" in nature?
>
>
> IMO, and as I lurker on commonsmath at best, my opinion probably doesn't
> and shouldn't carry a lot of weight, the appropriate design strategy is a
> functional one, which shares some of the attributes what you describe as
> OO (but functional is decidedly not OO).
Can you expand a little on exactly what you mean here, ideally with some
specific examples? Don't limit yourself to what is already implemented
in commonsmath.
>
> Phil Steitz wrote:
>
>
>>IMHO, the most important considerations
>>are 1) how easy the library will be to
>>navigate and use 2) how maintainable it
>>will be and 3) how well it will perform
>>(including resource requirements).
>
>
> I agree with that, and think a functional approach would definitely
> support the second point (maintainability) and IMO the first (ease of use)
> as well.
Can you provide some examples on the ease of use point here? You don't
have to limit them to what exists now in commonsmath. As a
mathematician, I might personally be very happy (sometimes) working with
function spaces definable by the operations that they support (e.g LP
spaces, groups, rings, fields, etc) but I don't think that
nonmathematicians  or even mathematicians who are lazy programmers 
would like to work in that world. A concrete example is the "Operable
objects" defined in Jade and their use in Jade's matrix class
(http://www.dautelle.com/jade/api/com/dautelle/math/Matrix.html). As a
user, I would much prefer to work directly with a real matrix (see
additional notes below on the special position of reals). Part of what
I am resisting here is the lure of "mathematical domain modelling" 
even from a functional standpoint  as a primary focus. I would prefer
to keep the focus on the practical applications and bring in the
abstractions only as we need them. I think that it is likely that I am
missing your main point, so please (gently) enlighten me.
The third point (performance) probably isn't helped by a
> functional approach, although it may not be hurt by it either. I'm of the
> "don't do it, yet" philosophy on optimization though.
I agree.
>
> Phil also wrote:
>
>
>>My opinion here is that a univariate real
>>function is an object in its own right.
>>I suppose that it could extend Functor,
>>but I do not see the point in this and
>>I would personally not like having to
>>lose the typing and force use and casting
>>to Double to implement
>>Object evaluate(Object obj);
>
>
> A few observations here:
>
> 1) A common approach to this sort of problem would be something like:
>
> abstract class <Type>UnaryFunction implements UnaryFunction {
> final Object evaluate(Object obj) {
> return (<Type>)evaluate((<Type>)obj);
> }
>
> abstract <Type> evaluate<Type>(<Type> type);
> }
>
> class MyFuction extends <Type>UnaryFunction;
>
> etc., but I'll argue that it's the distinction between primitives and
> their object wrappers that are the concern here.
This is certainly part of my problem. I could get over both of this,
however, if I saw big value in having UnivariateRealFunction extend
Functor. Here is more precisely what I am struggling with in the
specific case of realvalued functions. When I said that "a realvalued
(differentiable) function is an object in its own right" what I really
meant was that the fact that its characterization as a (partially)
composable mapping does not capture very much  the most important
functional characteristics of a real > real function make essential use
of the fact that its domain and codomain are the real numbers. Things
like convolution, integration, differentiation, rootfinding, etc. make
no sense at the Functor level. To me, having UnivariateRealFunction
extend Functor would be like having Complex extend Group. Sure, you
could do it and it makes sense logically, but why introduce the
additional layer unless there is a strong practical reason (or
anticipated reason) to do so? Also, just as there are additional
natural layers between Complex and Group (Field, Ring) there are also
probably additional natural layers between Functor and
UnivariateRealFuntion (see more below). I know this is mixing OO and
functional ideas, but hopefully you get the point.
Note that this does NOT rule out the applicability of the functor
approach for other things down the road.
>
> 2) It may not be necessary to commit to extending or using commonsfunctor
> from the beginning. Any functional approach is readily adapted to
> commonsfunctor. E.g., given:
>
> interface UnivariateFunction {
> Double evaluate(Double x);
> }
>
> it's not difficult to create a (commonsfunctor) UnaryFunction adapter:
>
> class Univariate2UnaryFunction implements UnaryFunction {
> Univariate2UnaryFunction(UnivariateFunction f) {
> this.f = f;
> }
>
> Object evaluate(Object obj) {
> return f.evaluate((Double)obj);
> }
>
> UnivariateFunction f = null;
> }
>
> which would join the two libraries, but again it's the distinction between
> primitives and their object wrappers that are the concern here.
Yes. but maybe not a serious concern for some use cases. This is an
interesting idea. I would like to think/discuss some more about the
potential uses of this.
>
> 3) I can imagine primitive versions of the commonsfunctor interfaces,
> say:
>
> interface DoubleFunction { double evaluate(double); }
>
> with either parallel implementations of the functor composers, adapters,
> and utilities, or with adapters between the two (or both). (I'm the guy
> behind most of collections.primitives.* after all.) But I don't imagine
> those being part of a version 1 release.
>
Also a very interesting idea. My intuition is that what will turn out
to be useful are not "primitive" versions, but "algebraic" or
"mathematical" versions (i.e., versions that use primitives or other
mathematical objects as domain, codomain to represent functors with
additional algebraic properties).
>
> In short, and for what it's worth, my suggestion is this:
>
> * Where appropriate (and I think it's probably appropriate often),
> commonsmath should follow a functional design, like the one we see in
> UnivariateFunction.
Please point out any additional opportunities/inconsistencies that you
can see now or that you see as more gets added to the package. Thanks in
advance.
>
> * This functional approach will probably be based on primitives rather
> than objects, and hence fully independent of anything in commonsfunctor.
For now, I agree. I am intrigued, however, by the idea of "mathematical
functors", mostly for use in more strictly mathematical applications
than what commonsmath is at least initially aiming at. To me, the real
distinction is between reals, complex numbers (not yet in the package),
matrices, etc and "domain elements", not primitives vs objects.
>
> * When object based functors are created, I'd consider implementing the
> corresponding commonsfunctor interface, or at least leaving room for
> doing so in the future (for instance, using the same method signatures
> with the same semantics, but not necessarily extending or implementing the
> functor type for now).
I agree.
>
> * Let's come back to this discussion after a v1 release of both math and
> functor, and see if we want to start bridging the two APIs more directly.
> I think doing so could be very useful, and with just a little bit of
> forethought, should be fairly easy as well.
I agree. Thanks for the feedback. Pls help make sure that we don't do
anything that will make this harder down the road.
Phil
>
>  Rod <http://radio.weblogs.com/0122027/>
>
>
> 
> To unsubscribe, email: commonsdevunsubscribe@jakarta.apache.org
> For additional commands, email: commonsdevhelp@jakarta.apache.org
>

To unsubscribe, email: commonsdevunsubscribe@jakarta.apache.org
For additional commands, email: commonsdevhelp@jakarta.apache.org
