We are mixing two things in this thread - how much we care about backward compatibility and how and when to use interfaces.
I think we need to settle both topics. I have stated my view, which is really just to standard Commons policy, on the backward compatibility issue. Based on many years experience using, developing and maintaining libraries here and elsewhere, I agree with others who have stated that constant incompatible change makes a library almost worthless for use across a wide range of applications. Something just used inside one application or relatively small development group can be constantly refactored and productively used; but broadly reusable components need to have stable APIs. Incompatible changes have to be well-documented and introduced in major releases that are relatively few and far between. That is essentially how we have operated in Commons for 10+ years now and it is the reason that some suggest that when we do a major API refactoring of a component we change the package name and even the component name. I don't buy the argument that we really *need* to keep making incompatible API changes in [math] because there are features or bugs that can't be added in compatible ways. I have seen only a tiny handful of these - just one in 2.2. Luc mentions SVD as a frustrating problem for us. The bugs have nothing to do with the API definition, unless I am missing something basic. We have numerical problems. We need to solve them. Gilles is right that we have limited resources. I would much rather that these resources be focused on solving the numerical and algorithmic problems involved in delivering robust and stable mathematical software than endless arguments about how to refactor the API. As a user, I would be much happier with a stable API with a few warts that provides well-documented, well-tested (because lots of users are using the *same* core impl) mathematics than a beautiful but unstable API with buggy implementation code. Regarding interfaces, I think we are starting to focus on the right question. I think we agree that use of interfaces just to separate interface from implementation in support of the strategy pattern is, let's just say "deprecated." When we started [math] back in 2003, that was not considered bad design. We went overboard with it, though, and ran into the problems we have been discussing on this thread around extensibility. Most of the bad designs came from my contributions, so I have to apologize for putting us into this position. To allow multiple implementations of a fully defined interface, we seem to have learned in Commons that abstract classes work better. I am fine with that principle and will volunteer to start first suggesting and discussing changes individually and then making them. I already started this with RandomData/RandomDataImpl. We can continue discussion on that thread about whether we even need an abstract class in that case. Other use for interfaces are to a) designate behaviors for implementation units that can be "plugged in" to algorithms (where the interface defines only some of the behaviors of the class - as in the multiple inheritance example). An example of this is the RandomGenerator interface, which encapsulates the behavior of a low-level source of random data. b) encapsulate abstract data types, e.g. Field. I think we need to keep at least these interfaces, but we should think long and hard about exactly what they should contain. Here again, I think we need to look at each example individually. Examples like RealMatrix could be argued to be good "b)" examples or restrictive handcuffs that should be eliminated. I think we need to be very careful with these decisions so that we can aim to really stabilize the API in 3.0. I honestly do not think that is an unrealistic expectation. Phil --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org