comp.lang.ada
 help / color / mirror / Atom feed
From: Jere <jhb.chat@gmail.com>
Subject: Re: Type invariants and private extensions?
Date: Thu, 14 Sep 2017 17:48:23 -0700 (PDT)
Date: 2017-09-14T17:48:23-07:00	[thread overview]
Message-ID: <bad49271-6c81-4eb6-b95b-7d7915d0aae1@googlegroups.com> (raw)
In-Reply-To: <ope1jl$1dgm$1@gioia.aioe.org>

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?


  reply	other threads:[~2017-09-15  0:48 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-11 19:51 Type invariants and private extensions? Victor Porton
2017-09-11 20:00 ` Egil H H
2017-09-11 20:48   ` Victor Porton
2017-09-11 21:19     ` Egil H H
2017-09-11 21:27       ` Victor Porton
2017-09-11 21:49         ` Egil H H
2017-09-11 22:00           ` Victor Porton
2017-09-11 22:06             ` Egil H H
2017-09-12  7:30             ` Dmitry A. Kazakov
2017-09-11 22:00         ` Jere
2017-09-11 22:02           ` Victor Porton
2017-09-12 18:26             ` Jeffrey R. Carter
2017-09-12 18:54               ` Victor Porton
2017-09-12 19:56                 ` Jeffrey R. Carter
2017-09-12 20:08                   ` Victor Porton
2017-09-12 22:34                     ` Shark8
2017-09-12 22:59                       ` Victor Porton
2017-09-13  4:21                         ` Jere
2017-09-13  4:28                           ` Jere
2017-09-13  4:34                             ` Jere
2017-09-14 13:52                           ` Victor Porton
2017-09-15  0:48                             ` Jere [this message]
2017-09-16 14:22                               ` Victor Porton
2017-09-14  7:28                         ` Shark8
2017-09-14 13:56                           ` Victor Porton
2017-09-14 13:58                             ` Victor Porton
2017-09-11 22:48         ` Shark8
2017-10-02 23:16         ` Randy Brukardt
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox