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,c7ea1cb7a2beb2ee X-Google-Attributes: gid103376,public From: claveman@fern.com (Charles H. Sampson) Subject: Re: Disallowing Pre-Defined Operations Date: 2000/03/15 Message-ID: <8aoifb$49f$1@newpoisson.nosc.mil> X-Deja-AN: 597896766 Distribution: world References: <8a9eeg$qtv$1@newpoisson.nosc.mil> <8ababr$c3u$1@wanadoo.fr><8afhed$f9v$1@newpoisson.nosc.mil> X-Complaints-To: usenet@newpoisson.nosc.mil X-Trace: newpoisson.nosc.mil 953142571 4399 128.49.4.5 (15 Mar 2000 17:49:31 GMT) Organization: Computer Sciences Corporation NNTP-Posting-Date: 15 Mar 2000 17:49:31 GMT Newsgroups: comp.lang.ada Date: 2000-03-15T17:49:31+00:00 List-Id: Robert Duff wrote: >claveman@fern.com (me) writes: > >> I've been lovingly fondling the LRM the last couple of days and I'm >> still not certain what's going on here. Whatever it is, it appears not >> to work. The only test I've run so far has been with the Green Hills >> compiler and it doesn't like this use of abstract for this purpose. >> Making educated guesses, it appears that the reason is this: Defining >> the type as abstract makes the operation illegal to call but it doesn't >> hide it. Extracting from my particular case, if I have the two declara- >> tions >> >> function "-" (L, R : Time_Type) return Delta_Time_Type; >> function "-" (L, R : Time_Type) return Time_Type is abstract; >> >> and I later have the subexpression TT1 - TT2, where the two values are >> both of type Time_Type, and this subexpression is part of an appropri- >> ately constructed expression, then the Green Hills compiler complains of >> an ambiguity. As I see it, it's saying, "I can't tell if you're refer- >> ring to the o. k. "-" that returns a value of type Delta_Time_Type or if >> you're referring to the other one, which would be illegal if that's what >> you meant." > >You'll have to post the exact code if we're to understand what's going >on there (all of the ops declared, and the supposedly ambiguous >statement). And the error message. O. K., here's an example. It's not meant to meaningful, just to show the problem, although I hope that the name for the integer variable suggests how it could be used meaningfully. This example has been tested on GNAT. The exact error messages depend on the compiler, but both GNAT and Green Hills 1.8.9a both complain about the ambiguity. procedure Disallow is type Time_Type is new Float; type Delta_Time_Type is new Float; function "-" (L, R: Time_Type) return Delta_Time_Type; function "-" (L, R: Time_Type) return Time_Type is abstract; TT1, TT2 : Time_Type; Elapsed_Seconds : Integer; begin Elapsed_Seconds := Integer (TT1 - TT2); end Disallow; >You should be able to do TT1 - TT2, so long as the context determines >the type. Eg, "X := TT1 - TT2;" will work, if X is a variable of type >Delta_Time_Type. And "Delta_Time_Type'(TT1 - TT2)" will work no matter >what the context. Certainly the qualified expression would remove any ambiguity, but the point of my original post was to be allowed to restrict pre-defined operations in such a manner that there is no ambiguity to begin with. >> Even if M. Rosen is right and Green Hills is wrong, this approach >> still doesn't work for me because the problem with literals (mentioned >> in my original post) still remains. To restate it, if I could use this >> technique to rule out >> >> function "*" (L, R : Delta_Time_Type) return Delta_Time_Type; >> >> then I would have also ruled out multiplying a delta time by a real lit- >> eral. > >You could define another type specifically for numeric literals. After >all, in "X * 2.5", 2.5 is not a time, it's conceptually a dimensionless >quantity. You presumably want to allow multiplication by a named >number, as well. Again, as I said in my original post, if you use another type to define what multiplication by a real literal means, you open yourself up to multiplication by any value of that type, not just literals. I also referred to "use[ing] numeric literals when appropriate" so, yes, that includes named numbers. >> Even if this worked (works), I find it lacking in esthetics. > >An abstract subprogram is exactly a subprogram that can't be called. >That's true for both tagged and untagged, although the rules that ensure >this property are more complicated in the tagged case, because they need >to account for dispatching calls. Yes, an abstract subprogram can't be called, but it is declared. What I want is one that can't be written, that gets an "undefined" error message out of the compiler. >It does seem a bit backwards, perhaps: you might like to declare the >operations that *do* exist, not the ones that don't. Most of the time, >most programmers don't bother with all this stuff, presumably for that >reason. Fine. Then rephrase my question to being about the ability to de- fine exactly the operations that exist for a type. Unfortunately, I seem to be inheriting ones that I don't want. > ... >>...A >> point I always make when arguing in favor of Ada is that it usually al- >> lows us to say what we mean in a fairly direct fashion. When we want to >> say that a type or a subprogram is abstract, we don't have to use some >> totally non-intuitive notation such as might be found in a more popular >> language. We simply say "is abstract". If the feature that I want were >> available, I'd really like to see something like >> >> function "-" (L, R : Time_Type) return Time_Type is disallowed; > >And how would this differ from the concept of an abstract subprogram? >Is it allowed for tagged types? Does it have all the same rules about >overriding as abstract subprograms do? I hope that some of the above clarifies how a disallowed operation would differ from an abstract operation. As to the other two questions, remember, my original question was whether this subject had been consid- ered during the Ada 95 deliberations, although I obviously have an in- choate proposal in mind if it wasn't. With that background, I think I know what I want in answer to the other two questions. At the point of the declaration, the operation ceases to exist. For the second ques- tion, I see no reason why the mechanism shouldn't apply to tagged types. (I don't have a feel for the utility of the idea in this case.) For the third question, it seems like the usual scope rules should apply. There- fore, using the usual mechanisms of the language, it should be possible to add a definition later in the scope, although this wouldn't be over- riding since there is nothing to override. > ... >> Another responder mentioned that disallowing operations would have >> an impact on generics. That's true, and a point that I have never con- >> sidered. I'll consider it as soon as I have this abstract subprogram >> stuff straightened out. At the very least, the contract model would >> have to become much more elaborate and I doubt that many people have the >> stomach for working on that. > >Actually, in an instance, all the operations revert to the predefined >ones anayway, so I don't see a problem (although many people think that >reversion is itself a language flaw). For the idea I have in mind, however ill-formed it might be, rever- sion to the pre-defined operations would indeed be a flaw, because the disallowed pre-defined operation would simply not exist. It seems like one thing for an existing operation to lose its abstractness in generics but it's quite another for a conceptually non-existent operation to come into being. Charlie -- ****** For an email response, my user name is "sampson" and my host is "spawar.navy.mil".