From: monir on
On Jul 31, 3:58 pm, Steven Correll <steven.corr...(a)gmail.com> wrote:
>

Steven;

That's neat!
I followed your example up to a point before losing it completely!
You clearly demonstrated the point! One can use same name for the
module and external procedures, but it is very very confusing !!
The g95 compiler (on Windows) was not confused however, and reproduced
your Linux results.

Will go through your example few more times.

Thanks again for your time and help.
Monir
From: Steven Correll on
On Aug 1, 7:48 pm, monir <mon...(a)rogers.com> wrote:
> On Jul 31, 3:58 pm, Steven Correll <steven.corr...(a)gmail.com> wrote:
>
>
>
> Steven;
>
> That's neat!
> I followed your example up to a point before losing it completely!
> You clearly demonstrated the point!  One can use same name for the
> module and external procedures, but it is very very confusing !!
> The g95 compiler (on Windows) was not confused however, and reproduced
> your Linux results.
>
> Will go through your example few more times.
>
> Thanks again for your time and help.
> Monir

I was hoping the example would help by showing side by side how to do
the same thing with module procedures on the one hand and external
procedures on the other. If you want to test your understanding of
which syntax pertains to each kind of procedure, you could try putting
an "e" in front of every "mysub*" identifier related to an external
procedure and an "m" in front of every "mysub*" identifier related to
a module procedure. If you do that correctly, the program should still
execute (and will be slightly more readable.)

Of course, when writing new code, the easiest approach is to use
module procedures always and external procedures never. Then there are
fewer rules to remember, and fewer opportunities to make mistakes.
From: monir on
On Aug 2, 12:07 pm, Steven Correll <steven.corr...(a)gmail.com> wrote:
> On Aug 1, 7:48 pm, monir <mon...(a)rogers.com> wrote:
> > On Jul 31, 3:58 pm, Steven Correll <steven.corr...(a)gmail.com> wrote:
>

Hi Steven;

1) In your example, putting:" ... an "e" in front of every "mysub*"
identifier related to an external
procedure and an "m" in front of every "mysub*" identifier related to
a module procedure..."
makes the example much clearer, and it works fine.

2) Your advice: " ... when writing new code, the easiest approach is
to use
module procedures always and external procedures never."
is well taken. In other words, leave the external procedure to the
experts.

3) Here's the Module procedure only, which works fine:

MODULE mymodule
implicit none
Interface mmysub
module procedure mysubi, mysubr
End Interface mmysub
Contains
Subroutine mysubi(arg)
integer :: arg(:)
print *, 'I am a module procedure', size(arg)
End Subroutine mysubi
Subroutine mysubr(arg)
real :: arg(:)
print *, 'I am a module procedure too', size(arg)
End Subroutine mysubr
END module mymodule

Program myprog
implicit none
integer :: myint(7)
real :: myreal(8)
call call_module_procedures()
Contains
Subroutine call_module_procedures()
USE mymodule
call mmysub(myint)
call mmysub(myreal)
End Subroutine call_module_procedures
END Program myprog

3) I hope you don't mind a couple of basic questions:
.....a) Why did you "USE mymodule" in the "Contains" section of the
main program instead of simply "USE mymodule" at the top of main ??
.....b) What happens if subroutine mysubr(arg) is Function myfunr(arg)
with myfunr and arg in DP ??
Keep in mind that dealing with External functions in F90 has been the
root cause of (my) confusion!

4) Once I know the answer (and understand it!), I'll try to use your
example as a template and modify my OP sample code accordingly.

Thanks again for your tremendous help and patience.
Monir
From: James Van Buskirk on
"monir" <monirg(a)rogers.com> wrote in message
news:9e697a9e-66d2-4a35-b776-da84aa9b5d4b(a)t2g2000yqe.googlegroups.com...

> 3) I hope you don't mind a couple of basic questions:
> ....a) Why did you "USE mymodule" in the "Contains" section of the
> main program instead of simply "USE mymodule" at the top of main ??

Actually placing the USE statement in PROGRAM MYPROG would have been
OK here because the interfaces for subroutines mysubr and mysubi
would have been accessible to internal subroutines
call_module_procedures and call_external_procedures by host
association. Host association, unlike USE association, can be
overridden, so subroutine call_external_procedures would still see
the external procedures, not the module procedures, and would invoke
them as in the present form of the example. In fact, if the USE
statement were present only in PROGRAM MYPROG it would be OK to place
the interface blocks for the external subroutines in both internal
subroutines. Overriding host association would lead to invoking the
external versions in subroutine call_external_procedures and even
though the interfaces to the module procedures would no longer be
available in subroutine call_module_procedures, since the procedures
are invoked generically there, the specific procedures that will be
invoked will in fact be the module procedures.

Thus I suggest that you move the USE statement from subroutine
call_module_procedures up into PROGRAM MYPROG and copy the interface
blocks from subroutine call_external_procedures into subroutine
call_module_procedures and the example should work identically to
the original version.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


From: Steven Correll on
On Aug 3, 12:17 pm, monir <mon...(a)rogers.com> wrote:
> 3)  I hope you don't mind a couple of basic questions:
> ....a) Why did you "USE mymodule" in the "Contains" section of the
> main program instead of simply "USE mymodule" at the top of main ??
> ....b) What happens if subroutine mysubr(arg) is Function myfunr(arg)
> with myfunr and arg in DP ??
> Keep in mind that dealing with External functions in F90 has been the
> root cause of (my) confusion!
>
> 4) Once I know the answer (and understand it!), I'll try to use your
> example as a template and modify my OP sample code accordingly.
>
> Thanks again for your tremendous help and patience.
> Monir

a) I wanted to keep the "module procedure" part of the program
separate from (and parallel with) the "external procedure" part so
that you could see which syntax was related to module procedures and
which syntax was related to external procedures. If I had put "use
mymodule" in the main program, it wouldn't have been clear that it was
needed by "call_module_procedures" but not needed by
"call_external_procedures". But if both "call_module_procedures" and
"call_external_procedures" wanted to call module procedures and not
external procedures, it would certainly make sense to put the "use"
statement in the main program, rather than repeating it in each of
those procedures.

b) I'm not sure I understand the question. I'll make a guess, and if
it's wrong, please ask again. My guess is that you want to see how the
same thing is accomplished with functions rather than subroutines, and
that you want the arguments and results of the functions to be type
"doubleprecision". If so, here it is. This time I've put an "m" in
front of each name that relates to module procedures, an "e" in front
of each name that relates to external procedures, an "r" after each
single-precision name, and a "d" after each double-precision name.
(There is one nit: it would be better for myprogf to obtain sp and dp
from mymodulef rather than redeclaring them itself, but I still wanted
to keep the module-related material, such as the "use" statement,
inside to "call_module_procedures" to highlight the contrast with
external procedures.)

module mymodulef
implicit none
integer, parameter :: sp = kind(1.0), dp = kind(1.0d0)
interface mmyfunc
module procedure mmyfuncr, mmyfuncd
end interface mmyfunc
contains
function mmyfuncr(arg)
real(sp) :: mmyfuncr, arg(:)
mmyfuncr = size(arg)
print *, 'I am a module procedure', mmyfuncr
end function mmyfuncr
function mmyfuncd(arg)
real(dp) :: mmyfuncd, arg(:)
mmyfuncd = size(arg)
print *, 'I am a module procedure too', mmyfuncd
end function mmyfuncd
end module mymodulef

function emyfuncr(arg)
implicit none
integer, parameter :: sp = kind(1.0)
real(sp) :: emyfuncr, arg(:)
emyfuncr = size(arg)
print *, 'I am an external procedure', emyfuncr
end function emyfuncr

function emyfuncd(arg)
implicit none
integer, parameter :: dp = kind(1.0d0)
real(dp) :: emyfuncd, arg(:)
emyfuncd = size(arg)
print *, 'I am an external procedure too', emyfuncd
end function emyfuncd

program myprogf
implicit none
integer, parameter :: sp = kind(1.0), dp = kind(1.0d0)
real(sp) :: mysp(7), spvar
real(dp) :: mydp(8), dpvar
call call_module_procedures()
call call_external_procedures()
contains
subroutine call_module_procedures()
use mymodulef
spvar = mmyfunc(mysp)
dpvar = mmyfunc(mydp)
print *, spvar, dpvar
end subroutine call_module_procedures
subroutine call_external_procedures()
interface emyfunc
function emyfuncr(arg)
implicit none
integer, parameter :: sp = kind(1.0)
real(sp) :: emyfuncr, arg(:)
end function emyfuncr
function emyfuncd(arg)
implicit none
integer, parameter :: dp = kind(1.0d0)
real(dp) :: emyfuncd, arg(:)
end function emyfuncd
end interface emyfunc
spvar = emyfunc(mysp)
dpvar = emyfunc(mydp)
print *, spvar, dpvar
end subroutine call_external_procedures
end program myprogf