Hi Gilles, and sorry for mistyping your name in my previous message, ----- "Gilles Sadowski" <gil...@harfang.homelinux.org> a écrit :
> Hi. > > > > [...] > > > > > > > > What about new code? With the current signature and > documentation > > > > there is no information on possible exception conditions. The > fact > > > > the method will throw an exception on failure needs to be > > > expressed. > > > > > > > > [...] > > > > > > The fact is: You don't know whether an exception will be raised > on > > > failure. > > > It depends on the implementation: A user might decide that failure > is > > > dealt with by returning "NaN" (or Infinity). > > > Another user might decide to throw a > "MathIllegalArgumentException" or > > > a > > > subclass thereof or something completely different... :-) > > > IMHO, the "FunctionEvaluationException" is fairly useless. Its > only > > > use I > > > can see is to wrap "alien" (user-defined) exceptions: Any methods > in > > > > When this exception was unchecked, it was the primary use of it : > wrapping > > exceptions unknown to [math]. Of course, we cannot enforce users to > use it > > and even when it was checked users could decide to throw any other > unchecked > > exceptions or return NaN. Documenting it is simply a gentle way to > tell our > > users this exception is the recommended way to signal errors. > > > There are at least 2 different issues: > 1. What is the recommended behaviour of implementations > 2. What CM will do when it calls "value" and catches an exception There is a third issue, and it was a driver for the current architecture. Some CM algorithms are utilities that are provided by the library that act on low level user functions and are intended to be called from higher level user function. They are "sandwiched" between two user levels. Typical examples are root finding, optimization or ODE integrators. In this case, the user knows it's own function and the fact it can fail for some values. When this case occurs, the function throws some kind of exception so that the algorithm is interrupted. It does not simply return a NaN as this would simply cause a nightmare in the commons math algorithms. The code compiles only if the exception was authorized beforehand in the interface (this was the case with the former architecture an checked exceptions) or if it is an unchecked exception (which is the case now). Of course, the user could have thrown any other unchecked exception even in the former architecture. At runtime, the commons-math algorithm does not catch the exception, neither the checked one before nor the unchecked one now (it may catch it, wrap it in its own exception and throw the wrapped one again, but I don't remember any exemple of this behavior in commons-math, only in upper level libraries I use). So some exception reached higher level user code, and there the user can decide what to do with it. If the same development team does develop both user levels, declaring exceptions could be cumbersome. If different development teams are in charge of the low anf top level, it is interesting to have a way to convey development guidelines to them via javadoc or declared throws statements. At least with one generic exception like FunctionEvaluationException, we provide an hint to developers of the low level function that it would be wise to stick with this exception type (even if they want to wrap a NotPositiveException in it for the sake of better relevance). We also provide an hint to developers of the top level algorithm that calls commons-math that the function they provide to it and that was provided to them by the other team may throw this exception and that commons-math simply let it slip upward. So they are aware they should at least understand when this occurs and be able to act properly. > > For (1) I don't think that it is wise to suggest that any function > should > throw "FunctionEvaluationException", because this exception doesn't > convey > any information. For example, a function that will compute the > square-root > should better throw a more specific "NotPositiveException" (a subclass > of > "IllegalArgumentException") when passed a negative argument. Yes, a more focused exception would be better. It is also possible to wrap a focused NotPositiveException into a general FunctionEvaluationException and get the best of both worlds. We cannot enforce it at java level. > > If some part of CM wants to catch a failure (e.g. because the > computation > can meaningfully continue, or just to provide a localized message), it > is > certainly not safe to catch only "FunctionEvaluationException" since > indeed > we cannot enforce that it will be the only exception type to arise. > Hence, for (2), we will catch *any* "RuntimeException" (and continue, > or > throw a "FunctionEvaluationException"). Yes, most of the time I think commons-math will not catch these exceptions at all. > It is thus useless and misleading to recommend something that we don't > care > about. Despite I agree with the premisses, I don't agree with this conclusion. We do care about these exception and we could document them. Simply we cannot handle them by ourselves and we let them slip upward to the user code calling our code. > > Thus, neither (1) nor (2) is reason for letting appear the word > "FunctionEvaluationException" within the interface file. > > To summarize, a "FunctionEvaluationException" class only makes sense, > IMHO, > for the localization (of exception messages) requirement: Catch every > exception and wrap it in a "FunctionEvaluationException". > [If you agree with this use-case, I'll modify the new > "FunctionEvaluationException" so that it takes the cause as its > argument.] > > Please let me know whether you have use cases that would contradict > the > above. Is the user case I exposed above help you understand the rationale behind the previous architecture ? It is exactly this case that lead me to use this pattern almost everywhere a commons-math algorithm has to call user-provided code. The problem first arose in ancient versions of the mantissa library (some code of which are now in commons-math). I did not foresee user code could fail when I designed some algorithm (I think it was about ODE). Then in a real case I had a computation that due to some underlying library did throw an exception and I could not let it go up because the interface I had to implement before providing my ODE to an integrator had no exception at all! So I added a way for user code to signal some error occurred and did not catch it al all in the integrator, it went all way up back to user code. I decided to use checked exception at that time and so documentation was automatic as the compiler would enforce users to be aware of the exceptions that may be thrown. You found that this was cumbersome because some functions may not throw any exception so the caller of the solver/optimizer/integrator had to deal with exceptions that would NEVER arise since they are not generated by commons-math itself and were not generated in some user code. We decided to switch to unchecked exceptions which in my view is now a good consensus (you had a hard time convincing me, I know). The case where user code does need to throw exceptions is still there and it should be handled gracefully too. The fact we cannot enforce users to use this specific exception and we cannot prevent them from using another unchecked exception is not a sufficient reason not to document the way we expect them to behave. Once again, if the same team or even single developer does both the low and top levels, he will not care wrapping its MyWonderfulVerySpecificUncheckedException into a FunctionEvaluationException at low level only to unpack it at top level. He will simply throw it here and catch it there and all will work seemlessly. When different, somewhat large teams develop a complex program, sometimes from different companies in different contracts for the same final user, sharing a common guideline (it's only a guideline) that FunctionEvaluationException is the expected way to interrupt commons-math code and go back to user level is a good thing. Hope this helps, best regards, Luc > > > > [...] > > Best, ;-) > Gilles > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > For additional commands, e-mail: dev-h...@commons.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org