(j3.2006) Question regarding the ambiguity of procedures with polymorphic arguments

Jim Xia jimxia
Wed May 11 10:43:02 EDT 2011


My colleague's Lotus Note is playing a trick on his email:-)  Here is 
Rafik's previous email


Cheers,



Jim Xia

Compiler Testing, X10 & XLF
IBM Toronto Lab at 8200 Warden Ave,
Markham, On, L6G 1C7
905-413-3444


"


Hi

Sorry about the previous email.  My mail client decided to turn my
message into a binary attachment.  Here is the original message,
while I get the mail client issue resolved:

I think a simple example makes it clear why they're ambiguous:

type(point3d) :: a, b
... = a%add_vector(b)

The call above matches both add_vector_2d and add_vector_3d.  To make
the generic interface unambiguous, you can make "vector" in add_vector_2d
take type(point2d) instead of class(point2d).

Regards

Rafik
PS  XL Fortran flags the interface as ambiguous as well.



----- Forwarded by Rafik Zurob/Toronto/IBM on 11/05/2011 10:31 AM -----

From:
Rafik Zurob/Toronto/IBM
To:
fortran standards email list for J3 <j3 at j3-fortran.org>
Cc:
fortran standards email list for J3 <j3 at j3-fortran.org>, 
j3-bounces at j3-fortran.org
Date:
11/05/2011 10:05 AM
Subject:
Re: (j3.2006) Question regarding the ambiguity of procedures with 
polymorphic arguments


Hi

I think a simple example makes it clear why they're ambiguous:

type(point3d) :: a, b
... = a%add_vector(b)

The call above matches both add_vector_2d and add_vector_3d.  To make the 
generic interface unambiguous, you can make "vector" in add_vector_2d take 
type(point2d) instead of class(point2d)

Regards

Rafik
PS  XL Fortran flags the interface as ambiguous as well.




From:
Tobias Burnus <burnus at net-b.de>
To:
fortran standards email list for J3 <j3 at j3-fortran.org>
Date:
11/05/2011 09:32 AM
Subject:
(j3.2006) Question regarding the ambiguity of procedures with polymorphic 
arguments
Sent by:
j3-bounces at j3-fortran.org



Dear all,

I have a question whether the following procedures is ambiguous (as one 
compiler claims) or not (3 compilers and an older version of the first 
one accept it). After initially believing that the program is valid, I 
now think that it invalid. I would be happy if someone could confirm or 
disprove this.

In the following, the type point3d extends point2d. The interfaces of 
the two functions are:

   function add_vector_2d( point, vector )
     class(point2d), intent(in)  :: point
     class(point2d), intent(in)  :: vector

   function add_vector_3d( point, vector )
     class(point3d), intent(in)  :: point
     type(point3d), intent(in)   :: vector


The reason I believe that they are ambiguous is:

"Two dummy arguments are distinguishable if [...] neither is TKR
compatible with the other" (F2008, 12.4.3.4.5)

For an actual argument of the type "class(point3d),type(point3d)",
either function has the correct interface. More precisely,
class(point2d) is type compatible* with class(point3d) - and
class(point2d) is type compatible with type(point3d).

The crucial word is "neither": While add_vector_3d's dummies are
not type compatible to add_vector_2d - the reverse is not true.
Thus, the arguments are not distinguishable.

(* A polymorphic entity that is not an unlimited polymorphic entity is
type compatible with entities of the same declared type or any of its
extensions.", F2008, 4.3.1.3.)

Tobias

PS: Full example by Arjen Markus. Note, there is also a polymorphic 
assignment, which makes the program definitely invalid - but it does not 
matter regarding the question above.


module points2d3d     implicit none

     type point2d         real :: x, y     contains         procedure 
             :: print           => print_2d         procedure 
     :: add_vector      => add_vector_2d         generic, public 
:: operator(+)     => add_vector     end type point2d

     type, extends(point2d) :: point3d         real :: z     contains 
       procedure               :: print                     => print_3d 
         procedure               :: add_vector_3dversion      => 
add_vector_3d         generic, public         :: add_vector_new 
    => add_vector_3dversion         generic, public         :: 
operator(+) => add_vector_3dversion     end type point3d

contains subroutine print_2d( point )     class(point2d) :: point

     write(*,'(2f10.4)') point%x, point%y end subroutine print_2d

subroutine print_3d( point )     class(point3d) :: point

     write(*,'(3f10.4)') point%x, point%y, point%z end subroutine print_3d

function add_vector_2d( point, vector )     class(point2d), intent(in) 
  :: point     class(point2d), intent(in)  :: vector     type(point2d) 
             :: add_vector_2d

     add_vector_2d%x = point%x + vector%x     add_vector_2d%y = point%y 
+ vector%y

end function add_vector_2d

function add_vector_3d( point, vector )     class(point3d), intent(in) 
  :: point     type(point3d), intent(in)   :: vector

     type(point3d)               :: add_vector_3d

     add_vector_3d%point2d = point%point2d + vector%point2d 
add_vector_3d%z       = point%z       + vector%z

end function add_vector_3d

end module points2d3d

program random_walk

     use points2d3d   ! Both 2D and 3D points available

     type(point2d), target   :: point_2d, vector_2d     type(point3d), 
target   :: point_3d, vector_3d

     !     ! A variable of class point2d can point to point_2d but     ! 
also to point_3d     !     class(point2d), pointer :: point, vector

     integer        :: nsteps = 100     integer        :: i     integer 
        :: trial     real           :: deltt  = 0.1

     ! Select what type of point ...     point => point_2d     vector => 
vector_2d

     do trial = 1,2         if ( trial == 1 ) then 
write(*,*) 'Two-dimensional walk:'         else             write(*,*) 
'Three-dimensional walk:'         endif

         call random_vector( point )

         do i = 1,nsteps             call random_vector( vector )

             point = point + vector

             call print_point( point )         enddo

         ! Now let's take a 3D walk ...

         point => point_3d         vector => vector_3d

     enddo
end program random_walk

_______________________________________________
J3 mailing list
J3 at j3-fortran.org
http://j3-fortran.org/mailman/listinfo/j3



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://j3-fortran.org/pipermail/j3/attachments/20110511/ebdda564/attachment.html>



More information about the J3 mailing list