comp.lang.ada
 help / color / mirror / Atom feed
From: Jeffrey Carter <spam@spam.com>
Subject: Re: Why should the value for a discriminant be static?
Date: Thu, 10 Feb 2005 00:19:00 GMT
Date: 2005-02-10T00:19:00+00:00	[thread overview]
Message-ID: <ULxOd.4427$mG6.1381@newsread1.news.pas.earthlink.net> (raw)
In-Reply-To: <420A6FA5.9040802@nowhere.fi>

Niklas Holsti wrote:

> I agree with the safety advantages of the static rule, but I have often 
> wished that an aggregate would allow an expression with a statically 
> known subtype as the discriminant *when* this subtype uniquely 
> determines the set of components. For example:
> 
>    type Days is (
>       Monday, Tuesday, Wednesday, Thursday, Friday,
>       Saturday, Sunday);
> 
>    subtype Busy_Days is Days range Monday .. Friday;
>    subtype Idle_Days is Days range Saturday .. Sunday;
> 
>    type Activity (Day : Days) is record
>       case Day is
>       when Busy_Days => Work : Work_Type;
>       when Idle_Days => Play : Play_Type;
>       end case;
>    end record;
> 
>    function Do_A_Job (Today : Busy_Days; Job : Work_Type)
>    return Activity
>    is
>    begin
>       return (
>          Day  => Today, -- Statically known to be in Busy_Days,
>          Work => Job);  -- therefore this component exists.
>    end Do_A_Job;

In simple terms, this design if faulty. It's easy to argue otherwise for 
this simple example (7 enumeration values and 2 variants), but I've seen 
real world examples where it's harder to argue this way. One had over 
200 enumeration values and about 10 variants.

I argued in that case that they really needed 11 types: and enumeration 
type for the discriminant with about 10 values, and 10 other types, one 
for each variant to contain the specific information for the variant. 
That level of code modification was considered unacceptable, so I 
pointed them to the local result variable alternative:

function F (Day : Busy_Days; Work : Works)
return Activities -- Let's use a consistent naming policy :)
is
    Result : Activities (Day => Day);
begin -- F
    Result.Work := Work;
    return Result;
end F;

Of course, they really had a parameter of type Days, and had to build 
results for every variant, for much larger variants, so this got pretty 
hairy.

For your particular example, I would always recommend a type for the 
discriminant:

type Day_Kind_ID is (Busy_Day, Idle_Day);

You could have 2 types for the actual day in question, or a single type 
with 2 subtypes; to differ from your example as much as possible, let's 
choose the former:

type Busy_Day_Name is (Monday, Tuesday, Wednesday, Thursday, Friday);
type Idle_Day_Name is (Saturday, Sunday);

type Activity_Info (Day_Kind : Day_Kind_ID) is record
    case Day_Kind is
    when Busy_Day =>
       Work_Day : Busy_Day_Name;
       Work     : Work_Info;
    when Idle_Day =>
       Play_Day : Idle_Day_Name;
       Play     : Play_Info;
    end case;
end record;

Then your function would be

function F (Day : Busy_Day_Name; Work : Work_Info) return Activity_Info
is
    -- null;
begin -- F
    return Activity_Info'(Day_Kind => Busy_Day, -- Static.
                          Work_Day => Day,
                          Work     => Work);
end F;

-- 
Jeff Carter
"My mind is aglow with whirling, transient nodes of
thought, careening through a cosmic vapor of invention."
Blazing Saddles
85



  reply	other threads:[~2005-02-10  0:19 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-09 14:30 Why should the value for a discriminant be static? Jacob Sparre Andersen
2005-02-09 18:34 ` Randy Brukardt
2005-02-09 20:16   ` Niklas Holsti
2005-02-10  0:19     ` Jeffrey Carter [this message]
2005-02-10 13:11       ` Niklas Holsti
2005-02-11  1:40         ` Jeffrey Carter
2005-02-11  7:52           ` Niklas Holsti
2005-02-09 22:22   ` Jacob Sparre Andersen
replies disabled

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