Fortran derived types - interface

I was wondering if it is somehow possible to define a derived type in Fortran which automatically returns the right type, without calling the type specifically e.g. var%real? Here's an example to explain what I mean:
module DervType
implicit none
type, public :: mytype
real(8) :: r
integer :: i
logical :: l
end type
end module DervType
program TestType
use DervType
implicit none
type(mytype) :: test
test = 1. !! <-- I don't want to use test%r here
end program TestType
Would this be possible by defining some sort of interface assignment (overload the =) or something like that? Is this even possible?
Thanks! Any help appreciated!

Found a solution to this and it was actually quite simple. Here's the code:
module DervType
implicit none
type, public :: mytype
real(8) :: r
integer :: i
character(len=:), allocatable :: c
logical :: l
end type
interface assignment(=) // overload =
module procedure equal_func_class
end interface
contains
subroutine equal_func_class(a,b)
implicit none
type(mytype), intent(out) :: a
class(*), intent(in) :: b
select type (b)
type is (real)
print *, "is real"
a%r = b
type is (integer)
print *, "is int"
a%i = b
type is (character(len=*))
print *, "is char"
a%c = b
type is (logical)
print *, "is logical"
a%l = b
end select
return
end subroutine equal_func_class
end module DervType
program TestType
use DervType
implicit none
type(mytype) :: test
test = 1. // assign real
test = 1 // assign integer
test = "Hey" // assign character
test = .true. // assign logical
print *, "Value (real) : ", test%r
print *, "Value (integer) : ", test%i
print *, "Value (character) : ", test%c
print *, "Value (logical) : ", test%l
end program TestType
I'm trying to use the variables within a program now (e.g. do some arithmetic calculations, etc.) but that seems to be rather difficult if not impossible. I might start another question about that.

Related

In fortran, why interface has a name? what does it do when you call the interface? [duplicate]

I'm trying to understand the difference between abstract interfaces and "normal" interfaces. What makes an interface abstract? When is each one necessary?
Suppose the examples below
module abstract_type_mod
implicit none
type, abstract :: abstract_t
contains
procedure(abstract_foo), pass, deferred :: Foo
end type
interface
subroutine abstract_foo ( this, a, b )
import :: abstract_t
implicit none
class(abstract_t), intent(in) :: this
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
end module
module concrete_type_mod
use abstract_type_mod
implicit none
type, extends ( abstract_t ) :: concrete_t
contains
procedure, pass :: Foo
end type
contains
subroutine Foo ( this, a, b )
implicit none
class(concrete_t), intent(in) :: this
real, intent(in) :: a
real, intent(out) :: b
b = 2 * a
end subroutine
end module
module ifaces_mod
implicit none
interface
subroutine foo_sub ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
end module
module subs_mod
implicit none
contains
pure subroutine module_foo ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
b = 2 * a
end subroutine
end module
program test
use ifaces_mod
use subs_mod
use concrete_type_mod
implicit none
type(concrete_t) :: concrete
procedure(foo_sub) :: external_sub
procedure(foo_sub), pointer :: foo_ptr
real :: b
foo_ptr => external_sub
call foo_ptr ( 0.0, b )
print*, b
foo_ptr => module_foo
call foo_ptr ( 1.0, b )
print*, b
call concrete%Foo ( 1.0, b )
print*, b
end program
pure subroutine external_sub ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
b = a + 5
end subroutine
The output is
5.000000
2.000000
2.000000
I haven't used abstract interfaces here. At least I think I havent? I've been doing this for a while and I've never used the abstract "qualifier" on interfaces. It seems that I haven't found a case where using abstract interfaces is required.
Could someone enlighten me here?
PS: Compiler Intel Visual Fortran Composer XE 2013 SP1 Update 3.
Edit:
Quoting Metcalf, Reid and Cohen in Modern Fortran Explained:
In Fortran 95, to declare a dummy or external procedure with an
explicit interface, one needs to use an interface block. This is fine
for a single procedure, but is somewhat verbose for declaring several
procedures that have the same interface (apart from the procedure
names). Furthermore, in Fortran 2003, there are several situations
where this becomes impossible (procedure pointer components or
abstract-type bound procedures).
So, is my compiler in error for accepting the code below and also the one with abstract type above?
module ifaces_mod
implicit none
interface
subroutine foo_sub ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
end module
module my_type_mod
use ifaces_mod
implicit none
type my_type_t
procedure(foo_sub), nopass, pointer :: Foo => null()
end type
end module
In both cases, I'd say that I actually have declared abstract interfaces without using the abstract keyword. I think my confusion has roots on the fact that the compiler is accepting code like this.
The "normal" interfaces — known by the standard as specific interface blocks (as you use in the title of the question) — are just normal interface blocks for some procedure. Therefore:
interface
subroutine foo_sub
end subroutine
end interface
means that there exists an actual (external) subroutine named foo_sub and it conforms to the specified interface.
An abstract interface
abstract interface
subroutine foo_sub_abs
end subroutine
end interface
just specifies how some procedure may look like, but the name is the name of the interface, not of any actual procedure. It can be used for a procedure pointers
procedure(foo_sub_abs), pointer :: p
or for a dummy arguments
subroutine bar(f)
procedure(foo_sub_abs) :: f
and it means that the actual procedure to which p will point or which is passed as f conforms to the abstract interface.
Note that you are allowed to use some existing procedure instead of an abstract interface in both two former examples. It just needs to have explicit interface available in the scope (typically it is in the same module, or in a module which is used).
As far as I know (but see #IanH's comment below) the compiler is allowed to refuse your code:
interface
subroutine abstract_foo ( this, a, b )
import :: abstract_t
implicit none
class(abstract_t), intent(in) :: this
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
because there exists no actual procedure named abstract_foo. Some compilers do not diagnose this, but they could.
Quite unrelated are generic interfaces. You can recognize them, because there is a name of a generic procedure after the word interface
interface generic_sub
procedure sub1
subroutine sub2(...)
end subroutine
end interface
Here sub1 and sub2 both exist, sub1 is already known and has already explicit interface available, sub2 is external and looks as the interface specifies, and both are specific procedure of the generic generic_sub. This is quite a different usage.
You then call
call generic_sub(...)
and according to the arguments you pass, the compiler chooses which specific procedure is called, if it is sub1, or sub2.
I would stress that these can be split into sparate interface blocks with the same name declared at different locations. You can add a specific procedure into an existing generic procedure this way.

Problem with accessing child declared type in Fortran

Consider the following code
module class_type
implicit none
class(*), pointer :: fnzo => null()
type, abstract :: gen
real :: ss
integer :: sdsd
class(gen), pointer :: next =>null()
end type
type, extends(gen) :: final1
real :: ss1
end type final1
type, extends(gen) :: final2
real :: x1(10)
end type
end module class_type
program test_class
use class_type
implicit none
class(gen), pointer :: test
type(final1) :: test1
allocate(test, source = test1)
print*, test% ss1
end program
I am trying to work out a a linked - list where each next element either inherits final1 or final2. Currently, just testing simple cases and I don't understand why I cannot access test%ss1. Anyone to help
As for "why we cannot access test% ss1", the following code might be useful for considering the reason. In this code, I get a user input (inp) and determine whether ptr points to variables of type test1 or test2. If ptr points to a variable of test2, accessing ptr% ss1 is clearly meaningless, so the compiler needs to guard against such an incorrect access. I think that is why the compiler allows only the access of components of gen (= declared type) unless select type (for actual data in memory) is provided.
program test_class
use class_type
implicit none
class(gen), pointer :: ptr !! parent type
type(final1), target :: test1 !! child type
type(final2), target :: test2 !! child type
integer :: inp
print *, "input some integer"
read *, inp
if ( inp == 1 ) ptr => test1
if ( inp == 2 ) ptr => test2
print*, "ptr% ss = ", ptr% ss !! OK
! print*, "ptr% ss1 = ", ptr% ss1 !! error (Line1)
select type ( ptr )
type is ( final1 ); print*, "ss1 = ", ptr% ss1 !! OK
type is ( final2 ); print*, "x1 = ", ptr% x1 !! OK
endselect
end program
If the Line1 is uncommented, it gives an error (with gfortran-8)
print*, "ptr% ss1 = ", ptr% ss1 !! error
1
Error: 'ss1' at (1) is not a member of the 'gen' structure; did you mean 'ss'?
I guess the situation is similar to other (statically typed) languages. For example, the following code in C++ gives an error when we access ptr->b.
#include <iostream>
using namespace std;
struct A {
int a = 1;
};
struct B : A {
int b = 100;
};
int main() {
A *ptr;
ptr = new B;
cout << ptr->a << endl; // 1
// cout << ptr->b << endl; // error: 'struct A' has no member named 'b'
delete ptr;
}
In order to access ss1, you need a pointer within your abstract class to the child object. The pointer can be of either type extensions you wish to define. Since your linked list has two different type extensions, you are required to declare two child pointers within your abstract class.
module class_type
implicit none
class(*), pointer :: fnzo => null()
type, abstract :: gen
real :: ss
integer :: sdsd
class(gen), pointer :: next =>null()
type(final1), pointer :: child
end type
type, extends(gen) :: final1
real :: ss1
end type final1
type, extends(gen) :: final2
real :: x1(10)
end type final2
end module class_type
program test_class
use class_type
implicit none
class(gen), pointer :: test
type(final1), target :: test1
allocate(test, source=test1)
test1% ss1 = 20.0
test% child => test1
write(*,*) test1% ss1
write(*,*) test% child% ss1
end program test_class
When you compile and execute, you'll see:
20.00000
20.00000

Heterogeneous array of Fortran classes

I have an abstract type and several types which inherit from him. Now I need to make an array of instances of those inherited types, but I'm not sure, if it's even possible in Fortran.
I've tried to make some wrapper type, like in Creating heterogeneous arrays in Fortran.
module m
implicit none
type, abstract :: a
integer, public :: num
end type a
type, extends(a) :: b
end type b
type, extends(a) :: c
end type c
type :: container
class(*), allocatable :: ptr
end type
end module m
program mwe
use m
type(b) :: b_obj
class(*), allocatable :: a_arr(:)
b_obj = b(1)
allocate(container :: a_arr(3))
a_arr(1) = container(b_obj)
end program mwe
But I'm getting this error:
test3.f90:28:25:
a_arr(1) = container(b_obj)
1
Error: Can't convert TYPE(b) to CLASS(*) at (1)
What am I doing wrong? Or is there any other, correct way to do it?
Attempt 2
I edited the code accordingly to francescalus's answer:
program mwe
use m
type(b) :: b_obj
type(c) :: c_obj
type(container), allocatable :: a_arr(:)
integer :: i
b_obj = b(1)
c_obj = c(2)
allocate(container :: a_arr(3))
a_arr(1)%ptr = b(1)
a_arr(2)%ptr = c(3)
a_arr(3)%ptr = c(1000)
do i=1,3
write(*,*) a_arr(i)%ptr%num
end do
end program mwe
And I'm getting another error:
test3.f90:36:35:
write(*,*) a_arr(i)%ptr%num
1
Error: ‘num’ at (1) is not a member of the ‘__class__STAR_a’ structure
As IanH commented when outlining the approach you take, the then current version of gfortran
does not appear to support definition of an unlimited polymorphic component via a structure constructor
container(b_obj) is such a thing. So, leaving aside whether you are still coming up against this problem, one may be interested in still allowing older versions/other compilers to use the code.
An alternative approach is not to use a constructor for the element of your container. Instead the single component can feature directly in an assignment:
use m
type(container) a_arr(3) ! Not polymorphic...
a_arr%ptr = b(1) ! ... so it has component ptr in its declared type
end mwe
Naturally, we still have the component of the container type polymorphic so any attempts to reference/define/etc., that component will be subject to those various restrictions. In your question you have the component unlimited polymorphic, but I see that you first talk about restricting the container's consideration to elements which extend the first type. Rather than declaring the container component as unlimited polymorphic it could be much more helpfully of declared type a:
type :: container
class(a), allocatable :: ptr
end type
This would be sufficient to solve the problem with
do i=1,3
write(*,*) a_arr(i)%ptr%num
end do
because num is a component of the declared type of a_arr(i)%ptr (that is., a). In general, it isn't the complete solution because
do i=1,3
write(*,*) a_arr(i)%ptr%num_of_type_b
end do
wouldn't work (with num_of_type_b a component in the extending type). Here you have to use the usual tricks (defined input/output, dynamic resolution, select type and so on). Those are beyond the scope of this answer and many other questions may be found covering them.
I add the correction to resolve the following error,
test3.f90:36:35:
write(*,*) a_arr(i)%ptr%num
1
Error: ‘num’ at (1) is not a member of the ‘__class__STAR_a’ structure
The unlimited polymorphic variable cannot directly access any component of the dynamic data type. In this case, a simple solution is to avoid class(*). The definition of container is changed to
type :: container
class(a), allocatable :: ptr
end type
So the working code in summary is as follows,
module m
implicit none
type, abstract :: a
integer, public :: num
end type a
type, extends(a) :: b
end type b
type, extends(a) :: c
end type c
type :: container
class(a), allocatable :: ptr
end type
end module m
program mwe
use m
type(container), allocatable :: a_arr(:)
integer :: i
allocate(container :: a_arr(3))
a_arr(1)%ptr = b(1)
a_arr(2)%ptr = c(3)
a_arr(3)%ptr = c(1000)
do i=1,3
write(*,*) a_arr(i)%ptr%num
end do
end program mwe

Difference between Fortran's "abstract" and "normal" interfaces

I'm trying to understand the difference between abstract interfaces and "normal" interfaces. What makes an interface abstract? When is each one necessary?
Suppose the examples below
module abstract_type_mod
implicit none
type, abstract :: abstract_t
contains
procedure(abstract_foo), pass, deferred :: Foo
end type
interface
subroutine abstract_foo ( this, a, b )
import :: abstract_t
implicit none
class(abstract_t), intent(in) :: this
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
end module
module concrete_type_mod
use abstract_type_mod
implicit none
type, extends ( abstract_t ) :: concrete_t
contains
procedure, pass :: Foo
end type
contains
subroutine Foo ( this, a, b )
implicit none
class(concrete_t), intent(in) :: this
real, intent(in) :: a
real, intent(out) :: b
b = 2 * a
end subroutine
end module
module ifaces_mod
implicit none
interface
subroutine foo_sub ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
end module
module subs_mod
implicit none
contains
pure subroutine module_foo ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
b = 2 * a
end subroutine
end module
program test
use ifaces_mod
use subs_mod
use concrete_type_mod
implicit none
type(concrete_t) :: concrete
procedure(foo_sub) :: external_sub
procedure(foo_sub), pointer :: foo_ptr
real :: b
foo_ptr => external_sub
call foo_ptr ( 0.0, b )
print*, b
foo_ptr => module_foo
call foo_ptr ( 1.0, b )
print*, b
call concrete%Foo ( 1.0, b )
print*, b
end program
pure subroutine external_sub ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
b = a + 5
end subroutine
The output is
5.000000
2.000000
2.000000
I haven't used abstract interfaces here. At least I think I havent? I've been doing this for a while and I've never used the abstract "qualifier" on interfaces. It seems that I haven't found a case where using abstract interfaces is required.
Could someone enlighten me here?
PS: Compiler Intel Visual Fortran Composer XE 2013 SP1 Update 3.
Edit:
Quoting Metcalf, Reid and Cohen in Modern Fortran Explained:
In Fortran 95, to declare a dummy or external procedure with an
explicit interface, one needs to use an interface block. This is fine
for a single procedure, but is somewhat verbose for declaring several
procedures that have the same interface (apart from the procedure
names). Furthermore, in Fortran 2003, there are several situations
where this becomes impossible (procedure pointer components or
abstract-type bound procedures).
So, is my compiler in error for accepting the code below and also the one with abstract type above?
module ifaces_mod
implicit none
interface
subroutine foo_sub ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
end module
module my_type_mod
use ifaces_mod
implicit none
type my_type_t
procedure(foo_sub), nopass, pointer :: Foo => null()
end type
end module
In both cases, I'd say that I actually have declared abstract interfaces without using the abstract keyword. I think my confusion has roots on the fact that the compiler is accepting code like this.
The "normal" interfaces — known by the standard as specific interface blocks (as you use in the title of the question) — are just normal interface blocks for some procedure. Therefore:
interface
subroutine foo_sub
end subroutine
end interface
means that there exists an actual (external) subroutine named foo_sub and it conforms to the specified interface.
An abstract interface
abstract interface
subroutine foo_sub_abs
end subroutine
end interface
just specifies how some procedure may look like, but the name is the name of the interface, not of any actual procedure. It can be used for a procedure pointers
procedure(foo_sub_abs), pointer :: p
or for a dummy arguments
subroutine bar(f)
procedure(foo_sub_abs) :: f
and it means that the actual procedure to which p will point or which is passed as f conforms to the abstract interface.
Note that you are allowed to use some existing procedure instead of an abstract interface in both two former examples. It just needs to have explicit interface available in the scope (typically it is in the same module, or in a module which is used).
As far as I know (but see #IanH's comment below) the compiler is allowed to refuse your code:
interface
subroutine abstract_foo ( this, a, b )
import :: abstract_t
implicit none
class(abstract_t), intent(in) :: this
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
because there exists no actual procedure named abstract_foo. Some compilers do not diagnose this, but they could.
Quite unrelated are generic interfaces. You can recognize them, because there is a name of a generic procedure after the word interface
interface generic_sub
procedure sub1
subroutine sub2(...)
end subroutine
end interface
Here sub1 and sub2 both exist, sub1 is already known and has already explicit interface available, sub2 is external and looks as the interface specifies, and both are specific procedure of the generic generic_sub. This is quite a different usage.
You then call
call generic_sub(...)
and according to the arguments you pass, the compiler chooses which specific procedure is called, if it is sub1, or sub2.
I would stress that these can be split into sparate interface blocks with the same name declared at different locations. You can add a specific procedure into an existing generic procedure this way.

Fortran Assignment operator Interface in derived data type

I have the following code:
Module Hello
Implicit None
Type, Public :: TestOne
Private
Integer :: One, Two, Three
contains
Procedure, Pass, Public :: Set => SetSub
End type TestOne
Private :: SetSub
Interface Assignment(=)
Module Procedure SubgetValue
End Interface Assignment(=)
contains
Subroutine SetSub(this)
Implicit none
Class(TestOne), Intent(InOut) :: this
this%one=1
this%two=2
this%three=3
End Subroutine SetSub
Subroutine SubGetValue(ISOut,TSIn)
Implicit None
Integer, Intent(Out) :: ISOut
Class(TestOne), Intent(In) :: TSIn
ISOut=TSIn%one
End Subroutine SubGetValue
End Module Hello
Program Test
use Hello
Implicit None
Type(TestOne) :: TSTest
Integer :: b
call TSTest%Set()
b=TSTest
write(*,*) b
End Program Test
In this version, I can access only "TSTest%One" via "=".
The question is how I can create an interface assignment such that I can access "TSTest%one", "TSTest%two" or "TSTest%three". If "One", "Two" and "Three" were not private, that would be trivial. However, the goal is to keep them private and access them via the interface assignment. Any additional module procedure for accessing "Two" or "Three" would have the same dummy arguments resulting in a compile time error.
However, another way to solve that issue would be a "setter"/"getter" routine, but I have read somewhere on the web that accessing varialbe via assignments is much faster than via a "getter" routine.
Any suggestions.
Thanks
Your defined assignment routine has the same overhead as a "getter" - because that's what it is.
If (when) compiler inter-procedural optimisation is up to scratch, there shouldn't be any additional overhead, particularly in the case where the TSTest object is not polymorphic.
Prior to your edit...
Beyond any obvious single candidate for extraction by the mixed type assignment, my preferred approach for this is to have separate bindings to access each component.
TYPE, PUBLIC :: TestOne
PRIVATE
INTEGER :: One, Two, Three
CONTAINS
PROCEDURE :: GetOne
PROCEDURE :: GetTwo
PROCEDURE :: GetThree
...
FUNCTION GetOne(this)
CLASS(TestOne), INTENT(IN) :: this
INTEGER :: GetOne
GetOne = this%One
END FUNCTION GetOne
...
b = TSTTest%GetTwo()
If I'm then feeling creative, I may also add some generic type bindings for unary "access" operators to the type:
TYPE, PUBLIC :: TestOne
PRIVATE
INTEGER :: One, Two, Three
CONTAINS
PROCEDURE :: GetOne
...
GENERIC :: OPERATOR(.TheOneOutOf.) => GetOne
...
b = .TheOneOutOf. TSTTest
though sometimes this creativity has just led to me becoming overly familiar with my compiler vendor's support channels.
(Consider making the defined assignment type bound.)