datetime and timedelta constructor validation
datetime and timedelta contructor function currently do not implement and validation of input arguments to the contructor. For example, the datetime contructor needs to validate the following:
- Is year > 0?
- Is 0 < month < 13?
- Is 0 < day < 32?
- etc.
and raise an exception if any of the above tests fail. Similarly for timedelta constructor.
Currently, these constructors are implemented as pure elemental functions which allows the user to instantiate an array of datetimes or timedeltas in a familiar Fortran array syntax. Once the above validations and raising exceptions are implemented, these functions cannot be pure (nor elemental) anymore, because only an impure procedure can write to standard output and stop the program. Consequently, this will require implementing a separate version of constructors that will accept arrays as actual arguments, and which will be used for overloading the contructor.
Or use the new impure elemental... If compiler support exists. Alternatively, do something creative with pointers to allow a state full error stack to be passed around and the check it when the function returns.
@zbeekman Did not know about this feature. Is it F2008?
@milancurcic Alternatively, provide a basic class encapsulating errors handling that will be the parent ancestor of all classes: all pure procedures will remain pure and exception handling vould be done outside the pure procedure. I have not tried this approach, but I found suggestions on that on clf-google-group.
@zbeekman can you elaborate more on both elemental impure procedures and pointers aproach? :pray:
Datetime rocks! My toy project that exploits it is not abbandoned...
impure elemental
From MCR:
Elemental procedures as defined in Fortran 95 and 2003 are required to be pure, a condition which aids parallel evaluation. While this is advantageous for performance, it does prevent other possibilities where one wishes to perform impure processing elementally on arrays of arbitrary rank. In such cases, one was forced to provide a separate function for each permutation of conformant ranks; for a procedure with two arguments, that was 22 separate procedures (8 cases where both arguments had the same rank, 7 where the first was scalar andthe second was an array, and 7 where the first was an an array and the second was scalar). With the increase of maximum rank to 15, this increases to 16+15+15 = 46 separate procedures. The impure prefix on the procedure heading allows one to define an impure elemental procedure, which processes array argument elements one by one in array element order. An example is shown in Figure 20.9. This example is impure in three ways: it counts the number of overflows in the global variable overflow_count, it logs each overflow on the external unit error_unit, and it terminates the program with stop when too many errors have been encountered.
Code example not included due to licensing concerns....
Only the requirements relating to ‘purity’ (lack of side-effects) are lifted: the elemental requirements remain, that is: • all dummy arguments of an elemental procedure must be scalar non-coarray dummy data objects and must not have the pointer or allocatable attribute; • all dummy arguments of an elemental procedure must have specified intent; • the result variable of an elemental function must be scalar, must not have the pointer or allocatable attribute, and must not have a type parameter that is defined by an expression that is not a constant expression; • in a reference to an elemental procedure, all actual arguments must be conformable; and • in a reference to an elemental procedure, actual arguments corresponding to intent out and inout dummy arguments must either all be arrays or all be scalar.
comment about pointer
Pointer arguments with intent(in) can be used to allow pure functions to have arguments that are effectively intent(inout) because intent attached to a pointer only refers to the pointer association, the value of the data it is pointing to can change.
In the end, though, using an error handling class with an error stack is the way to go, IMO.
@zbeekman Thank you for the summary. At first I felt embarrassed that I missed this in my MRC, but then I realized it's described in the green (new) book which I don't own yet. I still own the blue book (95/2003). :)
Anyhow, these are great recommendations. I like the idea of an extensible parent class with error handling methods as a most general and re-usable approach. I will take some time to digest this information.
Get the green one! (Or see when they're going to publish their next book... maybe Fortran 2015 will be covered)
@zbeekman I skipped the green book and got the red book last year. :)