comp.lang.ada
 help / color / mirror / Atom feed
* Implementing an elegant range type.
@ 2001-03-19 17:45 Chad R. Meiners
  2001-03-19 18:38 ` Mark Lundquist
  2001-03-21 22:55 ` Implementing an elegant range type Chad R. Meiners
  0 siblings, 2 replies; 15+ messages in thread
From: Chad R. Meiners @ 2001-03-19 17:45 UTC (permalink / raw)


There are certain times that I have wanted to pass ranges as a
parameter to subroutines, for example being able to
write, "Register_Slots (75..4242);" which of course isn't directly
allowed.  The solution I came up with is to declare a null type that
doesn't take up any memory so that I can create array type of the
ranges I want as in the example below.

type Nothing is null record;
for  Nothing'Size use 0;

type Integer_Range_Type is array (Integer range <>) of Nothing;

Thus I could declare an array, "Integer_Range : Integer_Range_Type
(Integer);", and use it to pass array slice which would contain the
range data.  Example: "Register_Slots (Integer_Range(75..4242));"

The problem I am encountering is that when I declare a variable
with a range as large as Integer_Range's I get a
Storage_Error which doesn't make much sense since if Integer_Range's
range is something smaller than 2**20 elements, Integer_Range'Size
equals 8 for all cases which I expect should be true even for the
large cases since the elements of the array have no size.  I am
using GNAT 3.13p on WinNT.

Has anyone used a similar approach for representing ranges or have
any advice on getting around the Storage_Error for large ranges?

Thank you,
-Chad R. Meiners





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

* Re: Implementing an elegant range type.
  2001-03-19 17:45 Implementing an elegant range type Chad R. Meiners
@ 2001-03-19 18:38 ` Mark Lundquist
  2001-03-19 20:50   ` Chad R. Meiners
  2001-03-20  4:48   ` Dr Adrian Wrigley
  2001-03-21 22:55 ` Implementing an elegant range type Chad R. Meiners
  1 sibling, 2 replies; 15+ messages in thread
From: Mark Lundquist @ 2001-03-19 18:38 UTC (permalink / raw)



Chad R. Meiners <crmeiners@hotmail.com> wrote in message
news:3ab6442f.0@silver.truman.edu...
> There are certain times that I have wanted to pass ranges as a
> parameter to subroutines, for example being able to
> write, "Register_Slots (75..4242);" which of course isn't directly
> allowed.  The solution I came up with is to declare a null type that
> doesn't take up any memory so that I can create array type of the
> ranges I want as in the example below.
>
> type Nothing is null record;
> for  Nothing'Size use 0;
>
> type Integer_Range_Type is array (Integer range <>) of Nothing;
>
> Thus I could declare an array, "Integer_Range : Integer_Range_Type
> (Integer);", and use it to pass array slice which would contain the
> range data.  Example: "Register_Slots (Integer_Range(75..4242));"

OK... how does this relate to your subject line, "Implementing an _elegant_
range type"? (emphasis mine) :-) :-) :-)

Looks like you blew past the last "Warning: Entering Kludge Zone" sign a few
miles back! :-)  Aren't you going to extreme lengths just to implement an
"ordered pair" abstraction in a non-idiomatic way?  And why... to be able to
use the ".." notation?  It doesn't seem worth the contortions to me!  Maybe
I'm missing something... if so, please clarify!

Why not just write:

    type Integer_Range is record
        First, Last : Integer;
    end record;

Then you'd be able to say (taking up your example):

    Register_Slots (Integer_Range'(75, 4242));

or

    Register_Slots ((First => 75, Last => 4242));

You can quite easily write

    function Length (Of : Integer_Range);

(or call it "Extent" or whatever) to give the effect of 'Length as you might
have used it with the Integer_Range_Type kludge.

Your Integer_Range_Type solution is kind of clever, but it's not readily
understandable... if I had to deal with some code written with this style of
representing ranges, it would take me a while (even with comments) to figure
out what in the world the Maximum Array Of Nothings is for and why we are
passing around slices of it.  And when I did figure it out, I would be
annoyed :-)

OK, so much for my $.04 (adjusted for inflation :-) worth of unsolicited
advice :-)

>
> The problem I am encountering is that when I declare a variable
> with a range as large as Integer_Range's I get a
> Storage_Error which doesn't make much sense since if Integer_Range's
> range is something smaller than 2**20 elements, Integer_Range'Size
> equals 8 for all cases which I expect should be true even for the
> large cases since the elements of the array have no size.  I am
> using GNAT 3.13p on WinNT.
>
> Has anyone used a similar approach for representing ranges or have
> any advice on getting around the Storage_Error for large ranges?

I don't understand the Size attribute well enough to be of much help here...
I just have not given it enough study.  I don't know of any language rule
that would require GNAT to do what it's doing, but that doesn't mean there
isn't one.  Or maybe it's a GNAT bug.  But most likely it's just something
that the implementation has every right to do.  Like I said, I don't really
know.

But... you might try playing with 'Size of the array type, 'Size of the
array object, and 'Component_Size.  If nothing else, the error messages may
be illuminating.

Mark Lundquist
Rational Software






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

* Re: Implementing an elegant range type.
  2001-03-19 18:38 ` Mark Lundquist
@ 2001-03-19 20:50   ` Chad R. Meiners
  2001-03-22 22:20     ` Nick Roberts
  2001-03-20  4:48   ` Dr Adrian Wrigley
  1 sibling, 1 reply; 15+ messages in thread
From: Chad R. Meiners @ 2001-03-19 20:50 UTC (permalink / raw)



"Mark Lundquist" <mark@rational.com> wrote in message
news:7nst6.593482$U46.17851651@news1.sttls1.wa.home.com...
>
> Chad R. Meiners <crmeiners@hotmail.com> wrote in message
> news:3ab6442f.0@silver.truman.edu...
> > There are certain times that I have wanted to pass ranges as a
> > parameter to subroutines, for example being able to
> > write, "Register_Slots (75..4242);" which of course isn't directly
> > allowed.  The solution I came up with is to declare a null type that
> > doesn't take up any memory so that I can create array type of the
> > ranges I want as in the example below.
> >
> > type Nothing is null record;
> > for  Nothing'Size use 0;
> >
> > type Integer_Range_Type is array (Integer range <>) of Nothing;
> >
> > Thus I could declare an array, "Integer_Range : Integer_Range_Type
> > (Integer);", and use it to pass array slice which would contain the
> > range data.  Example: "Register_Slots (Integer_Range(75..4242));"
>
> OK... how does this relate to your subject line, "Implementing an
_elegant_
> range type"? (emphasis mine) :-) :-) :-)

Well I am searching for the best solution for Implementing an elegant
range type.  The example I gave is a candidate I am evaluating.

> Looks like you blew past the last "Warning: Entering Kludge Zone" sign a
few
> miles back! :-)  Aren't you going to extreme lengths just to implement an
> "ordered pair" abstraction in a non-idiomatic way?  And why... to be able
to
> use the ".." notation?  It doesn't seem worth the contortions to me!
Maybe
> I'm missing something... if so, please clarify!

I don't it is fair to say that I blew past any warning signs.

Ranges in Ada are not types but they have operators such as "in" so they are
sort of a psuedo-type.  It occured that since ranges are a part of every
array,
passing a array of null elements is logically equivalent to passing a range.
I am conducting a controlled experiment in using null arrays to represent
ranges
in a more tangible form.


> Why not just write:
>
>     type Integer_Range is record
>         First, Last : Integer;
>     end record;
>
> Then you'd be able to say (taking up your example):
>
>     Register_Slots (Integer_Range'(75, 4242));
>
> or
>
>     Register_Slots ((First => 75, Last => 4242));
>
> You can quite easily write
>
>     function Length (Of : Integer_Range);
>
> (or call it "Extent" or whatever) to give the effect of 'Length as you
might
> have used it with the Integer_Range_Type kludge.

Of course that is the standard solution of making an ADT range type which
is entirely independent of Ada's ranges.  I have always found this solution
unsatifying since it is adds too much complexity to the code that makes use
of
it.  For example, the operator I want to use is "in" and not "Length".  I
want to be
able to write "If x in Switches_To_Be_Reserved'Range then ..." as opposed to
"If In(X,Switches_To_Be_Reserved) then ..." since the first seems to be the
more
consistant and readable approach.  With my approach all a programmer needs
to do is
declare an array type of "Nothing", and he/she gets the semantics and
operations
of the language automatically.

> Your Integer_Range_Type solution is kind of clever, but it's not readily
> understandable... if I had to deal with some code written with this style
of
> representing ranges, it would take me a while (even with comments) to
figure
> out what in the world the Maximum Array Of Nothings is for and why we are
> passing around slices of it.  And when I did figure it out, I would be
> annoyed :-)

I like this comment because it shows me why you perceive the solution as a
kludge :)

I freely admit that this solution is unusual.  That is why I haven't use it
in any real program.  Instead I am carefully examining its potentional as a
useful and elegant solution to a problem domain (What to do if you need to
pass (or return) a range of some type from a subroutine).

From your above arguement, I gather that your criticism is rooted with the
fact that the solution is unusual.  The problem with unusual solutions is
that
they often violate the limitations people place on the language.  One such
violation is the usage of an array to be a psuedo-function that returns a
requested range.  The other violation is that the elements of the array are
completely unimportant.

Perhaps we as a community should use this solution to as ourselves why we
place these limitations on a language as rich as Ada.  Is it simply baggage
brought over from previous experiences with other language?  If not why
should
these limitation be absolute?  It appears to me that this solution reduces
complexity by using semantics given by the langauge as oppose to having to
define
them independently.  The only problem is that is unusual which can be solved
by
making it publicly know and understood.

> OK, so much for my $.04 (adjusted for inflation :-) worth of unsolicited
> advice :-)

Thank you for volunteering your opinion.  It was my hope that I would
get some useful information and opinions to my question.

> >
> > The problem I am encountering is that when I declare a variable
> > with a range as large as Integer_Range's I get a
> > Storage_Error which doesn't make much sense since if Integer_Range's
> > range is something smaller than 2**20 elements, Integer_Range'Size
> > equals 8 for all cases which I expect should be true even for the
> > large cases since the elements of the array have no size.  I am
> > using GNAT 3.13p on WinNT.
> >
> > Has anyone used a similar approach for representing ranges or have
> > any advice on getting around the Storage_Error for large ranges?
>
> I don't understand the Size attribute well enough to be of much help
here...
> I just have not given it enough study.  I don't know of any language rule
> that would require GNAT to do what it's doing, but that doesn't mean there
> isn't one.  Or maybe it's a GNAT bug.  But most likely it's just something
> that the implementation has every right to do.  Like I said, I don't
really
> know.
>
> But... you might try playing with 'Size of the array type, 'Size of the
> array object, and 'Component_Size.  If nothing else, the error messages
may
> be illuminating.
>
> Mark Lundquist
> Rational Software

-Chad R. Meiners





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

* Re: Implementing an elegant range type.
  2001-03-19 18:38 ` Mark Lundquist
  2001-03-19 20:50   ` Chad R. Meiners
@ 2001-03-20  4:48   ` Dr Adrian Wrigley
  2001-03-20 15:31     ` Robert A Duff
  1 sibling, 1 reply; 15+ messages in thread
From: Dr Adrian Wrigley @ 2001-03-20  4:48 UTC (permalink / raw)


Mark Lundquist wrote:
...
> Looks like you blew past the last "Warning: Entering Kludge Zone" sign a few
> miles back! :-)  Aren't you going to extreme lengths just to implement an
> "ordered pair" abstraction in a non-idiomatic way?
...
> Your Integer_Range_Type solution is kind of clever, but it's not readily
> understandable... if I had to deal with some code written with this style of
> representing ranges, it would take me a while (even with comments) to figure
> out what in the world the Maximum Array Of Nothings is for and why we are
> passing around slices of it.  And when I did figure it out, I would be
> annoyed :-)

When I saw the title to the article, I thought it was someone who, like me,
had hit this problem, but had only found the obvious but verbose and
non-idiomatic solutions.

Seeing what Chad had devised, I also thought "that's kind of clever",
(I wish I had thought of it!),  and if Chad's solution were widely used,
people would know exactly what is going on and why, and not worry too much
(at least I wouldn't).

I see no reason why ranges couldn't be elevated to the status of any other type
(in Ada 0y), but I am not a language lawyer.  In fact, it was one of the
things already in my list of features I would like considered.  Presumably, the
issue here is the low demand for such a feature, and the availability
(inelegant) of work-arounds. (could we have reverse [downto] ranges
for arrays, like in VHDL please, while we're about it?).

I think Chad's problem with GNAT is similar to the problems I have been
having with Storage_Errors attempting to declare and/or use large arrays,
for which I have only been able to come up with ugly hacks to avoid.

Chad's inventiveness is to be commended IMHO!  Ranges as first class
types have richer semantics than simply an ordered pair, and if there
were a "standard" way to declare and use ranges as Chad seeks, I'd
be happy to use it on the (relatively few) occasions where appropriate.

I would also like a way of handling multi-dimensional ranges and values as
a single item (eg for addressing arrays in generic code), but this
is probably a little off topic.
--
Adrian Wrigley



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

* Re: Implementing an elegant range type.
  2001-03-20  4:48   ` Dr Adrian Wrigley
@ 2001-03-20 15:31     ` Robert A Duff
  2001-03-21  1:21       ` Dr Adrian Wrigley
  0 siblings, 1 reply; 15+ messages in thread
From: Robert A Duff @ 2001-03-20 15:31 UTC (permalink / raw)


Dr Adrian Wrigley <amtw@linuxchip.demon.co.uk> writes:

>...(could we have reverse [downto] ranges
> for arrays, like in VHDL please, while we're about it?).

What does it mean?

- Bob



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

* RE: Implementing an elegant range type.
@ 2001-03-20 20:17 Beard, Frank
  0 siblings, 0 replies; 15+ messages in thread
From: Beard, Frank @ 2001-03-20 20:17 UTC (permalink / raw)
  To: 'comp.lang.ada@ada.eu.org'


-----Original Message-----
From: Chad R. Meiners [mailto:crmeiners@hotmail.com]

>> Why not just write:
>>
>>     type Integer_Range is record
>>         First, Last : Integer;
>>     end record;
>>

> For example, the operator I want to use is "in" and not "Length".
> I want to be able to write "If x in Switches_To_Be_Reserved'Range then
..." 

Whether you use Mark's example above, or pass in the First and Last 
as parameters, you can still write the following:


   Assuming "Reserved_Range : in Integer_Range", as the formal argument
passed in.

   if x in Reserved_Range.First .. Reserved_Range.Last then ...


or, using Range_First and Range_Last as the formal parameters:

   Range_First : in integer;
   Range_Last  : in integer;

   if x in Range_First .. Range_Last then ...


I agree it might be slightly more elegant to pass a single parameter
so that the statement would be:

   if x in Reserved_Range then

but you're only saving one parameter, since "in" works for discrete types.

Frank




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

* Re: Implementing an elegant range type.
  2001-03-20 15:31     ` Robert A Duff
@ 2001-03-21  1:21       ` Dr Adrian Wrigley
  2001-03-21  3:58         ` Brian Rogoff
  2001-03-22 23:00         ` Array 'downto' [Was: Implementing an elegant range type] Nick Roberts
  0 siblings, 2 replies; 15+ messages in thread
From: Dr Adrian Wrigley @ 2001-03-21  1:21 UTC (permalink / raw)


Robert A Duff wrote:
> 
> Dr Adrian Wrigley <amtw@linuxchip.demon.co.uk> writes:
> 
> >...(could we have reverse [downto] ranges
> > for arrays, like in VHDL please, while we're about it?).
> 
> What does it mean?
> 
> - Bob

A fairly long post about various VHDL issues in relation to Ada...

In VHDL, one typically writes things like:

------------------------------------
-- "downto" example
type Byte is array (Integer range 7 downto 0) of Std_Logic;

-- In this case, "Byte" has the following attributes:
-- 
-- Byte'Low   = 0
-- Byte'High  = 7
-- Byte'Left  = 7
-- Byte'Right = 0

for I in Byte'range loop
-- counts from 7 to 0!
end loop;
-----------------------------------
-- "to" example
type Octet is array (Integer range 0 to 7) of Std_Logic;

-- In this case, "Octet" has the following attributes:
--
-- Octet'Low   = 0    Octet'High  = 7
-- Octet'Left  = 0    Octet'Right = 7

for I in Octet'range loop
-- counts from 0 to 7
end loop;
-----------------------------------
There is no 'First or 'Last attribute (as far as I remember!).

You can also define integer types with "downto", similarly.

Why?

It seems to be so that programs that do I/O on arrays can display
the most significant parts first.  VHDL simulators display the
'Left element first (on the left), and the 'Right last.

In the case of "Byte", therefore, bits are shown with bit 7 on the
left as people expect.  "Octet" would be displayed with bit 7 on
the right.  Conversion routines exist in standard libraries
that convert to and from integers.  I think they always take
the 'Left value to be the MSB.

When people declare arrays of values (not to be treated as bits
in a byte), they usually want the lowest indexed value on the left.
It is normal, therefore to represent (eg) a four byte register file
as:

type RegisterFile is array (0 to 3) of Std_Logic_Vector (7 downto 0);

which will then be displayed in a simulator in the manner people
expect (bytes in ascending order, bits in descending order).

Are there any other reasons?
--
I remember a time when most manufacturers' data sheets labeled bits
0 .. 7, where bit 0 was the LSB.  But Texas Instruments tended to
label bits from 1 to 8 with bit 8 being the LSB.  The VHDL approach
allows users to use whichever convention is appropriate.  Now,
however, everyone (including TI) seems to use the "7 downto 0" style.
--
Why would I like it in Ada 0y?

Simply to bring the languages even close together -  I used to switch
between the two quite frequently, and being almost, but not quite
identical syntax is annoying.

I also have written a VHDL -> Ada translator,  which has the potential
to allow hardware designs to migrate easily to software.
Handling of "downto" in array indices is not trivial, and I have left
this (very important!) feature out.  Does anyone else out there
use or have translators between the two languages?

I can also see application for Ada -> VHDL translation, but this
really has to be limited to a subset in practice (no dynamic creation
of tasks, exceptions or generic subprogram parameters in VHDL).

One unnecessary difference in VHDL is that variables are declared
with the keyword "variable", as in

variable X : Integer;

This should be omitted, and signals be declared "X : signal Integer;",
but this is probably not the right group to complain about VHDL syntax!
--
Since VHDL is one of the worlds most succesful hardware languages,
I think it has the potential to help introduce Ada to many
engineers largely unaware of its existence.   The numerous colleges
that teach VHDL could easily justify teaching Ada95 as the
"software counterpart".  The benefits of "the Ada way" are very
apparent when co-designing hardware and software using VHDL and C,
where it is routine to find the VHDL clarity and type checking
show how inefficient development in "C style" languages really is.
There are some, however, who advocate using "C style" languages
for hardware design, since people can leverage their familarity
with C in the learning process.  I do not agree with that approach.

Hope this sheds some light on Ada's relationship to VHDL as seen
by someone who has used both extensively in commerce (am I alone?).
--
Adrian Wrigley



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

* Re: Implementing an elegant range type.
  2001-03-21  1:21       ` Dr Adrian Wrigley
@ 2001-03-21  3:58         ` Brian Rogoff
  2001-03-22 23:00         ` Array 'downto' [Was: Implementing an elegant range type] Nick Roberts
  1 sibling, 0 replies; 15+ messages in thread
From: Brian Rogoff @ 2001-03-21  3:58 UTC (permalink / raw)


On Wed, 21 Mar 2001, Dr Adrian Wrigley wrote:
> I also have written a VHDL -> Ada translator,  which has the potential
> to allow hardware designs to migrate easily to software.
> Handling of "downto" in array indices is not trivial, and I have left
> this (very important!) feature out.  Does anyone else out there
> use or have translators between the two languages?

Nope, but such translators going either or both ways would be very useful. 
Believe it or not, I'm actually more of a Verilog guy (in Silicon Valley 
VHDL is not widely used) but I've definitely thought Ada had a lot of
potential here. It might be too late as C/C++ based hardware modeling is 
getting lots of press.

> I can also see application for Ada -> VHDL translation, but this
> really has to be limited to a subset in practice (no dynamic creation
> of tasks, exceptions or generic subprogram parameters in VHDL).

Have you seen Peter Ashenden's SUAVE enhancements to VHDL? It pretty much
makes VHDL into Ada 95.

> Since VHDL is one of the worlds most succesful hardware languages,
> I think it has the potential to help introduce Ada to many
> engineers largely unaware of its existence.   The numerous colleges
> that teach VHDL could easily justify teaching Ada95 as the
> "software counterpart".  The benefits of "the Ada way" are very
> apparent when co-designing hardware and software using VHDL and C,
> where it is routine to find the VHDL clarity and type checking
> show how inefficient development in "C style" languages really is.
> There are some, however, who advocate using "C style" languages
> for hardware design, since people can leverage their familarity
> with C in the learning process.  I do not agree with that approach.

I think Ada will be playing catch up, but it is a good idea. 

> Hope this sheds some light on Ada's relationship to VHDL as seen
> by someone who has used both extensively in commerce (am I alone?).

I'm with you in spirit, but Verilog is overwhelmingly more popular in the 
US and Japan than VHDL.

-- Brian





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

* RE: Implementing an elegant range type.
@ 2001-03-21 13:00 Francisco Javier Loma Daza
  0 siblings, 0 replies; 15+ messages in thread
From: Francisco Javier Loma Daza @ 2001-03-21 13:00 UTC (permalink / raw)
  To: comp.lang.ada; +Cc: 'comp.lang.ada@ada.eu.org'

El 20 Mar 2001 15:17:29 -0500, Beard, Frank escribi�:
> 
> -----Original Message-----
> From: Chad R. Meiners [mailto:crmeiners@hotmail.com]
> 
> >> Why not just write:
> >>
> >>     type Integer_Range is record
> >>         First, Last : Integer;
> >>     end record;
> >>
> 
> > For example, the operator I want to use is "in" and not "Length".
> > I want to be able to write "If x in Switches_To_Be_Reserved'Range then
> ..." 
> 
> Whether you use Mark's example above, or pass in the First and Last 
> as parameters, you can still write the following:
> 
> 
>    Assuming "Reserved_Range : in Integer_Range", as the formal argument
> passed in.
> 
>    if x in Reserved_Range.First .. Reserved_Range.Last then ...
> 
> 
> or, using Range_First and Range_Last as the formal parameters:
> 
>    Range_First : in integer;
>    Range_Last  : in integer;
> 
>    if x in Range_First .. Range_Last then ...
> 
> 
> I agree it might be slightly more elegant to pass a single parameter
> so that the statement would be:
> 
>    if x in Reserved_Range then
> 
> but you're only saving one parameter, since "in" works for discrete types.
> 
> Frank


    This is an interesting way to do range operations. I would like to
    do this one:

    function Iterator(this: Container.Object) return Container.Range;


    declare
        r: Container.Range := Iterator(list);
    begin
        for x in r'Range loop
            Process(Item(list, x));
        end loop;
    end;

    ...... even better

            Process(list(x)); -- :-)







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

* Re: Implementing an elegant range type.
  2001-03-19 17:45 Implementing an elegant range type Chad R. Meiners
  2001-03-19 18:38 ` Mark Lundquist
@ 2001-03-21 22:55 ` Chad R. Meiners
  1 sibling, 0 replies; 15+ messages in thread
From: Chad R. Meiners @ 2001-03-21 22:55 UTC (permalink / raw)


Given that there is some interest in this solution, I
have constructed a package that allows you to instantiate
a range type from a generic package.  I believe that it is
documented well enough to avoid the confusion that Mark
was worried about (if you wouldn't mind looking at it Mark
and telling me what you think ;).

You can play around with it and tell me what you think of it.
It can be downloaded at http://adapower.net/~cmeiners/ranges/ranges.zip

Thank you,
Chad R. Meiners





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

* Re: Implementing an elegant range type.
  2001-03-19 20:50   ` Chad R. Meiners
@ 2001-03-22 22:20     ` Nick Roberts
  2001-03-23 22:29       ` Brian Rogoff
  0 siblings, 1 reply; 15+ messages in thread
From: Nick Roberts @ 2001-03-22 22:20 UTC (permalink / raw)


"Chad R. Meiners" <crmeiners@hotmail.com> wrote in message
news:3ab66f83.0@silver.truman.edu...
> ...
> Of course that is the standard solution of making an ADT range type which
> is entirely independent of Ada's ranges.  I have always found this
solution
> unsatifying since it is adds too much complexity to the code that makes
use
> of it.  For example, the operator I want to use is "in" and not "Length".
I
> want to be
> able to write "If x in Switches_To_Be_Reserved'Range then ..." as opposed
to
> "If In(X,Switches_To_Be_Reserved) then ..." since the first seems to be
the
> more
> consistant and readable approach.

What is always possible is:

   procedure Reserve_Switches (Lo, Hi: in Switch_Number; ...) is

      subtype Relevant_Switch is Switch_Number range Lo..Hi;

   begin
      ...
      if S1 not in Relevant_Switch then ...
      ...
      for S2 in Relevant_Switch loop
         ...
      etc...

Given the suggested ADT Switch_Range, the first two lines could have been:

   procedure Reserve_Switches (Which: in Switch_Range; ...) is

      subtype Relevant_Switch is Switch_Number range Which.Lo .. Which.Hi;

I realise this is not quite the nirvana you wish for, but I think it goes a
long way towards addressing your actual requirements, without the need for
any really new (and potentially confusing) idioms.

Perhaps this should be a FAQ?

--
Nick Roberts
http://www.AdaOS.org






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

* Array 'downto' [Was: Implementing an elegant range type]
  2001-03-21  1:21       ` Dr Adrian Wrigley
  2001-03-21  3:58         ` Brian Rogoff
@ 2001-03-22 23:00         ` Nick Roberts
  2001-03-26 18:28           ` Stephen Leake
  2001-03-28 22:35           ` Robert A Duff
  1 sibling, 2 replies; 15+ messages in thread
From: Nick Roberts @ 2001-03-22 23:00 UTC (permalink / raw)


I intend (eventually ;-) to provide a representation attribute for this
purpose, for array objects and types, in my compiler.

For any array object or type A, if

   A(n)'Reverse_Element_Order

of type Standard.Boolean, is False, the elements of the nth dimension of A
will be placed in memory with the element corresponding to the lowest index
value in the lowest memory address. If it is True, the elements will be
placed with the element corresponding to the highest index value in the
lowest memory address. The default will be False. The subscript can be
omitted for the first dimension.

Additionally, for any multidimensional array object or type A,

   pragma Convention(Fortran,A);

will cause the representation to be leftmost dimension varying fastest. All
other conventions will cause the representation to be rightmost dimension
varying fastest.

Other implementors should feel free to copy these ideas if they fancy. It
should be understood that for certain environments (e.g. a virtual machine),
they will be unimplementable.

I am toying with the idea of a pragma Split_Array, which, when applied to an
array object or type, causes the array to be placed in memory as a set of
arrays (called 'columns'), one for each indivisible subcomponent of the
array's component type. If this causes columns to have a convenient width
(e.g. a byte or word), it could make some accesses to the array much faster
(at the expense of making some other accesses more complicated and slower).
Split_Array would be a kindred pragma to Pack (but they would not be
mutually exclusive, as one may wish to pack the columns).

--
Nick Roberts
http://www.AdaOS.org






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

* Re: Implementing an elegant range type.
  2001-03-22 22:20     ` Nick Roberts
@ 2001-03-23 22:29       ` Brian Rogoff
  0 siblings, 0 replies; 15+ messages in thread
From: Brian Rogoff @ 2001-03-23 22:29 UTC (permalink / raw)


On Thu, 22 Mar 2001, Nick Roberts wrote:
> "Chad R. Meiners" <crmeiners@hotmail.com> wrote in message
> > Of course that is the standard solution of making an ADT range type which
> > is entirely independent of Ada's ranges.  I have always found this
> solution
> > unsatifying since it is adds too much complexity to the code that makes
> use
> > of it.

In essence you want ranges to be first class citizens of the language. I 
feel your pain. One of the most frustrating things about Ada is the
inability to have write code which uses the pleasant built in Ada syntax. 

> For example, the operator I want to use is "in" and not "Length".

Yup. 

> What is always possible is:
> 
>    procedure Reserve_Switches (Lo, Hi: in Switch_Number; ...) is
>       subtype Relevant_Switch is Switch_Number range Lo..Hi;
>    begin
>       ...
>       if S1 not in Relevant_Switch then ...
>       ...
>       for S2 in Relevant_Switch loop
>          ...
>       etc...
> 
> Given the suggested ADT Switch_Range, the first two lines could have been:
> 
>    procedure Reserve_Switches (Which: in Switch_Range; ...) is
> 
>       subtype Relevant_Switch is Switch_Number range Which.Lo .. Which.Hi;
> 
> I realise this is not quite the nirvana you wish for, but I think it goes a
> long way towards addressing your actual requirements, without the need for
> any really new (and potentially confusing) idioms.

I like Chad's solution better, and contrary to the opinions of another
poster I don't think it's a kludge, though of course it would be nice if 
Ada allowed us to handle ranges more flexibly. 

-- Brian





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

* Re: Array 'downto' [Was: Implementing an elegant range type]
  2001-03-22 23:00         ` Array 'downto' [Was: Implementing an elegant range type] Nick Roberts
@ 2001-03-26 18:28           ` Stephen Leake
  2001-03-28 22:35           ` Robert A Duff
  1 sibling, 0 replies; 15+ messages in thread
From: Stephen Leake @ 2001-03-26 18:28 UTC (permalink / raw)


"Nick Roberts" <nickroberts@adaos.worldonline.co.uk> writes:

> I intend (eventually ;-) to provide a representation attribute for this
> purpose, for array objects and types, in my compiler.
> 
> For any array object or type A, if
> 
>    A(n)'Reverse_Element_Order
> 
> of type Standard.Boolean, is False, the elements of the nth dimension of A
> will be placed in memory with the element corresponding to the lowest index
> value in the lowest memory address. If it is True, the elements will be
> placed with the element corresponding to the highest index value in the
> lowest memory address. The default will be False. The subscript can be
> omitted for the first dimension.

When would this be useful? You might use it to handle bit-endianness,
with an array of Boolean, but that seems like overkill.

> Additionally, for any multidimensional array object or type A,
> 
>    pragma Convention(Fortran,A);
> 
> will cause the representation to be leftmost dimension varying fastest. All
> other conventions will cause the representation to be rightmost dimension
> varying fastest.

This is already in the standard.

> I am toying with the idea of a pragma Split_Array, which, when applied to an
> array object or type, causes the array to be placed in memory as a set of
> arrays (called 'columns'), one for each indivisible subcomponent of the
> array's component type. If this causes columns to have a convenient width
> (e.g. a byte or word), it could make some accesses to the array much faster
> (at the expense of making some other accesses more complicated and slower).
> Split_Array would be a kindred pragma to Pack (but they would not be
> mutually exclusive, as one may wish to pack the columns).

I guess this is more power than I can have by re-arranging the data
structure myself, and hiding it behind an abstract interface, but it's
not clear.

-- 
-- Stephe



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

* Re: Array 'downto' [Was: Implementing an elegant range type]
  2001-03-22 23:00         ` Array 'downto' [Was: Implementing an elegant range type] Nick Roberts
  2001-03-26 18:28           ` Stephen Leake
@ 2001-03-28 22:35           ` Robert A Duff
  1 sibling, 0 replies; 15+ messages in thread
From: Robert A Duff @ 2001-03-28 22:35 UTC (permalink / raw)


"Nick Roberts" <nickroberts@adaos.worldonline.co.uk> writes:

> I intend (eventually ;-) to provide a representation attribute for this
> purpose, for array objects and types, in my compiler.
> 
> For any array object or type A, if
> 
>    A(n)'Reverse_Element_Order
> 
> of type Standard.Boolean, is False, the elements of the nth dimension of A
> will be placed in memory with the element corresponding to the lowest index
> value in the lowest memory address. If it is True, the elements will be
> placed with the element corresponding to the highest index value in the
> lowest memory address. The default will be False. The subscript can be
> omitted for the first dimension.

I've toyed with that idea myself, but I'm not sure what use it is in
practise.

> Additionally, for any multidimensional array object or type A,
> 
>    pragma Convention(Fortran,A);
> 
> will cause the representation to be leftmost dimension varying fastest. All
> other conventions will cause the representation to be rightmost dimension
> varying fastest.

For types, that's what the RM already says, and I think many compilers
implement it.  But it seems problematic for objects.  At least, you
would have to have various restrictions.  For example, if the array is a
by-reference type, you can't be representing different objects
differently, because you might pass them as parameters.  For a type that
allowed by-copy parameter passing, you could do a massive conversion on
parameter passing, I suppose.

> Other implementors should feel free to copy these ideas if they fancy. It
> should be understood that for certain environments (e.g. a virtual machine),
> they will be unimplementable.

I don't understand why.  I can see cases where they are unimplementable,
but I don't see what it has to do with the environment.

> I am toying with the idea of a pragma Split_Array, which, when applied to an
> array object or type, causes the array to be placed in memory as a set of
> arrays (called 'columns'), one for each indivisible subcomponent of the
> array's component type. If this causes columns to have a convenient width
> (e.g. a byte or word), it could make some accesses to the array much faster
> (at the expense of making some other accesses more complicated and slower).
> Split_Array would be a kindred pragma to Pack (but they would not be
> mutually exclusive, as one may wish to pack the columns).

I've pondered the same idea myself.  Basically, you are laying things
out "inside out" -- that is, you're turning (eg) an array of records
into a record of arrays.  It sounds awfully hard to get this right, in
general, and you will need certain restrictions.  Consider passing a
component of the array-of-records as a parameter -- you need to gin up a
record, but you can only do that if by-copy is allowed.  (Or if you're
willing to implement by-ref in an extraordinarily complicated and
inefficient manner.)

In the end, I decided this kind of thing isn't worth the trouble.
Let the programmer declare a record-of-arrays, if that's more
efficient.  And if that's ugly, hide the ugliness in a package body.

- Bob



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

end of thread, other threads:[~2001-03-28 22:35 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-03-19 17:45 Implementing an elegant range type Chad R. Meiners
2001-03-19 18:38 ` Mark Lundquist
2001-03-19 20:50   ` Chad R. Meiners
2001-03-22 22:20     ` Nick Roberts
2001-03-23 22:29       ` Brian Rogoff
2001-03-20  4:48   ` Dr Adrian Wrigley
2001-03-20 15:31     ` Robert A Duff
2001-03-21  1:21       ` Dr Adrian Wrigley
2001-03-21  3:58         ` Brian Rogoff
2001-03-22 23:00         ` Array 'downto' [Was: Implementing an elegant range type] Nick Roberts
2001-03-26 18:28           ` Stephen Leake
2001-03-28 22:35           ` Robert A Duff
2001-03-21 22:55 ` Implementing an elegant range type Chad R. Meiners
  -- strict thread matches above, loose matches on Subject: below --
2001-03-20 20:17 Beard, Frank
2001-03-21 13:00 Francisco Javier Loma Daza

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