Modern Fortran OO Features
Total Page:16
File Type:pdf, Size:1020Kb
Modern Fortran OO Features Salvatore Filippone School of Aerospace, Transport and Manufacturing, [email protected] IT4I, Ostrava, April 2016 S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 1 / 25 Preface Premature optimization is the root of all evil | Donald Knuth Write 80% of your source code with yourself and your fellow programmers in mind, i.e. to make your life easier, not your computers life easier. The CPU will never read your source code without an interpreter or compiler anyway. Arcane or quirky constructs and names to impress upon the CPU the urgency or seriousness of your task might well get lost in the translation. S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 2 / 25 Preface Procedural programming is like an N-body problem | Lester Dye \The overwhelming amount of time spent in maintenance and debugging is on finding bugs and taking the time to avoid unwanted side effects. The actual fix is relatively short!" { Shalloway & Trott, Design Patterns Explained, 2002. S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 3 / 25 OOP { Recap By widely held \received wisdom", Object-Oriented Programming emphasizes the following features: 1 Encapsulation 2 Inheritance 3 Polymorphism All three are supported by Fortran. S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 4 / 25 OOP nomenclature Fortran C++ General Extensible derived type Class Abstract data type Component Data member Attribute class Base class pointer Dynamic Polymorphism Type guarding (select type) RTTI (dynamic cast) Type-bound procedure Virtual Member functions Method, operation* Parent type Base class Parent class Extended type Subclass Child class Module Namespace Package Generic interface Function overloading Static polymorphism Final Procedure Destructor Defined operator Overloaded operator Defined assignment Overloaded assignment Deferred procedure binding Pure virtual member function Abstract method Procedure interface Function prototype Procedure signature Intrinsic type/procedure Primitive type/procedure Built-in type procedure S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 5 / 25 Encapsulation: Type-bound procedures The first tenet of OOP is encapsulation: Package data, and bring the code (method) close to the data (object) The Fortran concepts for this are derived types (which we have already seen) and type-bound procedures. function greet(this) result(message) module astronaut_class class(astronaut), intent(in):: this implicit none character(len=max_string_length):: message private ! Hide everything by default message= this%greeting public:: astronaut ! Expose type & constructor end function integer,parameter:: max_string_length=100 end module type astronaut private program oo_hello_world character(len=max_string_length):: greeting use astronaut_class ,only : astronaut contains type(astronaut) :: pilot procedure:: greet ! Public by default pilot= astronaut('Hello, world!') end type print*, pilot%greet() contains end program S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 6 / 25 Encapsulation: Type-bound procedures Features of type-bound procedures: The name by which the procedure is invoked; The object on which it is invoked; The visibility; The extensibility (to be further explored later); Generic type-bound procedures S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 7 / 25 Encapsulation: Type-bound procedures contains module psb_base_mat_mod type:: psb_base_sparse_mat function psb_base_get_fmt() result(res) !> Row size implicit none integer(psb_ipk_), private::m character(len=5) :: res !> Col size res= 'NULL' integer(psb_ipk_), private::n end function psb_base_get_fmt !> Matrix state: ! integer(psb_ipk_), private:: state integer(psb_ipk_), private:: duplicate function psb_base_get_nrows(a) result(res) logical, private:: triangle implicit none logical, private:: upper class(psb_base_sparse_mat), intent(in)::a logical, private:: unitd integer(psb_ipk_):: res logical, private:: sorted res= a%m logical, private:: repeatable_updates=.false. end function psb_base_get_nrows contains function psb_base_get_ncols(a) result(res) implicit none procedure, pass(a):: get_nrows => psb_base_get_nrows class(psb_base_sparse_mat), intent(in)::a procedure, pass(a):: get_ncols => psb_base_get_ncols integer(psb_ipk_):: res procedure, nopass:: get_fmt => psb_base_get_fmt res= a%n end function psb_base_get_ncols end type psb_base_sparse_mat end module psb_base_mat_mod S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 8 / 25 Encapsulation: Type-bound procedures Type-bound procedures can be generic type:: psb_base_sparse_mat ....... contains procedure, pass(a):: transp_1mat => psb_base_transp_1mat procedure, pass(a):: transp_2mat => psb_base_transp_2mat generic, public:: transp => transp_1mat, transp_2mat end type psb_base_sparse_mat contains subroutine psb_base_transp_1mat(a) class(psb_base_sparse_mat), intent(inout)::a integer(psb_ipk_):: itmp itmp= a%m a%m= a%n a%n= itmp a%triangle= a%triangle a%upper=.not.a%upper end subroutine psb_base_transp_1mat subroutine psb_base_transp_2mat(a,b) class(psb_base_sparse_mat), intent(in)::a class(psb_base_sparse_mat), intent(out)::b b%m= a%n b%n= a%m b%triangle= a%triangle b%upper=.not.a%upper end subroutine psb_base_transp_2mat S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 9 / 25 Inheritance: extending types The second tenet of OOP is inheritance: Embrace and extend existing types type:: speaker contains procedure(talk) ,deferred:: speak end type abstract interface function talk(this) result(message) import:: speaker,msg_max_length class(speaker) ,intent(in):: this !character(:) ,allocatable :: message character(len=msg_max_length):: message end function end interface S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 10 / 25 Inheritance: extending types type,extends(speaker):: astronaut private character(len=msg_max_length):: greeting contains procedure:: speak => greet end type contains function greet(this) result(message) class(astronaut) ,intent(in):: this character(len=msg_max_length):: message message= this%greeting end function S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 11 / 25 Inheritance: extending types Rules: The extended type implicitly has all the comoponents of the parent type; The extended type implicitly has the parent type as a component; The extended type implicitly gets all of the methods of the parent type; You should only ever override specific procedures, generics work automatically S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 12 / 25 Polymorphism: static and dynamic The third tenet of OOP is polymorphism: Object instances may have different types Comes in two main varieties: Static polymorphism: the actual type can be resolved at compile time; Dynamic polymorphism: the actual type can only be resolved at runtime. Static polymorphism corresponds to the resolution of generic interfaces; we have already seen this in Fortran 95. S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 13 / 25 Morpheus: Greek god of dreams S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 14 / 25 Polymorphism Dynamic polymorphism is signalled by the CLASS keyword; a polymorphic entity must be either A dummy argument; A variable with the ALLOCATABLE attribute; A variable with the POINTER attribute; Examples: type point real:: x,y end type point type(point):: vp class(point), pointer:: pp pp => vp S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 15 / 25 Polymorphism A polymorphic variable may get its type by: The actual argument passed to a subroutine; The association between a pointer and a target; Specifying explicitly a type in an ALLOCATE statement. class(base_type), allocatable:: item .... allocate(extended_type:: item) Specifying a SOURCE or MOLD in the ALLOCATE statement. type(extended_type):: foo class(base_type), allocatable:: item .... allocate(item,source=foo) S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 16 / 25 Polymorphism Fine points: The CLASS specifier must appear for the passed object in all type-bound procedures (except those marked as FINAL); The CLASS specifier may or may not appear for other variables; Through a polymorphic variable you can only invoke methods of the declared type S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 17 / 25 Polymorphism The SELECT TYPE (aka type guard) construct allows fine discrimination among related types subroutine print_particle(p) class(particle)::p call print_vector('position',p%position()) call print_vector('momentum',p%momentum()) select type (p) type is (charged_particle) print*,'Charge is:',p%charge() class is (charged_particle) print*,'Charge is:',p%charge() print*,'May have other features ' type is (particle) print*,'Base particle type, nothing special ' class default print*,'Unknown particle type' end select end subroutine print_particle S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 18 / 25 Type inquiry functions extends type of(a,b) True if the type of a is an extension of the type of b same type as(a,b) True if the type of a is an extension of the type of b S. Filippone (SATM) Modern Fortran OO Features IT4I, Ostrava, 2016 19 / 25 The parent type component type:: psb_base_sparse_mat ....... contains procedure, pass(a):: transp_1mat => psb_base_transp_1mat procedure, pass(a):: transp_2mat => psb_base_transp_2mat generic, public::