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-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.191.130 with SMTP id gy2mr626370pac.19.1364266409813; Mon, 25 Mar 2013 19:53:29 -0700 (PDT) MIME-Version: 1.0 Path: q9ni25767pba.1!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!nntp.giganews.com!novia!news-hub.siol.net!exi-in1.telstra.net!news.telstra.net!newsgate.cuhk.edu.hk!goblin3!goblin.stu.neva.ru!nntp-feed.chiark.greenend.org.uk!ewrotcd!reality.xs3.de!news.jacob-sparre.dk!munin.jacob-sparre.dk!pnx.dk!.POSTED!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Is this expected behavior or not Date: Thu, 21 Mar 2013 18:27:22 -0500 Organization: Jacob Sparre Andersen Research & Innovation Message-ID: 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> NNTP-Posting-Host: static-69-95-181-76.mad.choiceone.net X-Trace: munin.nbi.dk 1363908446 10145 69.95.181.76 (21 Mar 2013 23:27:26 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Thu, 21 Mar 2013 23:27:26 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 X-Received-Bytes: 12364 Date: 2013-03-21T18:27:22-05:00 List-Id: "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. Of course, if you know the representation, you can get away with special-case loops (like a block move), but if you don't know the representation of the elements (or how the indexing works), a loop is the only possible implementation. Because of that, there is almost no value to slicing operations unless you know the representation and can use block move instructions. Otherwise, you are setting up a loop of dispatching operations, one element at a time. It's dubious that this is worth special language support. 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. The only advantage of the slice is the optimized code that it can produce, and that's gone if you don't have the representation. (The whole idea of slices was a mistake that probably shouldn't have been in the language in the first place -- it caused a reliance on not very good string processing instead of providing a reasonable mechanism from the beginning.) ... >> 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, and interface to foreign language already has to be done through special types. (Using a type that doesn't have convention C is wrong for C interfacing, although your current compiler might allow it, there is no reason to assume another has the same rules.) 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?? >> 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 -- any objects -- you ought to want the compiler to do the best job it can, not put arbitrary and possibly counter-productive restrictions on it. If you need a particular representation, then you need to give a representation clause. Otherwise, leave the compiler alone. > 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. (Janus/Ada uses a single representation for all objects of a type, and you don't have enough money to change that.) It's possible in limited circumstances to avoid that (statically constrained arrays come to mind), but every such special case greatly increases the complication of a compiler. 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. And again, I don't think you have enough money to change that situation (maybe if I won the Powerball I could...) >>>> 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. 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. 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. >> 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" that way, but calling a function to do that doesn't seem that bad. >>> 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. >> ... >>>> For someone that hates generics, why would you have so many? Thanks for the lengthy explanation. I'm not going to comment on it individually anymore, because one is always on thin ice talking about another's code without knowing all of the issues involved, and there seems to be a summary point. ... >>>> 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. But I still think you are trying too hard to avoid run-time checks. 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). (This is assuming use of Pre/Post, of course.) I realize some systems have to be locked down without run-time checks because of outside reliability requirements, but these systems can't have complex systems of generics (or usually have any dispatching or memory management, either). Ada's type system isn't powerful enough to push everything to static checks, and indeed I'm dubious that any practical system could be that powerful. Giant edifices of generics and/or interfaces are essentially impossible to understand and debug (and in the margin, compile). Simplify! Simplify! I'd rather use a few run-time checks and a few run-time parameters than end up with dozens of types and packages. Randy.