comp.lang.ada
 help / color / mirror / Atom feed
* Correct use of variants
@ 2005-11-07 10:32 Maciej Sobczak
  2005-11-07 12:52 ` Jean-Pierre Rosen
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Maciej Sobczak @ 2005-11-07 10:32 UTC (permalink / raw)


Hi,

Consider this:

with Ada.Text_IO;
with Ada.Integer_Text_IO;
use Ada.Text_IO;
use Ada.Integer_Text_IO;

procedure Hello is

    type Chooser is (First, Second);

    type Discriminated(Which : Chooser) is
       record
          case Which is
             when First =>
                X : Integer;
             when Second =>
                Y : Integer;
          end case;
       end record;

    A : Discriminated := (Which => First, X => 7);

begin

    Put(A.X);   -- prints 7
    New_Line;

--   does not compile:
--   A := (Which => Second, Y => 5);
--
--   Put(A.Y);   -- should print 5
--   New_Line;

end Hello;


Above, A is declared as a value of *constrained* type (what's the formal 
name for this - "anonymous constrained subtype"?), with the discriminant 
Which fixed to value First. Later the variant cannot be changed as shown 
in that the commented part would not compile.

What is the correct way to achieve the declaration of A with the 
possibility of changing the discriminant later? One of the ways is to 
use *some* default value for the discriminant, but I might have 
difficulty deciding which value is better than the others for this role. 
An arbitrary choice would create a misleading message to the reader that 
the particular value is considered to be "best" or "idle" or "starting" 
or whatever. In addition, having a default value for the discriminant 
means that it's not obligatory to initialize the variable A while it's 
declared and I would like to keep this enforced.


--
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Correct use of variants
  2005-11-07 10:32 Correct use of variants Maciej Sobczak
@ 2005-11-07 12:52 ` Jean-Pierre Rosen
  2005-11-07 19:46 ` Jeffrey R. Carter
  2005-11-07 23:40 ` Stephen Leake
  2 siblings, 0 replies; 5+ messages in thread
From: Jean-Pierre Rosen @ 2005-11-07 12:52 UTC (permalink / raw)


Maciej Sobczak a �crit :
> Hi,
> 
> Consider this:
> 
> with Ada.Text_IO;
> with Ada.Integer_Text_IO;
> use Ada.Text_IO;
> use Ada.Integer_Text_IO;
> 
> procedure Hello is
> 
>    type Chooser is (First, Second);
> 
>    type Discriminated(Which : Chooser) is
>       record
>          case Which is
>             when First =>
>                X : Integer;
>             when Second =>
>                Y : Integer;
>          end case;
>       end record;
> 
>    A : Discriminated := (Which => First, X => 7);
> 
> begin
> 
>    Put(A.X);   -- prints 7
>    New_Line;
> 
> --   does not compile:
> --   A := (Which => Second, Y => 5);
> -- 
> --   Put(A.Y);   -- should print 5
> --   New_Line;
> 
> end Hello;
> 
> 
> What is the correct way to achieve the declaration of A with the 
> possibility of changing the discriminant later? One of the ways is to 
> use *some* default value for the discriminant, but I might have 
> difficulty deciding which value is better than the others for this role. 
> An arbitrary choice would create a misleading message to the reader that 
> the particular value is considered to be "best" or "idle" or "starting" 
> or whatever. 
Providing a default value for the discriminant is the way to achieve 
this. Why this rule? Here is how it goes:
1) You want to declare a "mutable" (unconstrained) object:
    A : Discriminated;
2) A discriminant is too important to be left uninitialized
3) Therefore, declaring unconstrained objects is allowed only if the 
discriminants have default values. QED.

> In addition, having a default value for the discriminant 
> means that it's not obligatory to initialize the variable A while it's 
> declared and I would like to keep this enforced.
> 
Oh, I see your confusion here. You are not required to initialize your 
variable even if you don't provide default values for the discriminants, 
you just need to state the constraint:
   A : Discriminated (First);

In the form you use, the constraint comes from the initial value which 
makes it "look" unconstrained. BTW, such a declaration was not allowed 
(for variables) in Ada83.

You can force initialization of variables by giving it unknown 
discriminants, but the type has to be private. If you don't mind a 
run-time rather than compile-time check, you can do the following:

function Raise_PE return integer is
begin
    raise Program_Error;
    return 1; -- Required by the compiler
end;

type Must_Be_Initialized is
    record
       Junk : integer := Raise_PE;
       ...
    end record;
-- 
---------------------------------------------------------
            J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Correct use of variants
  2005-11-07 10:32 Correct use of variants Maciej Sobczak
  2005-11-07 12:52 ` Jean-Pierre Rosen
@ 2005-11-07 19:46 ` Jeffrey R. Carter
  2005-11-07 23:40 ` Stephen Leake
  2 siblings, 0 replies; 5+ messages in thread
From: Jeffrey R. Carter @ 2005-11-07 19:46 UTC (permalink / raw)


Maciej Sobczak wrote:
> 
> What is the correct way to achieve the declaration of A with the 
> possibility of changing the discriminant later? One of the ways is to 
> use *some* default value for the discriminant, but I might have 
> difficulty deciding which value is better than the others for this role. 
> An arbitrary choice would create a misleading message to the reader that 
> the particular value is considered to be "best" or "idle" or "starting" 
> or whatever. In addition, having a default value for the discriminant 
> means that it's not obligatory to initialize the variable A while it's 
> declared and I would like to keep this enforced.

Note that having a non-defaulted discriminant does not require initialization:

A : Discriminated (Which => First);

There was a thread on here a while ago about requiring and enforcing 
initialization; you might want to search for it. The options included using 
unknown discriminants with an initializing function; using a controlled type; 
and using a private type with a default initialized field that indicates that 
the object has not been initialized, an operation that initializes objects of 
the type and indicates that they have been initialized, and all other operations 
raising an exception if the value indicates a lack of initialization.

-- 
Jeff Carter
"Sir Lancelot saves Sir Gallahad from almost certain temptation."
Monty Python & the Holy Grail
69



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Correct use of variants
  2005-11-07 10:32 Correct use of variants Maciej Sobczak
  2005-11-07 12:52 ` Jean-Pierre Rosen
  2005-11-07 19:46 ` Jeffrey R. Carter
@ 2005-11-07 23:40 ` Stephen Leake
  2005-11-08  8:40   ` Maciej Sobczak
  2 siblings, 1 reply; 5+ messages in thread
From: Stephen Leake @ 2005-11-07 23:40 UTC (permalink / raw)


Maciej Sobczak <no.spam@no.spam.com> writes:

> What is the correct way to achieve the declaration of A with the
> possibility of changing the discriminant later? One of the ways is to
> use *some* default value for the discriminant, 

That is the only way.

> but I might have difficulty deciding which value is better than the
> others for this role. 

It makes absolutely no difference. The syntax makes it look like you
are giving a default value to the discriminant, but it doesn't matter
what value you put; it will never be used.

> An arbitrary choice would create a misleading message to the reader
> that the particular value is considered to be "best" or "idle" or
> "starting" or whatever. 

I usually use:

type Foo_Type (descrim : Descrim_Type := Descrim_Type'first) is ...;

to indicate that I don't care what the default descriminant is.

> In addition, having a default value for the discriminant means that
> it's not obligatory to initialize the variable A while it's declared
> and I would like to keep this enforced.

Other posts have addressed this.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Correct use of variants
  2005-11-07 23:40 ` Stephen Leake
@ 2005-11-08  8:40   ` Maciej Sobczak
  0 siblings, 0 replies; 5+ messages in thread
From: Maciej Sobczak @ 2005-11-08  8:40 UTC (permalink / raw)


Stephen Leake wrote:

>>but I might have difficulty deciding which value is better than the
>>others for this role. 
> 
> It makes absolutely no difference. The syntax makes it look like you
> are giving a default value to the discriminant, but it doesn't matter
> what value you put; it will never be used.

Yes, it will be used:

type Discriminated(Which : Chooser := First) is -- ...

A : Discriminated;

-- later:

Put(A.X); -- OK, because the First part is in use,
           -- even though X is not initialized (you get garbage)

Put(A.Y); -- CONSTRAINT_ERROR at run-time


> I usually use:
> 
> type Foo_Type (descrim : Descrim_Type := Descrim_Type'first) is ...;
> 
> to indicate that I don't care what the default descriminant is.

Indeed, looks to be self-documenting.


Thank you for this and other responses.

-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-11-08  8:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-11-07 10:32 Correct use of variants Maciej Sobczak
2005-11-07 12:52 ` Jean-Pierre Rosen
2005-11-07 19:46 ` Jeffrey R. Carter
2005-11-07 23:40 ` Stephen Leake
2005-11-08  8:40   ` Maciej Sobczak

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