Re: Creation of binary operators "Dr. Alan Barnes" <[log in to unmask]> Wed, 21 Apr 1999 11:57:20 +0100 text/plain (103 lines) ```I couldn't see why you want to have Max and Min as binary operators as the attribute functions (Integer'Max etc.) seem adequate. But if you do, it would be better to overload other operators which don't normally have a meaning for numbers (eg "&"). I think the answers to your two questions are: > 1. Is it possible to generate user defined binary operators (in > Ada)? No, you can only overload existing operators. > 2. If not, then why not? I guess one reason for this is practical: it would require fundamental changes to the parsing routines in the compiler if completely new operator symbols with extra precedence levels were introduced in the language. A related issue arose a few weeks ago when I redefined "/" and "**" for modular numbers in a package of the form: GENERIC    TYPE Zed_N IS MOD <>; PACKAGE Mod_Pack IS    NotInvertible, Zero_To_Power_Zero, Modulus_Too_Large : EXCEPTION;    FUNCTION "**"(A : Zed_N; N : Integer) RETURN Zed_N;    -- returns A**N. When N < 0 and Inverse(A) does not exist    -- raises the exception NotInvertible    -- raises the exception Zero_To_Power_Zero if 0**0 is formed.    FUNCTION "/"(A, B : Zed_N) RETURN Zed_N;    -- returns A*Inverse(B) mod n if Inverse(B) exists    -- else raises the exception NotInvertible    FUNCTION Inverse(A : Zed_N) RETURN Zed_N;    -- returns the inverse of A mod n if it exists    -- else raises the exception NotInvertible    FUNCTION IsInvertible(A : Zed_N) RETURN Boolean;    -- returns True if A has an inverse mod n, otherwise returns False END Mod_Pack; If simply instantiate the package and USE it in a client    TYPE Z31 IS MOD 31;    PACKAGE Mod31 IS NEW Mod_Pack(Z31);    USE Mod31; then the definitions of Standard."/" and Standard."**" are not overridden and a program using "/" and "**" with arguments of type Z31 is ambiguous and will not compile (with gnat). Suprisingly the situation is different if the package is not generic: PACKAGE Mod31 IS    TYPE Z31 IS MOD 31;    -- rest of package unchanged (apart from renaming fo Zed_N) If you simply WITH and USE this package the program compiles but the new overloadings of "/" and "**" are ignored and the ones from Standard are used. To override the Standard definitions in the client in either case you can do    FUNCTION "/"(A, B : Z31) RETURN Z31 RENAMES Mod31."/";    FUNCTION "**"(A : Z31; N : Integer) RETURN Z31 RENAMES Mod31."**"; This seems rather messy, but I couldn't see a way of avoiding it. I guess the reason for the above is that you cannnot TACITLY change the meaning of a program with a USE which overrides operators in Standard. However it is not clear to me why the sitaution is different for generic and non-generic packages. Also if an operator from Standard is given a new overloading by a renaming declaration in a (non-generic) package declaration, then a client program which WITH's and USE's the package and attempts to use the overloaded operators is again ambiguous and will not compile. Again the reason for the different behaviour is not clear to me. Is this situation covered by the LRM? If so, where? Or is it a 'feature' in gnat?    Alan Barnes    Department of Computer Science and Applied Mathematics    Aston University    Aston Triangle    Birmingham B4 7ET    U. K.    Telephone: +44 121 359 3611 Ext. 4663    E-Mail: [log in to unmask] (JANET)    Fax: +44 121 333 6215 ```