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=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,73cb216d191f0fef X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit X-Received: by 10.66.12.161 with SMTP id z1mr2643603pab.11.1364353693796; Tue, 26 Mar 2013 20:08:13 -0700 (PDT) Path: jv11ni186pbb.0!nntp.google.com!npeer01.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!border3.nntp.dca.giganews.com!border1.nntp.dca.giganews.com!border4.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!nrc-news.nrc.ca!goblin2!goblin.stu.neva.ru!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Is this expected behavior or not Date: Fri, 22 Mar 2013 17:07:51 +0100 Organization: cbb software GmbH Message-ID: <2qwq2cdeuvhu$.qtnb8zyhuob9$.dlg@40tude.net> References: <11rcs3gg4taww$.bylek8fsshyz$.dlg@40tude.net> <99929f93-b80f-47c3-8a37-c81002733754@googlegroups.com> <87ec4b1d-f7cd-49a4-8cff-d44aeb76a1ad@googlegroups.com> <78103a2f-5d19-4378-b211-1917175d5694@googlegroups.com> <3p6p8k0yfly7.ctazdw7fc5so$.dlg@40tude.net> <1jtvzi1v65aqm.1k5ejsveno59f.dlg@40tude.net> <1hvv2kd9smnfx.6spgz9thd1mh$.dlg@40tude.net> <1raubw1sk48ca$.69rdgczvnnf.dlg@40tude.net> Reply-To: mailbox@dmitry-kazakov.de NNTP-Posting-Host: FbOMkhMtVLVmu7IwBnt1tw.user.speranza.aioe.org Mime-Version: 1.0 X-Complaints-To: abuse@aioe.org User-Agent: 40tude_Dialog/2.0.15.1 X-Notice: Filtered by postfilter v. 0.8.2 X-Received-Bytes: 13529 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Date: 2013-03-22T17:07:51+01:00 List-Id: On Thu, 21 Mar 2013 18:27:22 -0500, Randy Brukardt wrote: > "Dmitry A. Kazakov" wrote in message > news:i93qv6ba3bv0.wuicbsmfm5ha.dlg@40tude.net... >> On Wed, 20 Mar 2013 18:57:58 -0500, Randy Brukardt wrote: > ... >>> Even if you are willing to confuse users with implicit dispatching, you're >>> also talking about turning every slice reference into a loop. >> I don't see why. When the slice object happens to be class-wide, you have >> a dope with a tag, bounds and a reference to some yet-to-be-discovered >> representation. When the slice is specific, you have a dope with bounds >> and a reference to some statically known representation. > > The underlying model of a slice is an implicit loop. We already have to use > loops to implement some slices in existing Ada; there is no possibility of > eliminating that. That's because ultimately everything is done on machine > objects (bytes, words, dwords, etc.) and you always need a loop if you are > going to operate on more than one. I still don't understand why is it relevant. Ada already has "loops" you are talking about for String and Wide_String. Why cannot you use them for their representations after selecting through dispatch? > Because of that, there is almost no value to slicing operations unless you > know the representation and can use block move instructions. I want to be able to pass a slice to Put_Line without copying. > There's nothing that you can do with a slice that you can't do with a loop, > and usually the loop is easier to write and understand. Are you suggesting to call Put from a loop instead of Put_Line? I Don't want the language forcing me doing that. >>> Why do you care? String objects are a lot bigger than a tag, so it can't be >>> a memory usage concern. The only other place it could possibly matter is >>> I/O. But for package like Text_IO, a tag and dispatching is exactly what you >>> want, and for 98% of strings, that's what they ultimately get used for. For >>> streaming and the like, the representation does not include the tag if you >>> stream a specific type. So what's the problem?? >> >> The problem is slicing and interfacing to other languages. Tagged string >> will require copying in and/or out each time you pass a slice to a >> subprogram. On top of that tagged types are by-reference which contradicts >> to copying. > > Slicing is already impossible for the case that we're talking about, ? Normal strings have slices and should continue to have them. > and > interface to foreign language already has to be done through special types. Which should certainly be in the same class! There is no semantic reason why char_array should not be considered string. > Clearly, types with an appropriate representation clause need to follow that > clause (or be rejected), but again I ask why do you care how types that are > going to be used purely by Ada (and that had better be most of them) are > implemented?? Because representation must be controlled by programmer, not by the language. It should be possible to declare a string object of *any* representation whatsoever. If the compiler does not know how to implement operations on this representation it should ask me, the programmer, to implement them. >>> Removing a tag from an object is an optimization; I believe every object >>> should have a tag and it's up to the compiler how to implement it. It's >>> really none of your (the programmer's) business (in the absence of >>> representation clauses). >> >> Only class-wide objects, you mean. Specific object need no tags and those >> with representation aspects shall not have it. > > No I mean all objects. It should be none of your business how the compiler > implements objects On the contrary, the compiler is free to choose a representation under the constraints specified by the programmer. I don't want Ada to become C#. >> As for considering it optimization, I really want this rather in the >> contract. Because the mechanism of adding some information to a class-wide >> object looks very promising beyond tags. We could use it on so many other >> cases: >> >> 1. Dimensioned values >> 2. Array bounds >> 3. Matrix dimensions >> 4. Storage pool reference in a pointer object >> ... > > None of the above makes any sense whatsoever. We need all of those things in > the object in order to generate code. So, you want to describe all possible problem domains in the RM? The RM should know that a matrix of 2 rows and 5 columns can be multiplied to a 5x8 matrix, but not to a 8x8 matrix? Good luck with that! > I suspect that if your model became the law of the land, compilers would > generate very bad code for any cases like the ones you want, and you > wouldn't be able to use the result anyway. Nobody tried. But I doubt it. My proposals have a goal to significantly simplify the language. Ada 2005 and 2012 added a huge number of special cases requiring special treatment. That surely complicates optimization of Ada programs which is already not great. Smaller and more regular language would be easier to optimize. >>>>> I don't think we need 'Class for access types, >>>> >>>> You need them because access types shall implement "access interface." >>>> We need access interface for user-defined referential types. >>> >>> Ada 2012 has user-defined referential types. You can do everything you >>> need with plain-old tagged types. >> >> Like having it 16-bit long? I don't like when the language mandates >> representation of use-defined types. It looks more like a discount center. > > If you *really* need a 16-bit pointer, that means you have truly critical > time/space needs. Not necessarily. It could be because the thing need to be atomic, or because I wanted to marshal it. The programmer may have his reasons. > And in that case, you really need to dump everything > modern (OOP, interfaces, etc.) in the trash can and write basic Ada 83-style > ADT code, without any attempt at anything special. Because the overheads > associated with OOP (especially any form of multiple inheritance) are always > going to cost many times in time and space your "16-bit pointer". A compiler > could fake it, but all that you've done is moved the costs into a corner > where they're less obvious. They didn't magically go away. This is a totally bogus argument. OO imposes no overhead on specific types. It does on class-wide objects, which simply non-existent in Ada 83. If you implemented class-wide objects on top of Ada 83 objects you would get exactly same overhead or more. > Besides, if the sort of uses you are asking about get prominence, then > clearly compiler writers will try to make their implementations more > efficient (as AdaCore has done with finalization). There is not fundamental > reason that a compiler writer with sufficient motivation couldn't leave the > tags out of tagged objects (that was a goal for the design of Ada 9x, and I > believe it is possible). There's no reason to invent new semantics when the > existing semantics is good enough. Nobody proposes to change tagged types. The idea is to add classes to non-tagged types by adding tag to the class-wide object while keeping specific objects as-is. >>> But in any case, this is a bad idea. You don't want to explicitly handle >>> memory management in modern programs. Do it under the covers somewhere >>> (like in the containers packages); do *not* expose access types. >> >> Container libraries need to be implemented as well. I don't want to expose >> access type, I want referential semantics. > > And that's the point of 4.1.5. The only thing you can't do is write "new" (what about 'Access? What about Unchecked_Deallocation?) > that way, but calling a function to do that doesn't seem that bad. How do I put such a reference in an array, for example? 4.1.5 would be extremely difficult to use for intended purpose. >>>> And I >>>> want to be able to write a class-wide subprogram which would take both >>>> Handle and some plain access type as a parameter. >>> >>> As I said, no new code should be exposing raw access types. Something >>> like the container Cursor type is a much better way to handle the need for >>> referential semantics. >> >> But 4.1.5 does not hide access types. On the contrary it mandates access >> type as the discriminant. > > Ahh, but that was a case where the "existing semantics" was good enough so > we didn't create a new thing. This is a very special access type, one that > almost never can be copied -- for practical purposes it can only be > dereferenced. That's what we needed. Note that there is no intent that > anyone ever create an object for this access type (and that is where all of > the problems lie). It just has the syntax of an access type so we didn't > have to invent a new thing to get dereferencing. You have a very specific use case in mind, namely containers. There is a whole world outside that, for which what you said is untrue, e.g. for smart pointers. The thing not only exposes access, it also exposes the target type. For smart pointers and handles you might what to hide both. Consider a handle to a file. You certainly don't want to make File_Descriptor it points to, visible. You want the handle to implement file I/O interface routed privately to the descriptor. You also want handles be copyiable and comparable, but treated as references to some opaque limited object. >>>>> Maybe you're trying too hard to be Object-Oriented; >>>> >>>> I am trying to have it type-safe. It would be just impossible to do in >>>> Ada 95. In Ada 2005, which has Java interfaces, it gives what I described. >>>> Lack of MI, which is worked around using generics. I guess that MI would >>>> slash the amount of code by ten. MD would do another tenth. >>> >>> It's not worth it to be type-safe in this way. Especially as >>> preconditions/postconditions combined with static analysis give the same >>> effect (compile time checking) with 10% of the work. >> >> Even if it were compile-time it would require same representation for all >> involved objects. How would I do it for Unsigned_1 and String? > > I don't see this necessarily. You certainly can use dispatching to support > different representations. No way. Consider operation Send: procedure Send (To : in out Register; Value : Unsigned_1); procedure Send (To : in out Register; Value : String); It cannot dispatch! Firstly, Unsigned_1 and String are not in the same class. Secondly, even if they were, it would be MD! So, you need MI and MD to make it happen. Without them, poor man's solution is messing with generics. > But I still think you are trying too hard to avoid run-time checks. If I weren't, I would use Perl, not Ada. I favor Ada exactly because it gives me static checks. It is sad to see Ada drifting towards run-time / dynamic-typing junk. > I think > these need a balance, especially as modern static analyzers can remove the > vast majority of them (or warn that they might fail, which is a cause for > concern). It is not about removing checks, though performance is a concern too. The major problem is that failed checks must be flagged as errors. You are a compiler writer, I am designing automation systems. To me run-time check is much too late. A fault can break real things, apart from maintenance. Imagine Claw running on an oil platform. Do you own a helicopter? -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de