Access a parameter from an interface (Fortran) - fortran

I am using a parameter to fix the precision of the used types.
This works fine until I try to use the same type within an interface. Consider this small example:
module Hello
implicit none
save
integer, parameter :: K = selected_real_kind(10)
contains
subroutine dosomething(fun)
real(K) :: foo
interface
function fun(bar)
real(K) :: bar
real(K) :: fun
end function fun
end interface
end subroutine
end module
Here, foo would be of the desired type, whereas the compiler (gfortran) complains for 'bar' and 'fun'.
The error is
Error: Parameter 'k' at (1) has not been declared or is a variable, which does
not reduce to a constant expression
Is there a way to get this working?
(For now, I am just writing selected_real_kind(10) everywhere but this is not elegant at all)
Thank you!

The easiest way is to add import inside the interface. It is somewhat of a misdesign that the definitions of the module are outside the scope of the interface. Plain import will import everything.
....
subroutine dosomething(fun)
real(K) :: foo
interface
function fun(bar)
import
real(K) :: bar
real(K) :: fun
end function fun
end interface
end subroutine
....
Also possible: import :: K

Related

How to avoid rewriting the same interface for a deferred type-bound procedure implemented in a submodule?

Consider the following code, which defines an abstract type foo with a deferred procedure sub, and a type foo2 which extends foo:
MODULE m
TYPE, ABSTRACT:: foo
CONTAINS
PROCEDURE(sub_int), DEFERRED:: sub
END TYPE
INTERFACE
SUBROUTINE sub_int(THIS, x)
IMPORT:: foo
CLASS(foo), INTENT(IN):: THIS
DOUBLE PRECISION, INTENT(INOUT):: x
END SUBROUTINE
END INTERFACE
TYPE, EXTENDS(foo):: foo2
CONTAINS
PROCEDURE:: sub
END TYPE
INTERFACE
MODULE SUBROUTINE sub(THIS, x)
CLASS(foo2), INTENT(IN):: THIS
DOUBLE PRECISION, INTENT(INOUT):: x
END SUBROUTINE
END INTERFACE
END MODULE
SUBMODULE (m) s
CONTAINS
MODULE PROCEDURE sub
x= x**2
END PROCEDURE
END SUBMODULE
Is there a way to avoid writing the second interface?
I understand that it is needed in order to declare sub as a module procedure (otherwise the implementation would need to be done in the module, and not in the submodule), but is this the only way to do it?
In other words, is it possible to implement the procedure sub for foo2 without rewriting the entire interface for it?
It is not possible. A separate module subprogram requires an interface block, either in its defining submodule or an ancestor of its defining submodule.
Whether a procedure happens to be nominated by one (or more!) bindings of one (or more!) types is totally irrelevant.

From module, use only some components of a derived data type

Consider this simple module:
module mod1
implicit none
type namespace
integer :: int1
real :: real1
endtype
type(namespace) :: namespace1
end module mod1
Now I want to import just int1 from this derived datastructure namspace1, so as to keep track of what variable came from where.
Following program give an error:
program tmp
use mod1, only: int1 => namespace1%int1
implicit none
print *, int1
end program tmp
I get the following error
Error: Syntax error in USE statement at (1)
Is there some way to only use requires components from a derived datatype? or I need to do use mod1, only: nm => namespace1 followed by nm%int1 only?
Components cannot be selectively USE'd into other scopes.
Components within a type can be made PRIVATE to the defining module and its descendants, but this prevents them from being accessed in all other program units.
Fortran derived types are not suitable as a namespace management prop.

Fortran Extended type overload procedure but use the parent procedure [duplicate]

This question already has answers here:
Modern Fortran: Calling an ancestor procedure from descendent
(1 answer)
A Fortran analog to python's super()?
(1 answer)
Closed 3 years ago.
I wonder if it's possible to have an extended derived type that overload a procedure but still manages to call the "parent" procedure.
Something like (won't work, infinite recursion)
module parent_class
implicit none
private
type,public,abstract :: parent
contains
procedure,pass(self) :: sub
end type
contains
subroutine sub(self)
class(parent),intent(inout) :: self
! Do something here
write(*,*) 'in parent'
end subroutine
end module
module child_class
use parent_class, only: parent
implicit none
private
type,public,extends(parent) :: child
contains
procedure,pass(self) :: sub
end type
contains
subroutine sub(self)
class(child),intent(inout) :: self
! do something here
! ...
write(*,*) 'in child'
call self%sub() ! < this is the parent procedure
end subroutine
end module
program main
use child_class
implicit none
type(child) :: my_child
call my_child%sub()
end program
One solution is to make sub publicly available in parent_class module and use it in child_class module but I would like to know other solutions.

Fortran generic procedure error: may not be generic

I know that you can make generic procedures using abstract types, like in here:
fortran class declaration of dummy argument
But can I do the same sort of thing with the following code?
module proc_mod
public :: forced,ideal
interface forced; module procedure forced1; end interface
interface forced; module procedure forced2; end interface
contains
function forced1() result(forced)
implicit none
integer:: forced
forced = 1
end function
function forced2(t) result(forced)
implicit none
integer,intent(in) :: t
integer:: forced
forced = t
end function
function ideal() result(i)
implicit none
integer:: i
i = 2
end function
end module
program procTest
use proc_mod
implicit none
integer :: n
procedure(forced), pointer:: funPointer => NULL()
write(*,'(A)') "Please enter the type of vortex calculation you wish to use."
read(*,*) n
select case( n )
case( 1 ); funPointer => forced
case( 2 ); funPointer => ideal
case default; funPointer => ideal
end select
write(*,'(A,I3)') "You chose function: ", funPointer()
stop
end program
Right now I'm getting the error: funPointer may not be generic. I'm sure there's a way around it, but I'm unfamiliar with generic procedures.
No, you cannot make procedure pointer to a generic procedure. You also cannot pass generic procedures as dummy argument. You must always choose one specific function.
You should perhaps explain what is your intention, not just show some code and ask if it can be done differently. But anyway, take in mind that Fortran generics are used for compile time dispatch.

Is it possible to emulate mixed abstract/deferred and regular procedures in Fortran 2003?

When I try to mix both regular procedures and deferred procedures in one abstract type, gfortran balks at any invocation of the regular procedures:
" Error: Base object for type-bound procedure call at (1) is of ABSTRACT type 'tbody' "
type, abstract :: tBody
private
...
contains
procedure :: init => new_Body
...
procedure (contained), deferred :: PointIn
end type tBody
abstract interface
logical(LGT) pure function contained( Body, Point )
import :: tBody, tAffinePoint, LGT
class(tBody), intent(IN) :: Body
type(tAffinePoint), intent(IN) :: Point
end function contained
end interface
subroutine newCuboid( this, ... )
class(tCuboid), intent(OUT) :: this
...
call this%tBody%init( ... )
.... [gfortran halts here]
end subroutine newCuboid
Is there a way to arrange the type tBody so that I can have both abstract, deferred procedures and regular, instantiated procedures?
No.
There's a simple solution - replace call this%tBody%init(...) with call new_Body(...) (you may need to make appropriate accessibility changes).
Possibly feeble rationalisation - you are not resolving the procedure on the basis of the type of the reference (because that's hard coded), so don't use type bound procedure syntax.
Another solution in some cases is to split the type hierarchy further, so that the abstract type tBody has a non-abstract parent that hosts the initial implementation of the "not deferred" procedures.