Is it currently possible to override the structure constructor in Fortran? I have seen proposed examples like this (such as in the Fortran 2003 spec):
module mymod
type mytype
integer :: x
! Other stuff
end type
interface mytype
module procedure init_mytype
end interface
contains
type(mytype) function init_mytype(i)
integer, intent(in) :: i
if(i > 0) then
init_mytype%x = 1
else
init_mytype%x = 2
end if
end function
end
program test
use mymod
type(mytype) :: x
x = mytype(0)
end program
This basically generates a heap of errors due to redundant variable names (e.g. Error: DERIVED attribute of 'mytype' conflicts with PROCEDURE attribute at (1)). A verbatim copy of the fortran 2003 example generates similar errors. I've tried this in gfortran 4.4, ifort 10.1 and 11.1 and they all produce the same errors.
My question: is this just an unimplemented feature of fortran 2003? Or am I implementing this incorrectly?
Edit: I've come across a bug report and an announced patch to gfortran regarding this issue. However, I've tried using a November build of gcc46 with no luck and similar errors.
Edit 2: The above code appears to work using Intel Fortran 12.1.0.
Is it currently possible to override the structure constructor in Fortran?
No. Anyway even using your approach is completely not about constructor overriding. The main reason is that structure constructor # OOP constructor. There is some similarity but this is just another idea.
You can not use your non-intrinsic function in initialization expression. You can use only constant, array or structure constructor, intrinsic functions, ... For more information take a look at 7.1.7 Initialization expression in Fortran 2003 draft.
Taking that fact into account I completely do not understand what is the real difference between
type(mytype) :: x
x = mytype(0)
and
type(mytype) :: x
x = init_mytype(0)
and what is the whole point of using INTERFACE block inside mymod MODULE.
Well, honestly speaking there is a difference, the huge one - the first way is misleading. This function is not the constructor (because there are no OOP constructors at all in Fortran), it is an initializer.
In mainstream OOP constructor is responsible for sequentially doing two things:
Memory allocation.
Member initialization.
Let's take a look at some examples of instantiating classes in different languages.
In Java:
MyType mt = new MyType(1);
a very important fact is hidden - the fact the object is actually a pointer to a varibale of a class type. The equivalent in C++ will be allocation on heap using:
MyType* mt = new MyType(1);
But in both languages one can see that two constructor duties are reflected even at syntax level. It consists of two parts: keyword new (allocation) and constructor name (initialization). In Objective-C syntax this fact is even more emphasized:
MyType* mt = [[MyType alloc] init:1];
Many times, however, you can see some other form of constructor invocation. In the case of allocation on stack C++ uses special (very poor) syntax construction
MyType mt(1);
which is actually so misleading that we can just not consider it.
In Python
mt = MyType(1)
both the fact the object is actually a pointer and the fact that allocation take place first are hidden (at syntax level). And this method is called ... __init__! O_O So misleading. ะก++ stack allocation fades in comparison with that one. =)
Anyway, the idea of having constructor in the language imply the ability to do allocation an initialization in one statement using some special kind of method. And if you think that this is "true OOP" way I have bad news for you. Even Smalltalk doesn't have constructors. It just a convention to have a new method on classes themselves (they are singleton objects of meta classes). The Factory Design Pattern is used in many other languages to achieve the same goal.
I read somewhere that concepts of modules in Fortran was inspired by Modula-2. And it seems for me that OOP features are inspired by Oberon-2. There is no constructors in Oberon-2 also. But there is of course pure allocation with predeclared procedure NEW (like ALLOCATE in Fortran, but ALLOCATE is statement). After allocation you can (should in practice) call some initializer, which is just an ordinary method. Nothing special there.
So you can use some sort of factories to initialize objects. It's what you actually did using modules instead of singleton objects. Or it's better to say that they (Java/C#/... programmers) use singleton objects methods instead of ordinary functions due to the lack of the later one (no modules - no way to have ordinary functions, only methods).
Also you can use type-bound SUBROUTINE instead.
MODULE mymod
TYPE mytype
PRIVATE
INTEGER :: x
CONTAINS
PROCEDURE, PASS :: init
END TYPE
CONTAINS
SUBROUTINE init(this, i)
CLASS(mytype), INTENT(OUT) :: this
INTEGER, INTENT(IN) :: i
IF(i > 0) THEN
this%x = 1
ELSE
this%x = 2
END IF
END SUBROUTINE init
END
PROGRAM test
USE mymod
TYPE(mytype) :: x
CALL x%init(1)
END PROGRAM
INTENT(OUT) for this arg of init SUBROUTINE seems to be fine. Because we expect this method to be called only once and right after allocation. Might be a good idea to control that this assumption will not be wrong. To add some boolean flag LOGICAL :: inited to mytype, check if it is .false. and set it to .true. upon first initialization, and do something else on attempt to re-initialization. I definitely remember some thread about it in Google Groups... I can not find it.
I consulted my copy of the Fortran 2008 standard. That does allow you to define a generic interface with the same name as a derived type. My compiler (Intel Fortran 11.1) won't compile the code though so I'm left suspecting (without a copy of the 2003 standard to hand) that this is an as-yet-unimplemented feature of the Fortran 2003 standard.
Besides that, there is an error in your program. Your function declaration:
type(mytype) function init_mytype
integer, intent(in) :: i
specifies the existence and intent of an argument which is not present in the function specification, which should perhaps be rewritten as:
type(mytype) function init_mytype(i)
Related
I use the Intel Visual Fortran. According to Chapmann's book, declaration of function type in the routine that calls it, is NECESSARY. But look at this piece of code,
module mod
implicit none
contains
function fcn ( i )
implicit none
integer :: fcn
integer, intent (in) :: i
fcn = i + 1
end function
end module
program prog
use mod
implicit none
print *, fcn ( 3 )
end program
It runs without that declaration in the calling routine (here prog) and actually when I define its type (I mean function type) in the program prog or any other unit, it bears this error,
error #6401: The attributes of this name conflict with those made accessible by a USE statement. [FCN] Source1.f90 15
What is my fault? or if I am right, How can it be justified?
You must be working with a very old copy of Chapman's book, or possibly misinterpreting what it says. Certainly a calling routine must know the type of a called function, and in Fortran-before-90 it was the programmer's responsibility to ensure that the calling function had that information.
However, since the 90 standard and the introduction of modules there are other, and better, ways to provide information about the called function to the calling routine. One of those ways is to put the called functions into a module and to use-associate the module. When your program follows this approach the compiler takes care of matters. This is precisely what your code has done and it is not only correct, it is a good approach, in line with modern Fortran practice.
association is Fortran-standard-speak for the way(s) in which names (such as fcn) become associated with entities, such as the function called fcn. use-association is the way implemented by writing use module in a program unit, thereby making all the names in module available to the unit which uses module. A simple use statement makes all the entities in the module known under their module-defined names. The use statement can be modified by an only clause, which means that only some module entities are made available. Individual module entities can be renamed in a use statement, thereby associating a different name with the module entity.
The error message you get if you include a (re-)declaration of the called function's type in the calling routine arises because the compiler will only permit one declaration of the called function's type.
I have an example code to test my understanding of overloading subroutines in Fortran 90. Here is my example:
module testint_mod
use constants
implicit none
private :: testvReal
private :: testvdpn
interface testv
module procedure testvReal
module procedure testvdpn
end interface
contains
subroutine testvReal(vR)
implicit none
real,intent(in) :: vR
write(*,*) vR
end subroutine
subroutine testvdpn(vdpn)
implicit none
real(kind=dpn),intent(in) :: vdpn
write(*,*) vdpn
end subroutine
end module testint_mod
program testintmain
use constants
use testint_mod
implicit none
real :: r
real(kind=dpn) :: d
integer :: i
interface testv
module procedure testvdpn
end interface
r = 2.0
d = dble(4.0)
call testv(r)
call testv(d)
end program testintmain
Where constants includes: integer,parameter dpn = selected_real_kind(14)
I get the error:
testint_main.F(10) : Error: Unresolved MODULE PROCEDURE specification name. [T
ESTVDPN]
module procedure testvdpn
-------------------------^
What am I doing wrong? Is overloading a function with selected_real_kind() not allowed?? I appreciate any help!
The specification in the main program of interface testv is problematic: the compiler is complaining that testvdpn cannot be resolved in the main program - and there is indeed nothing publicly accessible by that name. Further, testv is already accessible through use association of the module testint_mod in which it is defined. These three lines should be removed.
To answer the question asked later
Is overloading a function with selected_real_kind() not allowed?
If two procedures in a generic set are distinguished only by the kind type parameter of a real argument, then it doesn't matter should one (or more) come from a selected_real_kind result. However, care should be taken that the kind parameters really are distinct. It may be, for example, that the selected_real_kind(14) of the example returns the same kind as that of default real. This, and similar cases, would not be permitted. Although the compiler would surely moan.
Note also, for completeness, that for functions (rather than the subroutines of the question) disambiguation must be solely by the functions' arguments, not the results.
I've recently learnt about interface blocks when adding a function to my Fortran program. Everything works nice and neatly, but now I want to add a second function into the interface block.
Here is my interface block:
interface
function correctNeighLabel (A,i,j,k)
integer :: correctNeighLabel
integer, intent(in) :: i,j,k
integer,dimension(:,:,:),intent(inout) :: A
end function
function correctNeighArray (B,d,e,f)
character :: correctNeighArray
integer, intent(in) :: d,e,f
character, dimension(:,:,:),intent(inout) :: B
end function
end interface
It appears to me that this may not be the best option.
I've looked into subroutines, but I'm not very confident that it's the right solution. What I'm doing is relatively simple, and I need to pass arguments to the subroutine, but all the subroutines I've seen are a) complicated (i.e. too complicated for a function), and b) don't take arguments. They behave as though they manipulate variables without them being passed to them.
I've not really looked into modules properly, but from what I've seen it's not the right thing to use.
Which should I use when, and how do I go about it best?
Modules are always the right thing to use ;-)
If you have a very simple F90 program you can include functions and subroutines in the 'contains' block:
program simple
implicit none
integer :: x, y
x = ...
y = myfunc(x)
contains
function myfunc(x) result(y)
implicit none
integer, intent(in) :: x
integer :: y
...
end function myfunc
end program
Then the interface of the functions/subroutines will be known in the program and don't need to be defined in an interface block.
For more complex programs you should keep all functions/subroutines in modules and load them when required. So you don't need to define interfaces, either:
module mymod
implicit none
private
public :: myfunc
contains
function myfunc(x) result(y)
implicit none
integer, intent(in) :: x
integer :: y
...
end function myfunc
end module mymod
program advanced
use mymod, only: myfunc
implicit none
integer :: x, y
x = ...
y = myfunc(x)
end program advanced
The module and the program can (actually should) be in separate files, but the module has to be compiled before the actual program.
Seconding and extending what has already been said. It is better to put your procedures (subroutines and functions) into modules and "use" them because them you get automatic consistency checking of the interfaces with little effort. The other ways have drawbacks. If you define the interface with an interface block, then you have three things to maintain instead of two: the interface, the procedure itself and the call. If you make a change, then all three have to be modified to be consistent. If you use a module, only two have to be changed. A reason to use an interface block is if you don't have access to the source code (e.g., pre-compiled library) or the source code is in another language (e.g., you are using C code via the ISO C Binding).
The drawback to the "contains" approach is that contained procedures inherit all of the local variables of the parent program ... which is not very modular and can be very confusing if you forget this "feature".
alexurba's and MSB's answers are correct and useful as usual; let me just flesh out a little more detail on one point - if modules are the way to go (and they are), what are interfaces for at all?
For functions and subroutines in modules, anything that uses that module can automatically see those interfaces; the interfaces are generated when the module is compiled (that information, amongst other things, goes into the .mod file that's generated when you compile a module). So you don't need to write it yourself. Similarly, when you use a CONTAINed subprogram (which, agreeing with MSB, I find more confusing then helpful - they're much better thought of as closures or nested subroutines than external subroutines), the main program can already 'see' the interface explicitly and it doesn't need you to write it out for it.
Interface blocks are for when you can't do this - when the compiler isn't able to generate the explicit interface for you, or when you want something different than what is given. One example is when using C-Fortran interoperability in Fortran 2003. In that case, the Fortran code is linking against some C library (say) and has no way of generating a correct fortran interface to the C routine for you -- you have to do it yourself, by writing your own interface block.
Another example is when you do already know the interfaces to subroutines, but when you want to create a new interface to "hide" the subroutines behind - for instance, when you have one routine that operates on (say) integers, and one on reals, and you want to be able to call the same routine name on either and let the compiler sort it out based on the arguments. Such constructs are called generic routines and have been around since Fortran 90. In that case, you create an interface explicitly to this new generic routine, and list the interfaces to the "real" routines within that interface block.
I am trying to write a fortran program that uses green's functions to solve the heat equation. I am useing fortran 90 as opposed to 77 in part because I am under the impression that it is pretty much a replica of fortran 77 but with a few very helpful features thrown in. Though the main reason is for free form coding. I have some "useful" constants and variables in a module named "useful." I want to include those variables and constants in most of my programs, subroutines, functions, etc. I am just learning fortran. I have programed in perl, C++, java, matlab, and mathematica. I am finding it very difficult. I do not understand the difference between a program and a subroutine. I definitely have no clear idea of what a module is. I have spent the past 12 hours researching these terms and have yet to get concise distinctions and definitions. I get an assortment of samples that show how to declare these things, but very little that actually delineates what they are supposed to be used for.
I would really appreciate an explanation as to why my function, "x" is not able to "use" my "useful" module.
Also, a clarification of the previously mentioned fortran features would be really helpful.
module useful
integer, parameter :: N=2
double precision, parameter :: xmin=1, xmax=10, pi=3.1415926535898
double complex :: green(N,N), solution(N), k=(2.0,0.0)
end module useful
program main
use useful
!real*8 :: delta = 2**-7
do n1 = 1, N
do n2 = 1, N
green(n1,n2) = exp((0,1)*k*abs(x(n2)-x(n1)))/(4*pi*abs(x(n2)-x(n1)))
print *, x(n2)
end do
end do
end program main
function x(n1)
use useful
real :: n1, x
x=n1*(xmax-xmin)/N
end function x
Let start with some definitions.
Fortran programs are composed of program units. In so-called Fortran 2008 (current standard) there are five types of program units:
main program;
external subprogram;
module;
submodule;
block data program unit.
Let me concentrate your attention on the first three.
Main program
As standard claims it is
program unit that is not a subprogram,
module, submodule, or block data
program unit.
Not very useful definition. =) What you should know is that main program unit starts with keyword PROGRAM, it is the entry point of application and obviously a program shall consist of exactly one main program.
A program may also consist any number (including zero) of other kinds of program units.
External subprogram
A subprogram defines a procedure. There are two types of procedures and of course two types of subprograms to define them:
function subprograms to define functions;
subroutine subprograms to define subroutines.
A function subprogram is a subprogram that has a FUNCTION statement as its first statement.
A subroutine subprogram is a subprogram that has a SUBROUTINE statement as its first statement.
Also both procedures and subprograms differ in place of their appearance in program. You can use:
external subprograms to define external procedures;
internal subprograms to define internal procedures;
module subprograms to define module procedures.
external subprogram
subprogram that is not contained in a
main program, module, submodule, or
another subprogram
internal subprogram
subprogram that is contained in a main program or
another subprogram
module subprogram
subprogram that is contained in a module or submodule
but is not an internal subprogram
Module
It is just a definitions (type denitions, procedure denitions, etc.) container.
Now small example.
main.f90
! Main program unit.
PROGRAM main
USE foo
IMPLICIT NONE
CALL external_bar
CALL internal_bar
CALL module_bar
CONTAINS
! Internal subprogram defines internal procedure.
SUBROUTINE internal_bar
PRINT *, "inside internal procedure"
END SUBROUTINE internal_bar
END PROGRAM main
foo.f90
! Module program unit.
MODULE foo
IMPLICIT NONE
CONTAINS
! Module subprogram defines module procedure.
SUBROUTINE module_bar
PRINT *, "inside module procedure"
END SUBROUTINE module_bar
END MODULE foo
bar.f90
! External subprogram program unit.
! External subprogram defines external procedure.
SUBROUTINE external_bar
PRINT *, "inside external procedure"
END SUBROUTINE external_bar
A module is a higher level of organization than a subroutine or function.
Function "x" should be able to use the module useful. I think it more likely that program "main" is having difficulty correctly accessing "x". You would do better to also place function "x" into the module after a "contains" statement. In this case remove the "use useful" statement from "x". Then the program main would have full knowledge of the interface ... in Fortran nomenclature, the interface is explicit. This ensures that the passing of arguments is consistent.
It would help if you showed the error messages from the compiler.
Fortran 95/2003 is much more than FORTRAN 77 with a few extra useful features. The changes are much larger. Trying to learn it from the web is not a good idea. I suggest that you find a copy of the book "Fortran 95/2003 Explained" by Metcalf, Reid and Cohen.
I see two problems in your program.
The main subroutine doesn't know what x() is. Is it a real function, integer function, etc.? You can either add the following to your main program
real, external :: x
Or (as others suggested) move function X() into your module.
To do this, add a "contains" statement near the end of the module and
put the function between the "contains" and the "end module".
You have an argument mismatch. In the main program, N1 is explicitly declared as a real variable. In function X(), N1 is declared as a real. You need to fix this.
I would strongly suggest that you add "implicit none" statements to your main program,
module, and function. This will force you to implicitly type each variable and function.
One of the most troublesome issues with Fortran 90 is the lack of namespacing. In this previous question "How do you use Fortran 90 module data" from Pete, it has been discussed the main issue of USE behaving like a "from module import *" in Python: everything that is declared public in the module is imported as-is within the scope of the importing module. No prefixing. This makes very, very hard to understand, while reading some code, where a given identifier comes from, and if a given module is still used or not.
A possible solution, discussed in the question I linked above, is to use the ONLY keyword to both limit the imported identifiers and document where they come from, although this is very, very tedious when the module is very large. Keeping the module small, and always using USE : ONLY is a potentially good strategy to work around the lack of namespacing and qualifying prefixes in Fortran 9X.
Are there other (not necessarily better) workaround strategies? Does the Fortran 2k3 standard say anything regarding namespacing support?
For me this is the most irritating Fortran feature related to modules. The only solution is to add common prefix to procedures, variables, constants, etc. to avoid namespace collisions.
One can prefix all entities (all public entities seems to be more appropriate) right inside the module:
module constants
implicit none
real, parameter :: constants_pi = 3.14
real, parameter :: constants_e = 2.71828183
end module constants
Drawback is increased code verbosity inside the module. As an alternative one can use namespace-prefix wrapper module as suggested here, for example.
module constants_internal
implicit none
real, parameter :: pi = 3.14
real, parameter :: e = 2.71828183
end module constants_internal
module constants
use constants_internal, only: &
constants_pi => pi, &
constants_e => e
end module constants
The last is a small modification of what you, Stefano, suggested.
Even if we accept the situation with verbosity the fact that Fortran is not case-sensitive language force us to use the same separator (_) in entities names. And it will be really difficult to distinguish module name (as a prefix) from entity name until we do not use strong naming discipline, for example, module names are one word only.
Having several years of Fortran-only programming experience (I got into Python only a year ago), I was not aware of such concept as namespaces for a while. So I guess I learned to just keep track of everything imported, and as High Performance Mark said, use ONLY as much as you have time to do it (tedious).
Another way I can think of to emulate a namespace would be to declare everything within a module as a derived type component. Fortran won't let you name the module the same way as the namespace, but prefixing module_ to module name could be intuitive enough:
MODULE module_constants
IMPLICIT NONE
TYPE constants_namespace
REAL :: pi=3.14159
REAL :: e=2.71828
ENDTYPE
TYPE(constants_namespace) :: constants
ENDMODULE module_constants
PROGRAM namespaces
USE module_constants
IMPLICIT NONE
WRITE(*,*)constants%pi
WRITE(*,*)constants%e
ENDPROGRAM namespaces
Fortran 2003 has the new ASSOCIATE construct and don't forget the possibility of renaming USE- associated entities. But I don't think that either of these is much closer to providing a good emulation of namespaces than Fortran 90 already has, just (slightly) better workarounds.
Like some of the respondents to the question you link to, I tend to think that modules with very many identifiers should probably be split into smaller modules (or, wait for Fortran 2008 and use submodules) and these days I almost always specify an ONLY clause (with renames) for USE statements.
I can't say that I miss namespaces much, but then I've never had them really.
No one else summited this suggestion as an answer (though someone did in the comments of one answer). So I'm going to submit this in hopes it may help someone else.
You can emulate namespaces in the following way, and I would hope there would be no noticeable performance hit for doing so from the compiler (if so all object oriented Fortran programming is sufferings). I use this pattern in my production code. The only real downfall to me is the lack of derived type contained parameter variables, but I offer an option for that as well below.
Module Math_M
IMPLICIT NONE
PRIVATE
public :: Math
Type Math_T
real :: pi=3.14159
contains
procedure, nopass :: e => math_e
procedure :: calcAreaOfCircle => math_calcAreaOfCircle
End Type
Type(Math_T) :: Math
real, parameter :: m_e = 2.71828
contains
function math_e() result(e)
real :: e
e = m_e
end function math_e
function math_calcAreaOfCircle(this, r) result(a)
class(Math_T), intent(in) :: this
real, intent(in) :: r
real :: a
a = this%pi * r**2.0
end function math_calcAreaOfCircle
End Module Math_M
And the usage
Program Main
use Math_M
IMPLICIT NONE
print *, Math%pi
print *, Math%e()
print *, Math%calcAreaOfCircle(2.0)
End Program Main
Personally I prefer using $ over the _ for module variables, but not all compilers like that without compiler flags. Hopefully this helps someone in the future.