For Programmers: Free Programming Magazines  


Home > Archive > Fortran > March 2007 > Redefining intrinsic operators









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 Redefining intrinsic operators
FX

2007-03-21, 8:04 am

Hi all,

I'm trying to understand the subtelties of redefining intrinsic
operators. In particular, I'd like confirmation that the code below is
invalid, and that the reason is the right one:

module m1
interface operator(+)
module procedure f2
end interface
contains
function f2(a,b)
integer, intent(in) :: a(2)
integer, intent(in) :: b(3)
integer :: f2
f2 = 0
end function f2

end module m1

use m1
print *, (/1,1,5/) + (/2,2/)
end


I'd say it's invalid because of (12.3.2.1.1 of Fortran 2003):

"If the operator is an intrinsic-operator (R310), the number of
function arguments shall be consistent with the intrinsic uses of
that operator, and the types, kind type parameters, or ranks of the
dummy arguments shall differ from those required for the intrinsic
operation (7.1.2)."

Here, neither types nor kind type parameters nor ranks differ from the
intrinsic + operator, so it's not allowed. However, it seems a bit weird
since there's absolutely no way this can conflict (but the reason behind
this might be that it can't be decided "at compile-time", even though the
standard has no such concept).

Thanks for your insight in this matter.

--
FX
Michael Metcalf

2007-03-21, 7:05 pm


"FX" <coudert@alussinan.org> wrote in message
news:etra0n$1p08$1@nef.ens.fr...
> Hi all,
>
> I'm trying to understand the subtelties of redefining intrinsic
> operators. In particular, I'd like confirmation that the code below is
> invalid, and that the reason is the right one:
>
> module m1
> interface operator(+)
> module procedure f2
> end interface
> contains
> function f2(a,b)
> integer, intent(in) :: a(2)
> integer, intent(in) :: b(3)


I have f95 at hand. The first sentence of 12.3.2.1.1 says that "If OPERATOR
is specified in a generic specification [as above], all the procedures
specified in the interface block [f2] shall be functions that may be
referenced as defined operations... ." Your function f2 cannot be so
referenced, as neither of its two arguments is of defined tye. Hence, the
module is illegal.

Regards,

Mike Metcalf


Dick Hendrickson

2007-03-21, 7:05 pm

FX wrote:
> Hi all,
>
> I'm trying to understand the subtelties of redefining intrinsic
> operators. In particular, I'd like confirmation that the code below is
> invalid, and that the reason is the right one:
>
> module m1
> interface operator(+)
> module procedure f2
> end interface
> contains
> function f2(a,b)
> integer, intent(in) :: a(2)
> integer, intent(in) :: b(3)
> integer :: f2
> f2 = 0
> end function f2
>
> end module m1
>
> use m1
> print *, (/1,1,5/) + (/2,2/)
> end
>
>
> I'd say it's invalid because of (12.3.2.1.1 of Fortran 2003):
>
> "If the operator is an intrinsic-operator (R310), the number of
> function arguments shall be consistent with the intrinsic uses of
> that operator, and the types, kind type parameters, or ranks of the
> dummy arguments shall differ from those required for the intrinsic
> operation (7.1.2)."
>
> Here, neither types nor kind type parameters nor ranks differ from the
> intrinsic + operator, so it's not allowed. However, it seems a bit weird
> since there's absolutely no way this can conflict (but the reason behind
> this might be that it can't be decided "at compile-time", even though the
> standard has no such concept).
>
> Thanks for your insight in this matter.
>

I think there's two things going on here.

First, the design decision not to allow redefining intrinsic
operations. This was just a decision, probably based on not
letting people write completely unreadable programs, but basically
arbitrary. That's why something in the definition has to be different.
(But I bet you already knew that).

Second, the design decision not to allow generic resolution to
be a run-time decision. In your case, it's obvious what to do.
But for print *, array(I:J:K) + array(L:M:N)
there's no way to make the resolution at compile time. A related part
of this is that, by design, rank is also always a compile time thingo.
If overload resolution could depend on run-time values, then
so could rank. You merely need to have some of the possible overloads
return different rank results. In your case, depending on the values
of I..N, the result is either a scalar or an array.

There are several fairly artificial constraints in Fortran's generic
resolution rules. Many of the kind/rank/type/argument-ordering
rules could be relaxed. IMO, the committee just felt that things
were hard enough to understand and implement now, and that adding
more options, or relaxing rules, would just make it too hard
to implement, with little real gain for the "average" user. Just
a guess on my part.

Dick Hendrickson
Richard Maine

2007-03-21, 7:05 pm

FX <coudert@alussinan.org> wrote:

> print *, (/1,1,5/) + (/2,2/)


....where he tried to overlload + for this case.

Others have answered much, but let me add one unmentioned bit. You
appear to be trying to overload based on array size (not rank). You
can't do that, size not in general being known at compile time (see
Dick's comment - even tough special cases might be known, that would be
a big complication in ann already complicated area to handle such as a
special case).

There is an intrinsic elemental definition of + for integers. That
definition covers rank_1+rank1, so you can't overload another
rank_1+rank_1. The fact that your case differs in array size isn't
enough.


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







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com