From: Walt Brainerd on 15 Mar 2006 10:32 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 15 Mar 2006 19:12 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 15 Mar 2006 20:06 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 15 Mar 2006 20:46 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 15 Mar 2006 21:40
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 |