From: Colin Watters on


"Colin Watters" <boss(a)qomputing.com> wrote in message
news:hm1av4$ckb$1(a)news.eternal-september.org...
> Example, tweaked:
>
>
> Program test_Present
> real x,y
> real z(20)
> ...................
> call myPresent(x,y)
> end program test_Present
>
> ==========================
> Subroutine myPresent (A,B,C)
> real A,B
> real, optional :: C(20)
> ..................
> if (present(C)) then
> do something that uses C
> else
> do something that doesn't use C
> end if
> return
> end subroutine myPresent
>
>
....actually it's not that simple, coz myPresent needs an "explicit
interface". So let's have another go.

In this example there are a number of ways to make the interface explicit.
Easiest is:


Program test_Present

real x,y
real z(20)
...................
call myPresent(x,y)

stop 'finished'.

CONTAINS

==========================
Subroutine myPresent (A,B,C)
real A,B
real, optional :: C(20)
..................
if (present(C)) then
do something that uses C
else
do something that doesn't use C
end if
return
end subroutine myPresent

end program test_Present

Here, the "explicit interface" exists because myPresent is an Internal (or
Contained) Procedure of test_present. But this is not useful if you
actually want to call mpPresent from a lot of other routines in separate
files, in which case the more general method is to have myPresent in a
separate module, which may also (but need not) reside in a separate file,
thus:

.... Contents of file myPresent.f90:

Module myPresent_mod
implicit none
contains
Subroutine myPresent (A,B,C)
real A,B
real, optional :: C(20)
..................
if (present(C)) then
do something that uses C
else
do something that doesn't use C
end if
return
end subroutine myPresent
end module myPresent_mod

.... Contents of test_Present.f90:

Program test_Present
USE myPresent_mod, only: my_present
real x,y
real z(20)
...................
call myPresent(x,y)

stop 'finished'.

end program test_present


Finally, there is a third way, an "Interface Declaration". However there
are some problems with this so I don't reccommend it, and I won't show you
how to do it. I mention it only for sake of giving a complete answer, and
because you are bound to come across it soon anyway. (Alas many people
think an Interface Declatation is the only way to achieve an Explicit
interface, which is not so: the 2 examples above are MUCH better.)

--
Qolin

Email: my qname at domain dot com
Domain: qomputing


From: Colin Watters on

"Richard Maine" <nospam(a)see.signature> wrote in message
news:1jed7a7.7m34v51m23smiN%nospam(a)see.signature...
> Colin Watters <boss(a)qomputing.com> wrote:
>
>> Example, tweaked:
> [elided]
>
> Forgets about the explicit interface requirement.
>

....Sigh. Engage Brain Before Hit SEND !!! see my other post.

--
Qolin

Email: my qname at domain dot com
Domain: qomputing


From: robin on
"glen herrmannsfeldt" <gah(a)ugcs.caltech.edu> wrote in message news:hlv6ao$7d7$1(a)naig.caltech.edu...

| Note that many fast sort routines are not stable. That is,
| sorting in Y may not keep the elements as previously sorted
| in the same order.

"Stable" means that elements that are equal may not
be kept in the original order.

That it not a problem then each record has only one value,
as it's impossible to tell the difference between those records.

Lack of stability may become a problem when there are
other fields associated with each record, in which case
records having the same keys may be in a different
order after the sort.|


From: monir on
On Feb 23, 2:58 pm, "Colin Watters" <b...(a)qomputing.com> wrote:
> "Colin Watters" <b...(a)qomputing.com> wrote:

>...there are a number of ways to make the interface explicit.
>Easiest is:
>...............
>Here the "explicit interface" exists because myPresent is an Internal
>or Contained)Procedure of test_present.
>...if you actually want to call myPresent from a lot of other routines
>in separate files, in which case the more general method is to have
>myPresent in a separate module...

Your two explicit interface procedures (one with Contains and the
other with Module+Contains) work perfectly and as desired (Test 1 &
Test 2 below).
The apparent restriction in the Optional arg (see NOTE below) is not a
serious one, since one can always from the start rearrange the
argument list in "groups" and in a particular order to suit the
anticipated applications of the routine.
(see for example the call in Item 2 of my OP.)
The serious work now starts in incorporating the procedure into the
actual code!

Thank you ALL, Colin Watters and all responders, for the thoughtful
replies and tremendous help in resolving the issue.

Kind regards.
Monir


===========Test 1 =======================
Program Test1_Optional_Present

c NOTE: As mentioned in Item 4 of my OP:
c "... some programming languages/compilers allow the use of
"Optional"
c argument ... but once an argument is made Optional, all the
arguments
c that follow must be made Optional as well."
!This restriction appears to be also true in Fortran.
!In the following Tests, I don't see how one can make "b" for example
Optional
!while "c" is not and expects Sub myPresent(res,a,b,c) to know which
is which.

implicit none
real sum, x, y, z

x = 1.0
y = 3.0
z = 6.0

Call myPresent(sum,x,y,z) !include optional argument z
print *,' Sum1 = ', sum
Call myPresent(sum,x,y) !leave out optional arg z
PRINT *,' Sum2 = ', sum
stop 'finished'
CONTAINS
Subroutine myPresent(res,a,b,c)
implicit none
real res,a,b
real, Optional :: c

if (Present(c)) then
res = a+b+c
else
res = a+b
end if
end subroutine myPresent
End Program Test1_Optional_present

===========Test 2 =======================

Module myPresent_mod
implicit none
CONTAINS
Subroutine myPresent(res,a,b,c)
implicit none
real res,a,b
real, Optional :: c

if (Present(c)) then
res = a+b+c
else
res = a+b
end if
end subroutine myPresent
End Module myPresent_mod

Program Test2_Optional_Present
USE myPresent_mod, only: myPresent
implicit none
real sum, x, y, z

x = 1.0
y = 3.0
z = 6.0

Call myPresent(sum,x,y,z) !include optional argument z
print *,' Sum1 = ', sum
Call myPresent(sum,x,y) !leave out optional arg z
print*,' Sum2 = ', sum

stop 'finished'
End Program Test2_Optional_present
From: Richard Maine on
monir <monirg(a)mondenet.com> wrote:

> The apparent restriction in the Optional arg (see NOTE below)...
....
> c NOTE: As mentioned in Item 4 of my OP:
> c "... some programming languages/compilers allow the use of
> "Optional"
> c argument ... but once an argument is made Optional, all the
> arguments
> c that follow must be made Optional as well."
> !This restriction appears to be also true in Fortran.

No, there is no such restriction in Fortran. Just because you can't see
how something might be used doesn't necessarily mean that it isn't
allowed. It is much more reliable to actually read the restrictions
instead of trying to guess them. Guessing can sometimes work, but it
requires quite a lot of expertise in the language, and sometimes even
then one might guess the restrictions incorrectly. If you are
unfamilliar with major parts of the language, guessing doesn't work well
at all.

In this case, what you overlooked is the keyword form of argument
specification. Since optional arguments require an explicit interface,
that means that the keyword form will be alowed. (It also requires an
explicit interface).

It is often considered preferred style to put optional arguments at the
end of the argument list. I would tend to agree with that style
preference. But a style preference is not the sam ething as a language
requirement.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain