Defining and invoking a constructor in Fortran - oop

I can't figure out how I define a simple constructor for a class. What I want to do is allocate an array in mytype and later populate it in the main program.
What I have is this:
module types
implicit none
type mytype
real, allocatable :: someArray(:)
end type mytype
interface
module procedure :: init
end interface
contains
subroutine init(this)
class(mytype), intent(inout) :: this
allocate( this%someArray(5) )
end subroutine init
end module types
program test
use types
implicit none
type(mytype) :: array
call array%init
do i=1, 5
array%someArray(i) = real(i)
print *, array%someArray(i)
end do
end program test
When I compile I get the error
Error: MODULE PROCEDURE at (1) must be in a generic module interface
What does that mean? How can I define a generic module interface?
Thanks!

The language's model for a user provided constructor is a generic function with the same identifier as the type, that simply returns an object of the type. Beyond the ability to have a generic with the same name as a type, this is nothing special.
module types
implicit none
type mytype
real, allocatable :: someArray(:)
end type mytype
interface mytype
module procedure :: init
end interface
! init would typically be private.
contains
function init()
type(mytype) :: this
allocate( this%someArray(5) )
! Non-pointer function result must be defined.
this%someArray = 0
end function init
end module types
program test
use types
implicit none
type(mytype) :: x
x = mytype()
do i=1, 5
x%someArray(i) = real(i)
print *, x%someArray(i)
end do
end program test
(The example is somewhat pointless given other aspects of the language, such as parameterized types, array constructors, automatic allocation or even the out-of-the-box capability of the built-in structure constructors.)
The error message from the compiler perhaps means to reference a generic interface, as a procedure statement is only permitted in an interface block for a generic.
Specific type bound procedure references - things with the syntax object % binding - are generally used when you have a parent type that has a method with a particular signature (set of dummy arguments, bar the passed argument), and you want to override that method in extensions - i.e. invoke a different procedure that has the same signature. Constructors don't fit this - typically the information that needs to be passed to a constructor (i.e. the signature of the call) is type specific.

Related

Private, Save attributes for variables in Fortran 90 modules

I am trying to add access restrictions to some of the variables (using private attribute) in a module but I need to use those variables in subsequent invocations of routines within that module:
module MyMod
private
integer,allocatable :: A(:)
public :: init,calc
contains
subroutine init()
! allocating and initializing A
end subroutine init
subroutine calc()
! Using A
end subroutine
end module
Questions:
Is this true that the private variable will not be in the scope of the program which uses this module.
If the answer to 1 is yes, then I would think that I can use save attribute for this variable. Please correct me if I am wrong?
Is this the proper way to perform this task?
Yes, if you put a private statement into your module without any further specification, you set the default accessibility to private.
For the first question, the Fortran 2008 Standard (Cl. 4.5.2.2 §3) states that:
If a type definition is private, then the type name, and thus the structure constructor (4.5.10) for the type, are accessible only within the module containing the definition, and within its descendants.
So A will not be accessible from anywhere outside the module or submodule (descendant).
For the second question, yes - you can use save here. (This is not related to the accessibility attribute). In fact, starting with Fortran 2008, this is implied for module variables, see for the Fortran 2008 Standard (Cl. 5.3.16 §4) [thanks #francescalus]:
A variable, common block, or procedure pointer declared in the scoping unit of a main program, module, or submodule implicitly has the SAVE attribute, which may be confirmed by explicit specification [...]
If I understood your third question correctly, it is related to the initialization. You could realize this with a function/subroutine to which you pass an array for initialization:
module MyMod
! ...
contains
! ...
subroutine init( A_in )
implicit none
integer, intent(in) :: A_in(:)
! allocating and initializing A
allocate( A(size(A_in)) )
A = A_in
end subroutine
end module
Inside init() you create a copy of A_in which is only accessible within the module. As long as calc() is part of the module (or a submodule thereof), it has full access to A.
To add to the answer by Alexander Vogt an implication of the save attribute.
This attribute gives precisely the effect you seem to be after (from F2008 5.3.16):
The SAVE attribute specifies that a local variable of a program unit or subprogram retains its association status, allocation status, definition status, and value after execution of a RETURN or END statement unless [something not applicable here]
In your example, A is a local variable of the module (and so a program unit) MyMod.
This means that, after the call to init which, presumably, allocates A and sets values that status is retained after the subroutine returns. Those values are then available come the call to calc. Both init and calc, of course, refer to the same A through host association.
You mention Fortran 90, so there is a subtle change (again as mentioned in that other answer). Before Fortran 2008 module variables would require the save attribute explicitly giving in some circumstances for this effect to come about. There's no harm in giving the save attribute explicitly if you aren't sure how your compiler treats the code (and some would say it's good practice, anyway).
This is another way of accomplishing what you want to do while avoiding the 'save'.
module MyMod
private
public :: myType, init
type myType
private
integer, allocatable :: A(:)
end type myType
contains
subroutine init(obj, n)
type(myType), intent(inout) :: obj
integer, intent(in) :: n
allocate(obj%A(n), source=-9999999)
end subroutine init
end module MyMod
program test
use MyMod, only: myType, init
type(myType) :: m ! m is an opaque object
call init(m, 10)
end program test
In this example, m is an opaque object - I can create the object, pass it around, but not access its contents (the array A in this case). This way, I am hiding my data. As long as my object m is in scope, I can operate on the data hidden in the object through routines contained in the module myMod.
If you have access to a modern compiler that supports Fortran 2003, you can rewrite the module as
module MyMod
private
public :: myType
type myType
private
integer, allocatable :: A(:)
contains
procedure, public :: init
end type myType
contains
subroutine init(obj, n)
class(myType), intent(inout) :: obj
integer, intent(in) :: n
allocate(obj%A(n), source=-9999999)
end subroutine init
end module MyMod
program test
use MyMod, only: myType
type(myType) :: m ! m is an opaque object
call m%init(10)
end program test

How to create and use array of type extensions in Fortran? [duplicate]

I am trying to use pointers to create links between objects. Using Fortran and here is the code piece:
module base_pars_module
type,abstract,public :: base_pars
end type
end module
module test_parameters_module
use base_pars_module
type, extends(base_pars) :: test_pars
contains
procedure :: whoami
end type
contains
function whoami(this) result(iostat)
class( test_pars) :: this
write(*,*) 'i am a derived type child of base_pars'
end type
end module
module base_mask_module
use base_pars module
type, abstract , public :: base_mask
class(base_pars),pointer :: parameters
end type
end module
module test_mask_module
use base_mask_module
implicit none
type, extends(base_mask) :: test_mask
end type
end module
program driver
type(test_pars) , target :: par_Test
type(test_mask) :: mask_test
iostat= par_test%whoami()
mask_test%parameters=>par_test
iostat=mask_test%parameters%whoami()
end program
parameters at base_mask_module is a pointer with base_pars class. I would like to use this pointer to refer par_test object which is test_pars type that extends base_pars type. So the pointer and the target has the same class. But when I compile this it gives an error:
driver.f90:17.37:
iostat=mask_test%parameters%whoami()
1
Error: 'whoami' at (1) is not a member of the 'base_pars' structure
Is it a bug or am i doing something wrong?
When you have polymorphism like this there are two things to consider about an object: its dynamic type and its declared type. The parameters component of test_mask (base_mask) is declared as
class(base_pars),pointer :: parameters
Such a component therefore has declared type base_pars.
Come the pointer assignment
mask_test%parameters=>par_test
mask_test%parameters has dynamic type the same as par_test: test_pars. It's of declared type base_pars, though, and it's the declared type that is important when we care about its components and bindings. base_pars indeed has no whoami.
You need, then, something which has declared type par_test. Without changing the definitions of the derived types you can do this with the select type construct.
select type (pars => mask_test%parameters)
class is (par_test)
iostat=pars%whoami() ! pars of declared type par_test associated with mask_test%parameters
end select
That said, things get pretty tedious quite quickly with this approach. Always using select type, distinguishing between numerous extending types, will be quite a bind. An alternative would be to ensure that the declared type base_pars has a binding whoami. Instead of changing the main program as above, we alter the module base_pars_module:
module base_par_modules
implicit none ! Encourage good practice
type,abstract,public :: base_pars
contains
procedure(whoami_if), deferred :: whoami
end type
interface
integer function whoami_if(this)
import base_pars ! Recall we're in a different scope from the module
class(base_pars) this
end function
end interface
end module
So, we've a deferred binding in base_pars that is later over-ridden by a binding in the extending type test_pars. mask_test%parameters%whoami() in the main program is then a valid and the function called is that offered by the dynamic type of parameters.
Both approaches here address the problem with the binding of the declared type of parameters. Which best suits your real-world problem depends on your overall design.
If you know that your hierarchy of types will all have enough in common with the base type (that is, all will offer a whoami binding) then it makes sense to go for this second approach. Use the first approach rather when you have odd special cases, which I'd suggest should be rare.

Node Class with Value of Arbitrary Type, Fortran 2003

I have not found the host of information on generics in Fortran to be useful.
I would like to create a Node class that:
Contains a variable of arbitrary class, "ANYTHING :: value,"
the class of which can be specified either (a) at instantiation or (b) through an init subroutine.
Ideally, I would like to imitate the Java functionality of:
Node<Integer> n = new Node<Integer>();
Is this possible in Fortran 2003? Or will I have to create a Node-derived class for every possible class that 'value' might have?
The solution presented in the first post does not quite accomplish what I want. Consider:
program generics_test
implicit none
type node_int
integer :: x
end type node_int
type node
class(*), allocatable :: value
end type node
type(node) :: obj
allocate(node_int :: obj%value)
!This must be used:
select type (val => obj%value)
type is (node_int)
val%x = 1
class default
!throw en error
end select
end program generics_test
This illustrates the main issue: the need for select type to interact with an allocated unlimited polymorphic object. Take for example:
module node_class
type node
class(*), allocatable :: anything
contains
procedure, public :: init => init_sub
end type node
private :: init_sub
contains
subroutine init_sub(this, something)
class(node) :: this
somethingObj :: something ! <--- this assumes we know what soemthing is;
! generous, since my question doesn't assume that
allocate(this%anything, source=something)
end subroutine init_sub
end module node_class
It seems that, although you may take class(*), allocatable :: anything and allocate(anythingObj, source=somethingObj) somewhere inside of type node, node cannot ever treat anything as though it were a somethingObj unless anything appears in a select type... type is (somethingObj) block. Thus, to emulate the snippet of Java I've written above select type would have to have a case for every single object that will ever be encountered.
It is possible to have a component an unlimited polymorphic entity.
type node_int
end type node_int
type node
class(*), allocatable :: value
end type node
type(node) obj
allocate(node_int :: obj%value)
end
Here, the class(*) is your "ANYTHING" (even, thanks to #IanH correcting me, intrinsic types) and the allocate statement sets the type.
It is possible, if you want to get closer to Java-ness to override the structure constructor, so that
obj = node(mold)
works, where the dynamic type is taken from mold. [Fortran 2008 has the mold= specifier in allocate.] But I won't go into that unless requested.
Depending on exactly what you want to do you may find this approach is much more work than having distinct types.
Edit, following question update
When one then wants to use the value of an unlimited polymorphic entity as given above, one is tempted by something like
allocate (integer :: obj%value)
obj%value = 1
This won't work without the Fortran 2008 rules of automatic allocation. [In the question one has an x component of node_int, but I'll just pretend node_int is itself an integer.]
Instead, one can use sourced allocation:
allocate (obj%value, source=1)
or a select type construct
select type ( x => obj%value)
type is(integer)
x = 1
end select
[This is the heart of my suggestion that it's a lot of work.]
A more detailed example, including sourced allocation and constructor
module types
type Penguin
character(len=20) :: name
end type Penguin
type node
class(*), allocatable :: value
end type node
interface node
module procedure node_c
end interface node
contains
function node_c(value)
class(*), intent(in) :: value
type(node) node_c
allocate(node_c%value, source=value)
end function node_c
end module types
program test
use types
type(node) obj(3)
allocate(obj(1)%value, source = 1)
allocate(obj(2)%value, source = Penguin('Percy'))
obj(3) = node(Penguin('Harold'))
do i=1, 3
select type (val => obj(i)%value)
type is (integer)
print '("Value is an integer: ", I0)', val
class is (Penguin)
print '("Value is a penguin called ", A)', TRIM(val%name)
end select
end do
end
Output from the above, compiled with ifort 14.0.1
Value is an integer: 1
Value is a penguin called Percy
Value is a penguin called Harold

How to specify procedures to be executed depending on data type of polymorphic variables

Conside the following sample code:
module mod
implicit none
type :: typeBase1
integer :: A1
end type
type :: typeBase2
integer :: A3
end type
type :: typeBase3
integer :: A3
end type
type, extends(typeBase1) :: typeDerived1
! Void
end type
type, extends(typeBase2) :: typeDerived2
! Void
end type
type, extends(typeBase3) :: typeDerived3
! Void
end type
type, extends(typeBase1) :: typeDerived11
! Void
end type
type, extends(typeBase2) :: typeDerived21
! Void
end type
type, extends(typeBase3) :: typeDerived31
! Void
end type
type :: complexType
class(typeBase1), pointer :: ptrBase1 ! typeBase1, 2 and 3 are extensible
class(typeBase2), pointer :: ptrBase2
class(typeBase3), pointer :: ptrBase3
end type
interface calcul
subroutine calculA(obj1, obj2, obj3)
import
type(typeDerived1) :: obj1 ! typeDerived 1, 2 et 3 are derived type of typeBase1, 2 and 3
type(typeDerived2) :: obj2
type(typeDerived3) :: obj3
end subroutine
subroutine calculB(obj1, obj2, obj3)
import
type(typeDerived11) :: obj1 ! typeDerived 11, 21 et 31 are derived type of typeBase1, 2 and 3
type(typeDerived21) :: obj2
type(typeDerived31) :: obj3
end subroutine
end interface calcul
contains
subroutine calculComplexType(complex)
type(ComplexType), intent(inout) :: complex
call calcul(complex % ptrBase1, complex % ptrBase2, complex % ptrBase3)
end subroutine
end module mod
What I am trying to do is that the subroutine calculComplexType calls a different version of the subroutine calcul, basing on the dynamic type of ptrBase1, ptrBase2 and ptrBase3.
The code does not work, because the compiler looks for a subroutine with the following interface:
subroutine calcul(obj1, obj2, obj3)
class(typeBase1) :: obj1
class(typeBase1) :: obj2
class(typeBase1) :: obj3
end subroutine
whatever the dynamic type of ptrBase1, ptrBase2 and ptrBase3 is.
My question is: is there a way in Fortran to write the interface calcul in order to automatically select a procedure basing on the dynamic type of the arguments?
I would like to avoid to use a long sequence of "select class".
Any suggestion to rewrite the code is welcome!
If you request dispatch based on all three arguments, it cannot be done. Some languages offer so called multimethods for this.
In Fortran you can use normal single dispatch methods (type-bound procedures), but in that case it can choose the subroutine only according to one argument.
Otherwise you have to use select the select type construct and make a case for every possible combination, be it inside one single procedure, or to select between more versions of it.
For two arguments, you can also consider the double dispatch pattern.
This is simply not possible in Fortran; the best you can do with polymorphism is to use an overridden type-bound procedure, selecting a function based on the dynamic type of one particular entity.
However, depending on the nature of what calcul does, it may make more sense to define just one version of calcul that takes polymorphic arguments (i.e. class(typeBase1), class(typeBase2), class(typeBase3)), and deal with the dynamic type inside calcul itself. The benefits are twofold:
calcul may be able to test the type of each argument independently from the others. If that is the case, you will still have to write three select type constructs, but they won't be nested or duplicated.
It's likely that you can use single dispatch (with type-bound procedures) to remove the need for a select type construct completely.
It's difficult for me to think of a situation where the code in this question is really the best design you could use.
If calcul is really doing something completely "different" for each dynamic type, in a way that's relevant to the code that calls it, then the calling code should not be using polymorphic pointers (e.g. perhaps there should be a different complexType for each different calcul).
But if every version of calcul is doing essentially "the same" operation (as far as higher-level code knows/cares about), regardless of dynamic type, then there should only be one version and it should accept arguments that are of the base class.

Fortran90 assigning pointers and derived types at runtime

I have a question regarding assigning Fortran90 derived types and pointers at runtime. I want to pass a derived variable type to a subroutine after the code reads an input file. So depending on the input I pass the appropriate data type. Let me explain:
I have two modules:
Module A_mod and Module B_mod. Each has it's own unique data type and subroutines. For example:
Module A_mod
type A
real :: x, y
end type
contains
subroutine FunA(me)
type (A), intent(in) :: me
<do stuff>
end subroutine
End module A_mod
Module B_mod is a mirror of the above with B replacing A (also the data type B has x and y defined as integers).
I also have a third module that has this interface:
interface fun
modular procedure funA, funB
end interface
Here is my problem. The user via an input file determines which module subroutine to use. How can I make a generic pointer that gets associated at runtime? Or something similar that doesn't require pointers.
For example:
type (?) :: pt
Call fun(pt)
where after the program reads the input file it picks the correct data type to be sent to the interfaced subroutine "fun". So the type is unknown until runtime.
If Fortran would let me declare a variable in my execution portion of code it would look like this for example
IF(input.EQ."A") THEN
type(A) :: pt
ELSE
type(B) :: pt
END IF
CALL fun(pt)
Any suggestion would be appreciated !!
Thank you
This is difficult to do cleanly in Fortran 90. It is straight forward in Fortran 2003.
Resolution of the procedure to call when the generic reference fun is encountered (in CALL fun(pt)) is done at compile time, based on the declared type of pt.
If you are limited to Fortran 90, then effectively you will need to maintain a flag of some sort that indicates at runtime which particular derived type you want to work with, have a named object for each of type A and type B, and everytime you want to reference fun have an IF construct that selects the correctly named argument.
(If the size of the objects is significant you can arrange for them to have common storage.)
Something like:
TYPE(A) :: pt_A
TYPE(B) :: pt_B
...
IF (input .EQ. 'A') THEN
CALL fun(pt_A)
ELSE
CALL fun(pt_B)
END IF
In F2003, you would define a common parent type, that had a specific binding named fun. pt would then be a polymorphic allocatable object, allocated based on input to either type A or type B as appropriate.
TYPE :: Parent
CONTAINS
PROCEDURE(parent_Fun), DEFERRED :: Fun
END TYPE Parent
ABSTRACT INTERFACE
SUBROUTINE parent_Fun(obj)
IMPORT :: Parent
IMPLICIT NONE
CLASS(Parent), INTENT(IN) :: obj
END SUBROUTINE parent_Fun
END INTERFACE
TYPE, EXTENDS(Parent) :: A
REAL :: x, y
CONTAINS
PROCEDURE :: A => A_Fun
END TYPE A
TYPE, EXTENDS(Parent) :: B
INTEGER :: x, y
CONTAINS
PROCEDURE :: B => B_Fun
END TYPE B
CLASS(Parent), ALLOCATABLE :: pt
...
IF (input .EQ. 'A') THEN
ALLOCATE(A:: pt)
ELSE
ALLOCATE(B:: pt)
END IF
...
CALL pt%Fun()