[fpc-devel] "case" with range stupidities
Vinzent Hoefler
JeLlyFish.software at gmx.net
Thu Feb 15 15:20:11 CET 2007
On Thursday 15 February 2007 13:36, Daniƫl Mantione wrote:
> Op Thu, 15 Feb 2007, schreef Vinzent Hoefler:
> > Well, fair enough, but why is that I can declare a
> >
> > type
> > Foo = array[byte] of Something;
> >
> > where the type name "byte" also indicates the range? Considering
> > that
> >
> > type
> > Foo = array[Low (byte) .. High (byte) of Something;
> >
> > is totally equivalent, the allowed usage of range types seems a
> > little bit inconsistent...
>
> Yes, but as I said, case labels are a set, not just a range:
>
> const x=[0,1,5];
>
> type foo=array[x] of something
>
> ...would again be rather weird.
It would be, yes. It even seems constants can't be used in an array type
declaration at all (well, not in a way different from defining the
lower and upper bound, I mean) and
const
X = 0 .. 5;
does not work either while "type X = (Zero, One, Five)" would do both
cases. ;)
So in short: it seems a range type like "byte" can be used where a
"pure" range is expected, but it cannot be used where a set is expected
(like for a case label, even though there a set constant would not be
accepted either):
-- 8< --
type
X = (Zero, One, Five);
var
Bla : X;
const
Foobar = [Zero, One];
begin
Bla := Five;
case Bla of
Low (Foobar) .. High (Foobar) : WriteLn ('Less than Five.');
// The following two lines don't work, of course.
//Foobar : WriteLn ('NO.');
//[Foobar] : WriteLn ('NO.');
else
WriteLn ('More than One, I guess.');
end {case};
// A real set operation.
if Bla in Foobar then
WriteLn ('Really less than Five.')
else
WriteLn ('Wrong. It is NOT less than five!');
end.
-- 8< --
So if the case label is considered a set why can't I use a set constant
(see the commented lines above) and if I do the range thing, which
compiles, it does not consider the value of the constant but rather the
range of its /type/...?
Seems to me that case labels are very special things, at least.
Another oddity would be a for loop:
for Bla := One to Five do ...
would be a range only, yes? (Apart from the fact that - due to the "to"
keyword - really isn't).
So wouldn't it be easier to write
| for Bla := X do ...
here, when X is some range type, I'd like to iterate over? Again I have
to Write "Low (X) to High (X)" quite similar to the "case" case.
I suppose changing that behaviour regarding range types is not an option
at all, so I'd ask for some other improvement:
*deep breath*
What about a compiler built-in like Low() and High() called Range()
where its return type indicates something that would be compatible to a
case and for label and just denote the range of the whole type?
Basically a short cut to the "Low (Type) ..|to High (Type)" expression,
but without the possible pitfall of writing
Low (Type) .. High (A_Similar_And_Unfortunately_Compatible_Type)
and thus being less error-prone...?
I mean, doing:
|for Bla := Range (X) do
or
|case Bla in
|Range (X): ...
doesn't actually look unreadable to me...
Regards,
Vinzent.
More information about the fpc-devel
mailing list