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,103b407e8b68350b X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-02-03 01:59:41 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!headwall.stanford.edu!fu-berlin.de!uni-berlin.de!tar-alcarin.cbb-automation.DE!not-for-mail From: Dmitry A. Kazakov Newsgroups: comp.lang.ada Subject: Re: Anybody in US using ADA ? One silly idea.. Date: Mon, 03 Feb 2003 10:59:39 +0100 Message-ID: <2b9s3vo3bbnaikqd6d4jpppfflfq2kbgfu@4ax.com> References: <1043855067.848326@master.nyc.kbcfp.com> <3OXZ9.85359$Ve4.6306@sccrnsc03> <1043880843.44251@master.nyc.kbcfp.com> <1043938782.244443@master.nyc.kbcfp.com> <25ji3v8n915cnnnaqpjvm4f7i01a66r9pf@4ax.com> <1043949507.331484@master.nyc.kbcfp.com> <1044025336.3067@master.nyc.kbcfp.com> <1044033063.693737@master.nyc.kbcfp.com> NNTP-Posting-Host: tar-alcarin.cbb-automation.de (212.79.194.111) Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: fu-berlin.de 1044266380 38294565 212.79.194.111 (16 [77047]) X-Newsreader: Forte Agent 1.8/32.548 Xref: archiver1.google.com comp.lang.ada:33714 Date: 2003-02-03T10:59:39+01:00 List-Id: On Fri, 31 Jan 2003 12:11:03 -0500, Hyman Rosen wrote: >Dmitry A. Kazakov wrote: >> I do not see how this would make one substitutable for another. > >This makes it possible to write code that works seamlessly with >the different kinds of string, as long as the operations used >are common to all of them. In C++ you just write your generic >method, and the compiler instantiates it for the types you >supply, without you having to tell it anything. In this case the types a siblings, not subtypes. BTW generics give us an example of substituatability independent on the type representation. Consider a generic function: generic type X is private; procedure Foo (Arg : X); Here, any "private" is substitutable for Arg. I can be Integer, Float, almost everything. >> Thunk code. > >Huh? What does this mean? That thunk code needs to be generated >to do what you want? To make view conversion when an inherited method is called. > I know that. But things don't work this >way in Ada, C++, or Java, at least as far as I know about Ada. > >> I do not want flawed implicit type conversions. I want sub- and >> supertyping. If an implementation of sub-/supertyping is based > > on some conversions, I do not care. > >But as I keep repeating, your concept of sub/supertyping is at odds >with the general understanding of this. When you describe what you >want, it looks like two-way type conversion is the only thing that >is necessaery, so it is natural to ask why inheritance should be >involved in this at all. It is inheritance in my view. If there are two things present for a method and a type: 1) substitutability (conversions is a way to provide it) 2) automatic substitution [by the compiler] then I say that the method is inherited by the type. >> procedure Query (X : in out Float); >> -- The initial value is used as a default >> ... >> I : Integer := 10; >> begin >> Query (Float (I)); > >Cool. More stuff I didn't know about Ada. But to quote from the Ada RM, > "If the target type is tagged, then an assignment to the view > assigns to the corresponding part of the object denoted by > the operand;" >so as I've been saying, Ada follows the conventional view that an >object is its base type(s), without any conversions needed. The >view conversion for a tagged type just winds up pointing at the >appropriate subobject. "just winds up pointing" *is* a conversion. Imagine that other sorts were allowed too! >Hmm. the same section continues > "otherwise, an assignment to the view assigns to the object, > after converting the assigned value to the subtype of the > object (which might raise Constraint_Error);" > >Ada experts - does this mean that each time the Query routine >above assigns a value to X it has to know that X is really a >view conversion of I, and check for error? Or can it just do >the check once at copy-out time? The former would seem to add >draconian complexity to subroutines. You can do conversions at a call point. That is the whole idea of substitutability. The "inherited" method remains same. You just compose it with apporipriate conversions to and back. >> A given object may have only one type. > >Says who? Me, is that matter? (:-)) There could be many type theories, but the simpliest one is to require that there is only one type of a given value. >> If C is A why memcpy does not work? > >Because memcpy yields undefined behavior when copying >C++ objects around. On the other hand, X = Y will work >perfectly fine. Then you should explain what "is a" does mean. It is definitely not mathematical =, as memcpy shows. It is rather a sort of equivalence. Equivalence in OO is defined as substitutability, which does not necessarily imply equality. So C is not A, C is only substitutable for A, i.e. it is an equivalent to A. >> subtype Positive is Integer range 0..Integer'Last; > >You know, I used to think that C++ could benefit from having >Ada-like subranges. Thanks for opening my eyes :-) > >> It is not better. My point was: we should check as much as possible at >> compile-time. Your point was: we should check only things actually >> used in the given program, as templates do. I gave you an example why >> it is a bad idea. You responded with another example. So the point >> stands. > >I think I failed to understand your example, then. >You say that we should check as much as possible at >compile-time, but what does that mean? Perhaps I >should require that my types all be able to dance a >soft-shoe number, in case I have to give a demo of >my code to executives? You claim that there is benefit >in requiring that types support unused operations. I >don't see what that benefit is, or where you cut off >the infinite list of possible operations that a type >could conceivably support. If you define a type, say, "field". Then you should implement all operations of the field. Otherwise, it is not a field, but a group or something else. So the users of your type would have no delusions about it. If it has interface of a group, why to present it as field? It is just DbC. Ada gives an example of this approach: when you derive from an abstract type, the derived non-abstract type has to implement all abstract operations, no matter whether some of them will never be used. Failure to do that is a *compile-time* error. Same thing with C++ templates produces a "valid" program! (Ada generics are safer in this respect) --- Regards, Dmitry Kazakov www.dmitry-kazakov.de