[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