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,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.13.202.5 with SMTP id m5mr9375534ywd.190.1505436503571; Thu, 14 Sep 2017 17:48:23 -0700 (PDT) X-Received: by 10.36.246.203 with SMTP id u194mr85221ith.2.1505436503520; Thu, 14 Sep 2017 17:48:23 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!paganini.bofh.team!weretis.net!feeder6.news.weretis.net!feeder.usenetexpress.com!feeder-in1.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!b1no518818qtc.1!news-out.google.com!c139ni1089itb.0!nntp.google.com!127no380031itw.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Thu, 14 Sep 2017 17:48:23 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=173.71.208.22; posting-account=QF6XPQoAAABce2NyPxxDAaKdAkN6RgAf NNTP-Posting-Host: 173.71.208.22 References: <364ff8e0-c7dd-4980-b19f-5d438edd8353@googlegroups.com> <7df81b3c-1fde-4395-8b9b-1a945820a7f7@googlegroups.com> <4565e696-3294-4c27-a761-d18eccb1e1e1@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Re: Type invariants and private extensions? From: Jere Injection-Date: Fri, 15 Sep 2017 00:48:23 +0000 Content-Type: text/plain; charset="UTF-8" Xref: news.eternal-september.org comp.lang.ada:48137 Date: 2017-09-14T17:48:23-07:00 List-Id: On Thursday, September 14, 2017 at 9:52:58 AM UTC-4, Victor Porton wrote: > Jere wrote: > > > On Tuesday, September 12, 2017 at 6:59:17 PM UTC-4, Victor Porton wrote: > >> Shark8 wrote: > >> > >> > On Tuesday, September 12, 2017 at 2:09:08 PM UTC-6, Victor Porton > >> > wrote: > >> >> Jeffrey R. Carter wrote: > >> >> > >> >> > > >> >> > "I want to" is not the same as "there is no way to solve the problem > >> >> > in current Ada". Ada has a feature that provides exactly what you > >> >> > need. It's called a variant record. > >> >> > >> >> It is a tagged type. AFAIK, a type cannot be both a variant record and > >> >> tagged. > >> > > >> > You certainly can: > >> > > >> > Type Type_Enumeration is ( TInteger, TReal, TBoolean, Nothing ); > >> > > >> > Type Example( Item_Type : Type_Enumeration ) is tagged record > >> > case Item_Type is > >> > when TInteger => I : Integer; > >> > when TReal => R : Float range Float'Range; > >> > when TBoolean => B : Boolean; > >> > when Nothing => Null; > >> > end case; > >> > end record; > >> > > >> >> Moreover, the object in consideration is a wrapper over a certain C > >> >> API. It surely cannot be described in variant record terms. > >> > > >> > Sure it can; there's a reason that there's a separation between > >> > specification and body, part of which is so you can hide something like > >> > an interface to C and present something sensible to your > >> > program/clients. > >> > >> Thanks. > >> > >> But this seems not to solve my problem: > >> > >> The base type for Example cannot be defined as a discriminated type for > >> certain Type_Enumeration, because it is possible that when creating the > >> object it may be yet unknown what the value of the discriminant should > >> have (my main problem is to invent somethings if this value is known at > >> object creation, but we must support the unknown case too). AFAIK, it is > >> not possible to change the discriminant later. > >> > > > > I may be misunderstanding what you are looking for, but you can > > make discriminant types unconstrained to let you choose the type > > at run time: > > > > Type Type_Enumeration is ( TInteger, TReal, TBoolean, Nothing ); > > > > Type Example( Item_Type : Type_Enumeration := Nothing) is tagged > > record > > case Item_Type is > > when TInteger => I : Integer; > > when TReal => R : Float range Float'Range; > > when TBoolean => B : Boolean; > > when Nothing => Null; > > end case; > > end record; > > > > Then all you have to do is declare an object with no > > specified discriminant: > > > > Some_Object : Example; --notice no discriminant > > > > In Ada, when you do this, you are able to assign new versions > > of the type (with different discriminants: > > > > Some_Integer : Example := (Item_Type => TInteger, I => 100); > > Some_Float : Example := (Item_Type => TFloat, F => 20.2); > > > > Some_Object := Some_Integer; > > Some_Object := Some_Float; > > > > That's just a play example, you can handle building them however > > you want at run time. > > It does not suffice for me, because at the point of actual object creation, > the discriminant value may be yet unknown. Sometimes, I need first create > the object and LATER (when the object was already created and I did some > operations with it) assign it the type. > > -- > Victor Porton - http://portonvictor.org But that is what this does. You declare your object: Some_Object : Example; --notice no discriminant Here no discriminant is provided, so it is unconstrained. Sometime later (a minute from now, a 100 days from now, etc.) you get some user input that tells you what type you want (we'll say an integer for example, but any type you have defined can be used), you can then simply do: declare Some_Integer : Example := (Item_Type => TInteger, I => User_Input); begin Some_Object := Some_Integer; end; -- You might even be able to simply do it without a declare block: -- Some_Object := (Item_Type => TInteger, I => User_Input); -- I just haven't tried that out. and now you have a runtime selected version. You can replace that Some_Integer with Some_Real or any other version you want. You don't have to know the type at compile time because the type Example is unconstrained. You can have a discriminated type that is unconstrained so you can change it freely at runtime. Since the default value of the discriminant is "Nothing", it handles the object while we are waiting for input and are basically in an unknown state. You can rename Nothing to Unknown if it helps for readability. Does that sound better?