On Monday, November 18, 2013 12:18:31 Walter Bright wrote: > I agree. But I'll add that it would be even better to redesign FracSec.from > so it never throws at all - have it assert(0) for invalid values being > passed to it. > > Exceptions should not be thrown for invalid arguments. Data validation > should be handled separately.
I think that that depends. In some cases, it would just mean duplicating work if the API expected the caller to verify the arguments' validity first. A prime example of this would be functions which parse strings. It would be highly inefficient for a function like fromISOExtString to assert instead of enforcing. The caller would have to do the exact work that the function has to do in order to do the check, so it's just wasteful to expect the caller to ensure the validity of the input. Constructors for types like SysTime or DateTime are in a bit more of a grey area in that in most cases what's passed is likely to be valid - e.g. hopefully, when someone gives a date, they have some clue that the date is valid ahead of time. However, there are cases where the caller really has no way of knowing ahead of time whether a date is going to be valid or not - e.g. is February 29th a valid date in year X? A function could be provided to check the validity ahead of time, but that puts a greater burden on the caller and ends up duplicating the checks. It also would have created more code duplication in std.datetime in some places, because the checks would have to be put in more places rather than having them in a centralized location (e.g. Date's constructor can check the validity of the values, and DateTime can just take advantage of that rather than having to duplicate the check). I do acknowledge however that it's a grey area. In general, std.datetime takes a defensive programming approach rather than the DbC approach with the idea that it's often likely that the input is going to be originate from a user or file and that many of the checks have to be done regardless, so asking the programmer to do them just adds overhead. In some cases, it arguably should have used DbC, but there were enough places that it should have been using defensive programming already that it was more consistent to use defensive programming in any of the grey areas. - Jonathan M Davis
