From: Walt Brainerd on
James Giles wrote:
> Walt Brainerd wrote:
>
>>James Giles wrote:
>
> ...
>
>>>Most things about module use issues are not much different
>>>than IMPLICIT NONE. All the arguments against the ONLY
>>>clause sound very much like the arguments against IMPLICIT
>>>NONE earlier on.
>>>
>>
>>I agree in general, but when I tried to force myself
>>to do it, one of the first examples was a substantial
>>module with new types and *many* operator and assignment
>>extensions. I found listing them much more painful than
>>just listing a bunch of variable names.
>
>
> You are using *all* those operators and assignments
> in each local context? You must have some very busy
> code.
>
The particular example is using a module that defines
a big integer data type.

I have a hard time imagining many lines of code that
do integer arithmetic that don't use add, subtract,
multiply, divide, sqrt, assignment, compare (there's
six right there) operations, but maybe your imagination
is better than mine.

--
Walt Brainerd +1-877-355-6640 (voice & fax)
The Fortran Company +1-520-760-1397 (outside USA)
6025 N. Wilmot Road walt(a)fortran.com
Tucson, AZ 85750 USA http://www.fortran.com
From: James Giles on
Walt Brainerd wrote:
> James Giles wrote:
....
>> You are using *all* those operators and assignments
>> in each local context? You must have some very busy
>> code.
>>
> The particular example is using a module that defines
> a big integer data type.
>
> I have a hard time imagining many lines of code that
> do integer arithmetic that don't use add, subtract,
> multiply, divide, sqrt, assignment, compare (there's
> six right there) operations, but maybe your imagination
> is better than mine.

Well, I guess so. Most uses of big-integers are for an
expression or two, maybe a few lines even, to accomplish
things beyond the ability of the intrinsic INTEGER (or
even REAL) type(s). This small amount of code may
actually use only, say, add, divide, and assignment (to
compute the average of a large array of integers without
the risk of overflow, and without losing precision like
you would if you use REAL intermediates).

To be sure, you are (I suspect deliberately) addressing one
of the places where the ONLY clause is least intuitive. When
you define a new numeric type, people expect most of the
normal arithmetic operators as an "intrinsic" part of that
new type. After all, that's what really makes it numeric,
isn't it? However, that is an anomalous property that only
numeric types have. What other whole category of new
data types has, inherently in the minds of users, a whole
set of operations they expect to see? Differently implemented
Sets? Maybe. But what do those operators look like?

So, maybe (only maybe) the policy of always having an
ONLY clause might be relaxed for modules that define
a new numeric type (and only one or more numeric types
and their "intrinsic" operations - nothing else should be
in there). But before we abandon a useful policy, maybe
we should examine what makes importing a new numeric
type so onerous.

Well, operators express very clearly the operations of
arithmetic by long-standing convention and they're *short*.
In spite of their brevity, they aren't usually so bad as to
be terse (possibly just because people try not to confuse
themselves with them and almost intuitively avoid situations
that might do that: also because of long-standing convention?).
Even though one of their major properties is brevity, in order
to import them with an ONLY clause Fortran makes you pair
them - individually - with one of the longest keywords in the
language.

So first let's address the emphasized word in the last sentence.
Suppose the syntax of Fortran's ONLY clause were modified
so that operators were not *individually* required to be
specified with the OPERATOR keyword (everywhere else
in the language, OPERATOR still applies to one at a time):

USE my_big_ints, ONLY: big_int_T, & ! the data type itself
assignment(=), modulo, sqrt, & ! some functions and the assign
operator (+, -, *, /, <, <=, ==, /=, >=, >) ! the operators

(I'm writing this with a proportional font. Otherwise I'd have
these line up better.)

This is already a lot better. And again, if your code doesn't
actually use all those operatons, maybe they should be left
out of the ONLY list. Having the ONLY is informative.
I wouldn't have expected a defined assignment, most new
types use default assignment (but Walt mentioned it, so there
it is). I wouldn't have expected a square root function
(intrinsic INTEGERs don't have one). I put in modulo
(because that's one I *would* very often use with big integers)
even though Walt didn't mention it. And I put in all the relational
operators even though Walt mentioned relationals in the singular.

Having the ONLY list is useful in another way: it will remind
you when some types don't have some of the above operations.
Quaternions are numeric, but don't have relationals (other than
== and /=) and don't have modulo. Rationals are numeric but
definitely don't have SQRT. On the other hand, rationals will
probably have some new inquiry functions and maybe a different
constructor than the default - it's useful to have a local verification
of what these are called.

Are there other possible changes to improve things? Almost
certainly. Suppose you name the property that a data type
has a certain set of operations defined on it and permit a
type name that you're importing to be qualified with that
property name. So, you might write:

USE my_big_ints, ONLY: (numeric, ordered) -> big_int_T, &
assignment(=), modulo, sqrt

The NUMERIC qualification says that +, -, *, and / are defined
on the data type (and to look in the MODULE for them). And the
ORDERED qualification says that <, <=, ==, /=, >=, and > are
defined on the data type. So, you no longer have to explicitly
list these. You could permit the user to define his own property
names and have them as qualifiers. So, someone might define
the name TRANSCENDENTAL to mean that the type is numeric
(so you won't have to separately mention that), and that, in addition,
the trig functions, exponential functions, SQRT, and a few others
were all defined for each new type with that name as it's qualifier.

Lots of things are possible. I favor sticking with the "always
have an ONLY clause" policy and pressuring the committee for
improved features. That way we don't end up with legacy code
from this era that confuses users of the next.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


From: glen herrmannsfeldt on
James Giles <jamesgiles(a)worldnet.att.net> wrote:

> To be sure, you are (I suspect deliberately) addressing one
> of the places where the ONLY clause is least intuitive. When
> you define a new numeric type, people expect most of the
> normal arithmetic operators as an "intrinsic" part of that
> new type. After all, that's what really makes it numeric,
> isn't it?

Java specifically didn't include operator overloading because
people might use operators for non-intuitive functions,
especially numerical operators for non-numerical operations.

Then they used + for the string concatenation operator...

-- glen
From: James Giles on
glen herrmannsfeldt wrote:
> James Giles <jamesgiles(a)worldnet.att.net> wrote:
>
>> To be sure, you are (I suspect deliberately) addressing one
>> of the places where the ONLY clause is least intuitive. When
>> you define a new numeric type, people expect most of the
>> normal arithmetic operators as an "intrinsic" part of that
>> new type. After all, that's what really makes it numeric,
>> isn't it?
>
> Java specifically didn't include operator overloading because
> people might use operators for non-intuitive functions,
> especially numerical operators for non-numerical operations.
>
> Then they used + for the string concatenation operator...

Well that is the other side of the coin. I tend to think though
that anyone that overloads numeric operators to do non-numeric
things deserves what (s)he gets and can pay me or some other
consultant to disentangle the mess later - or waste more of his (her)
own time on it. Languages that do so intrinsically should be
loudly and regularly criticized for it (and avoided if possible).

Language design is always about compromise. Is the risk of
abuse overwhelming or is the convenience of legitimate uses
worth it? Either way, the language itself should make careful
choices for intrinsic operators. I cringe at the thought of
having to write rational arithmetic as mult(add(I,sub(J,K)),II).
So I favor allowing operators to be overloaded. But, it's
not without misgivings. Defined operators I also support
but with even stronger misgivings. I don't think anything
would convince me that allowing users to define the precedence
of their defined operators was a good idea.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


From: John Harper on
In article <Gr3Sf.567858$qk4.49132(a)bgtnsc05-news.ops.worldnet.att.net>,
James Giles <jamesgiles(a)worldnet.att.net> wrote:
>
> Defined operators I also support
>but with even stronger misgivings. I don't think anything
>would convince me that allowing users to define the precedence
>of their defined operators was a good idea.

Having had that in Algol 68, and wanting to do 3-D vector analysis
in Fortran in which .DOT. and .CROSS. would have to be defined ops with
the same precedence as * (the usual maths convention), I disagree.

--
John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington, New Zealand
e-mail john.harper(a)vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045