From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,751584f55705ddb7 X-Google-Attributes: gid103376,public From: John G. Volan Subject: Re: Side-effect arithmetic again [was: Ada ... in embedded systems] Date: 1996/03/26 Message-ID: <4j7dcl$dfu@dayuc.dayton.saic.com> X-Deja-AN: 144137592 distribution: world references: <31499D21.1DA6@escmail.orl.mmc.com> <827432438.26126@assen.demon.co.uk> <4ivnr9$86o@dayuc.dayton.saic.com> content-type: text/plain; charset=ISO-8859-1 x-xxmessage-id: organization: Science Applications International Corp. (SAIC) mime-version: 1.0 newsgroups: comp.lang.ada Date: 1996-03-26T00:00:00+00:00 List-Id: Rober Dewar said: >John said > >"Horrors! This assumes that Standard.Integer subsumes all possible ranges >of 'Pos values for all discrete types (enumeration, integer, modular). >A very dubious assumption! What about Long_Long_Integer? The long-term >reusability of this package is problematic." > >Nope, not horrors at all. Increment should mean increment, not add, if >you want to add, please use the + operator which is just fine for >this purpose. Oh, for goodness sake, Robert, are you quibbling over terminology? Forget the identifiers I happened to choose, what do you think the C operators += and -= mean? Maybe I should have reserved the names "Increment" and "Decrement" as analogs for "++" and "--" only, and not overloaded them as analogs for "+=" and "-=" too. Perhaps I should have used "Increase" and "Decrease" for the latter instead, since clearly "Increment" and "Decrement" carry the connotation of adding/subtracting an "incremental" (i.e., "small") amount. >I think it actively HELPS maintainability that increment accepts only >small positive values. Hardly. The trouble with Robert Eachus's version, e.g.: > type Item is (<>); ... > procedure Increment (This : in out Item; By: in Positive) is > begin > This := Item'Val(Item'Pos(This) + By); > end Increment; is that it doesn't just limit the "By" parameter to Standard.Positive, it also limits the "This" parameter to possibly a relatively small range of the Item type. But this is not explicit -- the user will discover it only by accident, when the "This" parameter happens to have a position number beyond the range of Standard.Integer, so that the call to Item'Pos blows up with Constraint_Error. Perhaps if Robert Eachus wanted to make this limitation more explicit, he should have done: generic type Item is (<>); package Discrete_Arithmetic is subtype Addable is Item range Item'Val (Integer'Max (Integer'First, Item'Pos(Item'First))) .. Item'Val (Integer'Min (Integer'Last, Item'Pos(Item'Last))); procedure Increase (This : in out Addable; By : in Positive); procedure Decrease (This : in out Addable; By : in Positive); ... end Discrete_Arithmetic; Now _that_ would have been "truth in advertising." But this is silly. IMHO, Robert Eachus goes too far in trying to use a _single_ generic to define analogs for += and -= universally for all _discrete_ types, including enumerated types. Being able to "increment" or "decrement" an enumerated value beyond its immediate successor or predecessor might be an interesting capability, but does it justify cluttering things up for the integer and modular cases? Considering the latter, why would anyone want to take a variable of their own particular integer or modular type and add/subtract a value of a _different_ integer type (namely Standard.Integer)? In Robert Dewar's terms, I think Robert Eachus' generalization is a _confusion_, rather than a _unification_, of the concept of numeric addition/subtraction. When designing generics, it is all too easy to fall into the trap of being _overly_ general. I believe it would be much, much simpler to just define the "Increase" and "Decrease" procedures in terms of an Item type for which "+" and "-" are already defined, and simply have done with it: procedure Increase (This : in out Item; By : in Item) is begin This := This + By; end Increase; procedure Decrease (This : in out Item; By : in Item) is begin This := This - By; end Decrease; That's not a problem if Item is a generic formal _numeric_ type -- i.e., one of the following that I had before: generic type Item is range <>; -- generic formal integer type package Integer_Arithmetic is ... generic type Item is mod <>; -- generic formal modular type package Modular_Arithmetic is ... generic type Item is digits <>; -- generic formal floating-point type package Floating_Arithmetic is ... generic type Item is delta <>; -- generic formal fixed-point type package Fixed_Arithmetic is ... With these in place, we could then do something like, oh, I dunno, say: type Simulation_Coordinate is range -10_000 .. +10_000; package Simulation_Coordinate_Arithmetic is new Integer_Arithmetic (Simulation_Coordinate); use Simulation_Coordinate_Arithmetic; ... for The_Simulation_Step in Simulation_Step loop ... for Target_Index in Target_Table'Range loop ... Increase (Target_Table(Target_Index).Current_X, By => Target_Table(Target_Index).Delta_X_Per_Step); Increase (Target_Table(Target_Index).Current_Y, By => Target_Table(Target_Index).Delta_Y_Per_Step); -- Note: deltas are _not_ necessarily positive for every -- target. Targets might be moving in any direction. ... end loop; ... end loop; IMHO, this is more readable, and less error-prone than, say: Target_Table(Target_Index).Current_Y := Target_Table(Target_Index).Current_X + Target_Table(Target_Index).Delta_Y_Per_Step; Whoops! Gosh, what I _really_ meant to say was: Target_Table(Target_Index).Current_Y := Target_Table(Target_Index).Current_Y + Target_Table(Target_Index).Delta_Y_Per_Step; ;-) >I also think that the extnsion of these operators, dubious in the first >place, to weird cases like mod is a disservice. I can put up with += in >C but I find the use of things like %= and ^= to be tortured syntax, >which I prefer NOT to import in any case. Nobody is advocating C's tortured syntax. All we're doing here is coming up with a (partial) analogy, in Ada, for the _semantics_ of these operations. There is absolutely no reason to suppose that the analogous Ada procedures would be "tortured" at all. (Note that I'm calling these a _partial_ analogy for C's op= functions. The Ada analogs I'm suggesting are _procedures_ with side effects, not _functions_ with side effects -- now _that_ would be a truly tortured concept). A procedure called "Modulo" that reduces a variable to its modulo after division, and a procedure called "Remainder" that reduces a variable to its remainder after division, seem to me to be just as understandable, and just as well justified (as far as that goes) as, say, "Increase", "Decrease", "Multiply", and "Divide". I could just as easily argue that it was "tortured syntax" to invent special infix operator functions for "mod" and "rem" in the first place. Why didn't the original designers of Ada simply do these as ordinary functions, or perhaps attribute functions? Well, whatever the reasons, the fact remains that they _do_ exist, and have become well accepted, and are considered analogous to + - * / . So, _if_, I say, _if_ we're going to supply side-effect-procedure versions for + - * /, then why not, by analogy, do the same for mod and rem? >I still think the whole business is a tempest in a teapot, and do not think >that the use of any of these packages helps in reading, maintaining, or >even writing code. Well, you know, Robert, I'm half inclined to agree with you (I've done a lot of declare-blocks-with-renaming-declarations in my time), but I'm not prepared to stand on my pulpit and preach to the vast unwashed mass of C and C++ programmers (and maybe COBOL programmers too) that their precious side-effect arithmetic operations are not fit for mortal ken. I'm not going to tell them that they can either accept "the One True Ada Way" or they can just march their little fannies right out of our congregation, thank you very much! I'd much rather tell them that, yes, they can get what they want out of Ada, if they really need it, and here's a safe and easy way to do it. I think it's much more prudent to take people like that and turn them _on_ to Ada _first_ -- and _then_ try to gently persuade them that one of their cherished idioms might not be so essential as they thought. Unless (heaven forfend!) that idiom might have some merit after all ... In an earlier post, Robert Dewar writes: >Only a true lover of verbosity could like increment(item) which is longer ^^^^^^^^^^^^^^^^^^^^^^^^^ (And to whom might you be referring, hmmm? :-) Would the immortal Professor Dewar engage in cheap shots? Nooooo...) >than either > >(a) the standard Ada form: item := item + 1; > >(b) the COBOL form (!) add 1 to item It's pointless to compare this with the COBOL form, since we're talking about what's possible within the syntax of Ada. But as for Ada syntax, hmmm, let's see. It looks like Increment (Reasonably_Readable_Variable); has a cost of 1*N+13 keystrokes (where N is the length of the variable name), whereas Reasonably_Readable_Variable := Reasonably_Readable_Variable + 1; has a cost of 2*N+9 keystrokes. First of all, we _all_ know that the whole point of programming is _keystroke conservation_, yes indeedee! I know _I_ for one am _not_ gonna risk carpal tunnel typing in 13 keystrokes when I can get by with just 9, by gum! And of course, _everyone_ would agree that the constant term (13 vs 9) is _by far_ more important than the linear term (1*N vs 2*N). So _of course_ the first version is _always_ going to be longer than the second version. Mm-hmm. Yup. So it's _self evident_ that only a true lover of verbosity would prefer the first version over the second. Mm-hmm. Yup. (For the sarcasm impaired: :-/ There is a difference between gratuitous verbosity and necessary thoroughness. There is also such a thing as gratuitous brevity. I object to abbreviations such as "Inc" and "Dec" on the grounds that you would never use them in conversation, nor would you write them in English prose. They are too easily confused with "Ink" and "Inc." and "Deck" and "Deque". To me, the extra 6 characters needed to type in "Increment" and "Decrement" are a triviality, compared with the guarantee this gives me that my code will be understood by anyone with a working knowledge of the English language. By the way, it's always bothered me that there is really no polite way to pronounce 'Succ. :-) { But, u no, f u cn rd ths, u myt s wel uz C styl 4 ur prsnl ltrs! :-) } >Of course a discussion like this always generates lots of discussion. >Unlike abstract types, type extnsions, overriding, dispatching etc, >everyone at least fully understands the idea of incrementing a variable :-) Oh, sure they do, sure, sure. And, it seems, everyone fully understands this idea ... _differently_. :-) ------------------------------------------------------------------------ Internet.Usenet.Put_Signature ( Name => "John G. Volan", E_Mail => "John_Volan@dayton.saic.com", Favorite_Slogan => "Ada95: The *FIRST* International-Standard OOPL", Humorous_Disclaimer => "These opinions are undefined by SAIC, so" & "any use would be erroneous ... or is that a bounded error now?" ); ------------------------------------------------------------------------