Home > Archive > Fortran > November 2004 > Ambiguous interfaces
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Ambiguous interfaces
|
|
| Stig Kildegård Andersen 2004-11-04, 3:58 pm |
| There is probably a valid reason why the following generic interface is
ambiguous. I would appreciate if someone would explain it to me
Thank You in advance,
Stig Kildegård
module MyModule
implicit none
interface f
module procedure f1
module procedure f2
end interface
contains
real function f1(x)
real, dimension(1) :: x
f1 = x(1)
end function
real function f2(x)
real, dimension(2) :: x
f2 = x(1) + x(2)
end function
end module
program MyProgram
use MyModule
implicit none
write(*,*) f((/1.0/))
end program
| |
| David Ham 2004-11-04, 3:58 pm |
| On Thu, 4 Nov 2004 15:00:03 +0100
"Stig Kildeg=E5rd Andersen" <stigkildegaardatmaildotdk> wrote:
> There is probably a valid reason why the following generic interface
> is ambiguous. I would appreciate if someone would explain it to me
>=20
> Thank You in advance,
> Stig Kildeg=E5rd
Quoting from the Gospel according to M,R&C p93:
"one of them has more non-optional arguments of a particular data type,
kind type parameter, and rank ..."
So rank (number of dimensions) counts but shape (extent of dimensions)
doesn't. It has been pointed out here before that the generic ambiquity
rules are stricter than logically necessary: compilers are only required
to recognise a subset of the circumstances in which a person might be
able to inspect the source and disambiquate the cases.
David
>=20
>=20
>=20
> module MyModule
> implicit none
>=20
> interface f
> module procedure f1
> module procedure f2
> end interface
>=20
> contains
>=20
> real function f1(x)
> real, dimension(1) :: x
> f1 =3D x(1)
> end function
>=20
> real function f2(x)
> real, dimension(2) :: x
> f2 =3D x(1) + x(2)
> end function
>=20
> end module
>=20
> program MyProgram
> use MyModule
> implicit none
>=20
> write(*,*) f((/1.0/))
>=20
> end program=20
>=20
>=20
| |
| David Frank 2004-11-04, 3:58 pm |
| Your 2 functions arent sufficiently different to distinguish them,
(they both take a real array argument).
You could make F2 take a real(8) argument if you really need such an
animal.
| |
| Stig Kildegård Andersen 2004-11-04, 3:58 pm |
| > Quoting from the Gospel according to M,R&C p93:
Funny, first thing I did was to look there too :-)
> So rank (number of dimensions) counts but shape (extent of dimensions)
> doesn't. It has been pointed out here before that the generic ambiquity
> rules are stricter than logically necessary: compilers are only required
> to recognise a subset of the circumstances in which a person might be
> able to inspect the source and disambiquate the cases.
That is too bad. I should think that most compilers already have the tools
to recognise the different interfaces. If I removed the interface block from
the module and tried the following calls from the program I would expect the
compiler to check the interfaces explici interfaces to the subroutines and
to issue error messages:
write(*,*) f2((/1.0/))
write(*,*) f1((/1.0, 2.0/))
Mysteriously, though, CVF only issues an error message for the call to f2
but not for the call to f1. Perhaps this has something to do with the old
(mal?)practice of declaring arrays as having dimension(1) even though
indices larger than one are accesed following the declaration?
Kind Regards,
Stig Kildegård
| |
| Patrick Begou 2004-11-04, 3:58 pm |
| Stig Kildegård Andersen wrote:
> There is probably a valid reason why the following generic interface is
> ambiguous. I would appreciate if someone would explain it to me
>
> Thank You in advance,
> Stig Kildegård
>
>
As f1 and f2 have only one argument wich is a one dimension array,
genericity is not the best choice for this problem.
may be you could implement the f procedure testing the size of the array
with the SIZE intrinseque and call f1 or f2 as private functions in your
module.
>
> module MyModule
> implicit none
private f1
private f2
>
> contains
real function f(x)
implicit none
real, dimension(:) :: x
if (SIZE(x,1)) .EQ. 1 THEN
return f1(x)
else ! may be some additional test if size != 2
return f2(x)
ENDIF
end function
>
> real function f1(x)
> real, dimension(1) :: x
> f1 = x(1)
> end function
>
> real function f2(x)
> real, dimension(2) :: x
> f2 = x(1) + x(2)
> end function
>
> end module
>
> program MyProgram
> use MyModule
> implicit none
>
> write(*,*) f((/1.0/))
>
> end program
>
>
| |
| Richard E Maine 2004-11-04, 3:58 pm |
| [About generic resolution based on array size]
David Ham:
[color=darkred]
> That is too bad. I should think that most compilers already have the tools
> to recognise the different interfaces....
No they don't. You are missing something *VERY* fundamental about
generics. Generic resolution is done at compile time; that is really,
really important. Shape is not in general known at compile time;
sometimes, but not in general. Compilers don't have the predictive
tools necessary to do compile-time resolution of things that can
depend on input data.
And in case you answer that it could be applied to those cases where
the shape is known, realize that this would be completely different
from any thing else in generics. The conditions on generics guarantee
that there *CANNOT* be an ambiguous call. The conditions are all on
the set of specifics in the generic. There are no cases where a
possible ambiguity exists, but you are prohibited from having a call
that hits the ambiguity.
As to whether generics could have been specified that way... well
there are probably lots of arguments one could make on various sides,
but I don't think I'll even try to figure out what they would be (I
have vague ideas about some questions that might come up, but I
haven't thought them through and those might not be all the questions
either).
For now I'll just say that the design principle of not allowing
even the potential for an ambiguous call is so much throughout
the system of generics, that changing that would constitute a complete
rewrite of the whole area. Trying to just tack on an exception would
make for a horrible mess (and generics are already awfully complicated).
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| Stig Kildegård Andersen 2004-11-04, 3:58 pm |
| > if (SIZE(x,1)) .EQ. 1 THEN
> return f1(x)
> else ! may be some additional test if size != 2
> return f2(x)
> ENDIF
Actually, this is exactly what I wanted to avoid for this paricular
application. I was trying to push the selection of which function to call
where back to compile time, because otherwise the selections would have to
be made millions of times during program execution.
The actual situation where I wanted to do something like this would take
some time to explain. I was just curious as to why the approach a single
array with different fixed sizes is not allowed.
Kind Regards,
Stig Kildegård
| |
| Stig Kildegård Andersen 2004-11-04, 3:58 pm |
| >>> So rank (number of dimensions) counts but shape (extent of dimensions)
>
>
> No they don't. You are missing something *VERY* fundamental about
> generics. Generic resolution is done at compile time; that is really,
> really important. Shape is not in general known at compile time;
> sometimes, but not in general. Compilers don't have the predictive
> tools necessary to do compile-time resolution of things that can
> depend on input data.
> And in case you answer that it could be applied to those cases where
> the shape is known, realize that this would be completely different
> from any thing else in generics. The conditions on generics guarantee
> that there *CANNOT* be an ambiguous call. The conditions are all on
> the set of specifics in the generic. There are no cases where a
> possible ambiguity exists, but you are prohibited from having a call
> that hits the ambiguity.
I understand that generics are resolved at compile time. After having stared
at the example code with only fixed size arrays for a while I just forgot to
think of the cases where the sizes of the argument to a generic subprogram
are not known at compile time. Sorry about the stupid question - I will
blaim my cold for making me not figure this one out before asking here.
Thank You for making this clear even to me,
Stig Kildegård
| |
| David Frank 2004-11-04, 3:58 pm |
|
"Stig Kildegård Andersen" <stigkildegaardatmaildotdk> wrote in message
news:418a84e6$0$86913$edfadb0f@dread16.news.tele.dk...
>
> Actually, this is exactly what I wanted to avoid for this paricular
> application. I was trying to push the selection of which function to call
> where back to compile time, because otherwise the selections would have to
> be made millions of times during program execution.
>
> The actual situation where I wanted to do something like this would take
> some time to explain. I was just curious as to why the approach a single
> array with different fixed sizes is not allowed.
>
> Kind Regards,
> Stig Kildegård
>
You could always provide extra info to allow F2 to be different.
e.g. adding a integer arg.n that either can be left unused or perhaps used
to
good advantage f2 = sum(x(1:n))
| |
| Richard E Maine 2004-11-04, 3:58 pm |
| "Stig Kildegård Andersen" <stigkildegaardatmaildotdk> writes:
> Sorry about the stupid question
Not stupid at all.
While the usual "there are no stupid questions" is perhaps a bit of an
overstatement, one would have to go a *LOT* farther out than this one
to even be in sight of such a label. :-)
I could certainly see how people could miss this one. I might have
even seen someone ask it in a J3 meeting. Not sure, and I don't
recall the specific case, but it sure wouldn't surprise me.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
|
|
|
|
|