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
next prev parent 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