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.176.94.151 with SMTP id y23mr10297490uag.80.1505276470458; Tue, 12 Sep 2017 21:21:10 -0700 (PDT) X-Received: by 10.36.51.147 with SMTP id k141mr77313itk.14.1505276469929; Tue, 12 Sep 2017 21:21:09 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!news.unit0.net!peer02.am4!peer.am4.highwinds-media.com!peer02.iad!feed-me.highwinds-media.com!news.highwinds-media.com!b1no1963704qtc.1!news-out.google.com!c139ni536itb.0!nntp.google.com!o200no657706itg.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Tue, 12 Sep 2017 21:21:09 -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> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <4565e696-3294-4c27-a761-d18eccb1e1e1@googlegroups.com> Subject: Re: Type invariants and private extensions? From: Jere Injection-Date: Wed, 13 Sep 2017 04:21:10 +0000 Content-Type: text/plain; charset="UTF-8" X-Received-Body-CRC: 4294899668 X-Received-Bytes: 4517 Xref: news.eternal-september.org comp.lang.ada:48093 Date: 2017-09-12T21:21:09-07:00 List-Id: 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.