J3/98-100 To: J3 From: William Clodius Subject: Multimethods and OOF Date: November 12, 1997 One aspect of polymorphism that is a potential source of controversy was revealed during recent discussions of the data subgroup. This aspect involves what are often known as multimethods. Multimethods can take two or more actual arguments of a polymorphic type. The most simple (and commonly occurring) example of multimethods are simple binary methods, which have only two arguments, both of the same polymorphic type. This paper will focus on simple binary methods as sufficient to illustrate the problems. It is considered likely that a solution to the binary method problem will provide strong guidance to the general solution. The current proposal for object oriented Fortran has polymorphism strongly tied to inheritence, with the resolution of method dispatch determined by the type of one of the arguments (single dispatch). The use of single dispatch causes no problems when only one of the arguments is of a polymorphic type. Problems can arise when more than one argument can be of a polymorphic type, because the proper method to be selected can, in principle, depend on all such arguments. There are a number of ways of addressing this problem most of which are not immediately relevant for Fortran. However, interested readers can refer to the paper of Bruce et. al. "On Binary Methods", (Ref. 1) A simple example of the type of problems multimethods can invoke is given below in pseudo-OOF code TYPE, EXTENSIBLE :: POINT1D ! Defines a polymorphic type REAL :: X END TYPE SUBROUTINE EXAMPLE(A, B) ! A binary method that calls another ! binary method TYPE(POINT1D) :: A ! Determines the dispatching object TYPE(POINT1D) :: B ! Has the type of A in some sense IF (A .EQ. B) THEN ! The equality operator is the ! simplest possible binary method WRITE (*,*) 'A and B are equal' ELSE WRITE (*,*) 'A and B are not equal' END IF END SUBROUTINE EXAMPLE TYPE, POINT2D, EXTENDS(POINT1D) REAL :: X END TYPE ! EXAMPLE is not overridden. The preceding code raises the following questions: 1. Should code such as SUBROUTINE EXAMPLE be allowed by the language for extensible types? If not what does that imply for the default equality operator? 2. If code such as SUBROUTINE EXAMPLE is allowed, what should be the default requirements on D for CALL EXAMPLE(C, D) when C and D are declared with polymorphic type POINT1D and and at runtime C has the specific type POINT2D, i.e., must D have the specific type POINT1D or POINT2D? (Note: Ada requires D to have the type POINT2D and it does not cause problems. I believe C++ and its relatives either forbid this syntax or require D to have type POINT1D. Other options are known to either be type unsafe (e.g., Eiffel's general covariance), or too complicated or inefficient for Fortran's user community (e.g., the multimethods of CLOS and Dylan.)) 3. Should the language provide a specific syntax for the constraint implied by the decision on question 2, i.e., should the statement TYPE(POINT1D) :: B in SUBROUTINE EXAMPLE above be written something like TYPE_OF(A) :: B ! other syntaxes might be MATCH(A) ! TYPE(==A), KIND(A) if B must have the same type as A, or FIXED(POINT1D) :: B ! or TYPE(POINT1D) if B must always have the TYPE(POINT1D). 4. Should the constraint appear in the definition of EXAMPLE, or in the procedures that call EXAMPLE, or both? 5. Should the language provide an explicit means of overriding the default implied by the decision on question 2? References 1. Kim Bruce, Luca Cardelli, Giuseppe Castagna, The Hopkins Objects Group, Gary T. Leavens, And Benjamin Pierce, "On Binary Methods," published in Theory and Practice of Object Oriented Systems, Vol. 1, No. 3, p. 221?, 1995. Also available at the web sites of both Kim Bruce and Luca Cardelli, http://www.cs.williams.edu/~kim/ and http://www.luca.demon.co.uk/.