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=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!gegeweb.org!usenet-fr.net!proxad.net!feeder1-2.proxad.net!137.226.231.214.MISMATCH!newsfeed.fsmpi.rwth-aachen.de!reality.xs3.de!news.jacob-sparre.dk!loke.jacob-sparre.dk!pnx.dk!.POSTED!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Your wish list for Ada 202X Date: Mon, 7 Apr 2014 20:15:10 -0500 Organization: Jacob Sparre Andersen Research & Innovation Message-ID: References: <7f1c01c5-3563-4b94-9831-152dbbf2ecdc@googlegroups.com> <8bhozh836pyt$.1qctlysud0s2q$.dlg@40tude.net> <1cdsyxjzsfgzm.1synpaujysv21$.dlg@40tude.net> <1aa804jg9qq4o$.wdiq33yo621l.dlg@40tude.net> NNTP-Posting-Host: static-69-95-181-76.mad.choiceone.net X-Trace: loke.gir.dk 1396919711 26855 69.95.181.76 (8 Apr 2014 01:15:11 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Tue, 8 Apr 2014 01:15:11 +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 Xref: news.eternal-september.org comp.lang.ada:19186 Date: 2014-04-07T20:15:10-05:00 List-Id: "Dmitry A. Kazakov" wrote in message news:1aa804jg9qq4o$.wdiq33yo621l.dlg@40tude.net... > On Wed, 2 Apr 2014 17:39:06 -0500, Randy Brukardt wrote: > >> "Dmitry A. Kazakov" wrote in message >> news:1cdsyxjzsfgzm.1synpaujysv21$.dlg@40tude.net... >> ... >>>>> Of course The former >>>>> would be greatly preferable. This requires yet another feature Ada >>>>> lacks - >>>>> interface inheritance. Unbounded_String must drop parent's >>>>> implementation/representation and inherit only the interface. >>>> >>>> That's not the problem at all. (The parent here would have no >>>> representation, so there is nothing to drop.) >>> >>> Unbounded_String will be derived from String, or String derived from >>> Unbounded_String. The point is to keep it a hierarchy. >> >> Why? There is no interesting relationship between String and >> Unbounded_String other than the interface (which is inherited from the >> root >> type). > > The relationship is that you can mix Unbounded_String and String in > operations like "&". Yeah, just like mixing apples and oranges. Mixed operations are not the Ada way of typing. >> There is no opportunity to share implementations, which is the other >> reason to inherit one from another. > > Most of implementations of String can be shared by Unbounded_String. This > is what people do manually all the time converting Unbounded_String to > String and back. No, not really. Most implementations of Root_String'Class could be shared amongst string types. But specific implementations are tied to particular representations; that's exactly what we want to get rid off. Moreover, there cannot be automatic sharing of operations; that weakens the type system. One only wants to share operations that are explicitly intended to be shared; that's the point of declaring packages operating on Root_String'Class rather than some specific type. >> Just inheriting things because something *thinks* they should be related >> is >> silly. There is no advantage to using String'Class (if such a thing >> existed) >> rather than Root_String'Class, since all the former does is restrict what >> your subprogram can do; it doesn't add any capability. > > You have just said that constrained types are useless. What is the > advantage of using String (1..80). It does not add any capability... Constrained types *are* useless -- Ada has no such thing. It only has unconstrained types (remember that names only apply to subtypes). And in particular, a constrained class-wide type is an evil thing, because it's mixing things that should not be mixed: relaxing and tightening constraints at the same time. >>> And the real problem >>> with all that is that there is more than one vector of inheritance: >>> 1. memory management (fixed, bounded, unbounded) >>> 2. range (character, wide_character, wide_wide_character) >>> 3. encoding (UCS-4, UCS-2, UTF-8, ASCII) >> >> 1 and 3 are irrelevant, because they shouldn't have any effect on the >> interface -- they're things that should be totally hidden outside of >> streaming for 3. Perhaps 2 should have some affect on the interfaces, but >> that's easily handled with a second level of abtsract types defining >> those >> interfaces. > > Presently 1-3 are exposed, and I don't understand how you are you going to > hide them: > > type A (Length : Positive) is record > X : String (1..Length); > end record; > > type B is record > X : Unbounded_String; > end record; > > Looks a quite visible difference to me. Object declarations of course use concrete, specific types. So what's your point? The majority of operations would take Root_String'Class and thus work on any object. Ones that don't would have been restricted for some good reason, and would work as now. What's so hard about that? >> Besides, 1 can totally be defined after the fact with packages. That's >> the >> model that I'm suggesting. > > This is equivalent to deriving from fixed string, which is the common > denominator. No, I'm deriving from an abstract type with no representation. There's a huge difference. >> "Unbounded_String" is a container for a >> Root_String'Class type; it adds unbounded memory management to whatever >> the >> string type does. There is no reason that one has to do that as part of >> the >> string abstraction. > > But then you necessarily loose all operations String cannot have, e.g. > Append, Replace, etc. The idea is of course that Unbounded_String, > Unbounded_Wide_Wide_String, Unbounded_UTF8_String share this interface. Ada.Strings.Fixed has all of those operations. Why would we lose them? The problem with Ada.Strings as it is is that the operations are subtly different; there's no good reason for that. ... >> You would have >> to qualify all string literals in an MD world, and that's something >> programmers would never tolerate. > > Ambiguity of literals can be resolved using preference rules like ones > invented for Universal_Integer. We could introduce Universal_String etc. That doesn't work at all; universal integer only has a preference against itself. All other types are equal. So you still have problem of being unable to tell between String and Unbounded_String. And preference rules for user-defined types cause all kinds of visibility and maintenance headaches. > Another method could be making Latin-1 literals contravariant String, i.e. > > package Dont_Make_Me_Primitive is > function "A" return String; > function "AB" return String; > function "ABC" return String; > ... > end Dont_Make_Me_Primitive; > > not inherited by Unbounded_String, Wide_String etc. That will introduce > desired preference. Then Unbounded_String will not have any literals, and you'd still have problems with Wide_Wide_String vs. String. > And, yes, you will be able to assign "ABC" to Unbounded_String because > ":=" > is a MD operation with one body dealing with that: > > procedure ":=" (Left : in out Unbounded_String; Right : String); But that's unimplementable. > Otherwise, yes, preference rules are necessary to resolve > > A & B & C > > Between > > String'(A & B) & C > > and > > Unbounded_String'(A & B) & C Right, and such preferences are always trouble in a programming language. They are a prime source of beaujolais effects, which Ada considers completely unacceptable. (Adding or removing a declaration should never change a legal program into a different legal program with a different meaning.) >>>> We can't get rid of these problematical operations -- it would be way >>>> too >>>> incompatible. So new packages is the only way to go. >>> >>> You can, and everything will stay compatible if the type system is fixed >>> first (MD, MI etc). Within present type system it is indeed unfixable >>> and >>> moreover, new packages will likely become as messy as the old ones. >> >> As I said before, I am skeptical that an MD system (even ignoring MI) >> could >> be implemented efficiently enough to be used in critical operations like >> strings. As soon as you go to MD, the linear tag model has to ba >> abandoned, >> and some sort of search mechanism used for finding bodies to dispatch to. > > An MD operation needs an N-D array indexed by tags of controlling > arguments. Dispatching is indexing the array. Sure, but you can't represent the array that way, because you don't know N at compile-time (someone can define new types and link them in after the fact). And even if you did, it would be an impracticaly large a data structure in most cases. (Consider that there are something like 20 string types in a Root_String'Class model, or that there are around 100 window types in Claw.) That being the case, you have to use some sort of lookup scheme, and whether that can be efficient enough is a question. > (However there are serious problems with implementation of MD which I have > no idea how to resolve. MI is much simpler) I suppose MI is simpler, but it has a similar problem with tag construction. (At least there is only one dimension for interfaces; full MI would turn things into a much worse situation, as hidden types would have to be allowed - and then its possible for a type to have multiple copies of the same interface.) Randy.