|
| 1 | +To: J3 |
| 2 | +From: Brad Richardson |
| 3 | +Subject: Traits for Types |
| 4 | +Date: 2020-January-27 |
| 5 | + |
| 6 | +Proposal for Fortran Standard: 202y (NOT 202x) |
| 7 | + |
| 8 | +1. Problem |
| 9 | + |
| 10 | +Currently, in order to pass a derived type to some library expected a type |
| 11 | +derived from it's own abstract type requires the addition of a "wrapper" type |
| 12 | +to be used. This requires a cumbersome amount of boiler plate code and is |
| 13 | +not conducive to the type of "generic" code one would like to be able to write. |
| 14 | + |
| 15 | +This proposal seeks to address the issue that writing "generic" libraries is |
| 16 | +either not possible, or places undue burden on its users. The main benefits are |
| 17 | +the reduction in repeated logic or boiler plate wrapper types required for |
| 18 | +generic libraries, thereby enabling more code reuse and easier to maintain |
| 19 | +code bases. |
| 20 | + |
| 21 | +2. Proposed Solution |
| 22 | + |
| 23 | +The solution would require the addition of a few attributes and variable |
| 24 | +declaration capabilities. First is the addition of the `trait` attribute |
| 25 | +to a type specification. This requires that the type be abstract, and contain |
| 26 | +no components. I.e. |
| 27 | + |
| 28 | + type, abstract, trait :: Show_t |
| 29 | + contains |
| 30 | + procedure(show_i), deferred :: show |
| 31 | + end type Show_t |
| 32 | + |
| 33 | + abstract interface |
| 34 | + function show_i(self) result(string) |
| 35 | + class(Show_t), intent(in) :: self |
| 36 | + character(len=:), allocatable :: string |
| 37 | + end function show_i |
| 38 | + end interface |
| 39 | + |
| 40 | +Second is the addition of the `implements` attribute for a type specification. |
| 41 | +The `implements` attribute requires a list of at least one trait the type is to |
| 42 | +implement, requiring the type to contain the procedures with the interfaces |
| 43 | +defined by the trait(s). I.e. |
| 44 | + |
| 45 | + type, implements(Show_t) :: Thing_t |
| 46 | + character(len=:), allocatable :: the_string |
| 47 | + contains |
| 48 | + procedure :: show |
| 49 | + end type Thing_t |
| 50 | + |
| 51 | + function show(self) result(string) |
| 52 | + class(Thing_t), intent(in) :: self |
| 53 | + character(len=:), allocatable :: string |
| 54 | + |
| 55 | + string = self%the_string |
| 56 | + end function show |
| 57 | + |
| 58 | +Third is the addition of a variable declaration form using `trait`, in a similar |
| 59 | +fashion to `class`. The `trait` specification would require a list of at least |
| 60 | +one trait, and must either be allocatable, or a dummy argument of a procedure. |
| 61 | +In a similar manner that the instantiated value of a class variable must be of |
| 62 | +that type, or an extended type, the instantiated value of a trait variable must |
| 63 | +be of a type which implements the given trait(s). Thus, no components of the |
| 64 | +instantiated value are accessible, only the procedures defined by the trait(s). |
| 65 | + |
| 66 | +3. Backward compatibility |
| 67 | + |
| 68 | +This addition to the language would not break any existing standard |
| 69 | +conforming Fortran program, and thus preserves Fortran's backward |
| 70 | +compatibility. |
| 71 | + |
| 72 | +4. Further discussion |
| 73 | + |
| 74 | +Online discussion that led to this proposal can be found at |
| 75 | +https://github.com/j3-fortran/fortran_proposals/issues/125 |
0 commit comments