comp.lang.ada
 help / color / mirror / Atom feed
* Re: Modular types inside records
  2000-10-21  0:00   ` Pawe� Niewiadomski
@ 2000-10-21  0:00     ` Jeff Carter
  2000-10-21  0:00       ` Pawe� Niewiadomski
  2000-10-23  0:00     ` Robert A Duff
  1 sibling, 1 reply; 11+ messages in thread
From: Jeff Carter @ 2000-10-21  0:00 UTC (permalink / raw)


"Pawe� Niewiadomski" wrote:
> generic
>     type item_type is private;
>     type mod_n_max is mod <>;
> package queues is
>     type queue is tagged private;
>     function empty (q: queue) return boolean;
>     function full (q: queue) return boolean;
>     procedure add (q: queue; item: in item_type);
>     procedure remove (q: queue; item: out item_type);
> private
>     type arr is array (natural range <>) of item_type;
>     procedure move_to_0 (var: out natural);
>     procedure move_to_last (var: out natural; values: in arr);
> 
>     type queue is tagged record
>         values: arr (0..mod_n_max'modulus-1);
>         tail: mod_n_max:=0;
>         head: mod_n_max:=1;
>     end record;
> end queues;

As you have probably found out, this won't work very well, since your
array is indexed by Natural and your index variables are Mod_N_Max. You
can put a bunch of type conversions in your code to work around this,
but it would be clearer to define

   type Arr is array (Mod_N_Max) of Item_Type;

I have no idea why you have included the procedures Move_To_0 and
Move_To_Last in the private part.

-- 
Jeff Carter
"I waggle my private parts at your aunties."
Monty Python & the Holy Grail




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

* Re: Modular types inside records
  2000-10-21  0:00 Modular types inside records Pawe� Niewiadomski
@ 2000-10-21  0:00 ` Robert Dewar
  2000-10-21  0:00   ` Pawe� Niewiadomski
  0 siblings, 1 reply; 11+ messages in thread
From: Robert Dewar @ 2000-10-21  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 686 bytes --]

In article <8FD47616EPablo@213.25.200.9>,
  niewiap@widzew.net (Pawe� Niewiadomski) wrote:
> If you have any idea on how to solve this problem (no dynamic
> memory  allocation, please) I would be grateful for sharing it
> with me

Keep things simple, don't always try to look for ingenious
ways of using the language

   X := X + 1;
   if X = max then X := 0; end if;

will work just fine

And no, there is clearly no way to use a modular type in
this case. To understand why, consider that the model of
generics is always organized to allow shared generics, and
we can't have base types whose range is dynamic at runtime!



Sent via Deja.com http://www.deja.com/
Before you buy.




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

* Modular types inside records
@ 2000-10-21  0:00 Pawe� Niewiadomski
  2000-10-21  0:00 ` Robert Dewar
  0 siblings, 1 reply; 11+ messages in thread
From: Pawe� Niewiadomski @ 2000-10-21  0:00 UTC (permalink / raw)


I have an assignment to implement a normal, unidirectional queue as a 
static array of n_max elements.  I wanted the array to be "cyclic", namely 
I wanted to use two variables: head and tail of a modular type within the 
queue record so that there would be no constraint error unless the array 
were really full (checked by an appropriate function).  If the tail index 
were on the last element of the array, its value after the incrementation 
would be 0, and by that time the 0 element of the array would be probably 
freed.

generic
    type item_type is private;
package queues is
    type queue(n_max: positive) is tagged private;
    function empty (q: queue) return boolean;
    function full (q: queue) return boolean;
    procedure add (q: queue; item: in item_type);
    procedure remove (q: queue; item: out item_type);
private
    type arr is array (natural range <>) of item_type;
    type queue (n_max: positive) is tagged record
        values: arr (0..n_max);
        tail: natural:=0; --I want these two be of modular type with 
        head: natural:=1; --a modulus equal to n_max+1
    end record;
end queues;

If you have any idea on how to solve this problem (no dynamic memory 
allocation, please) I would be grateful for sharing it with me
Pawel




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

* Re: Modular types inside records
  2000-10-21  0:00 ` Robert Dewar
@ 2000-10-21  0:00   ` Pawe� Niewiadomski
  2000-10-21  0:00     ` Jeff Carter
  2000-10-23  0:00     ` Robert A Duff
  0 siblings, 2 replies; 11+ messages in thread
From: Pawe� Niewiadomski @ 2000-10-21  0:00 UTC (permalink / raw)


>
>   X := X + 1;
>   if X = max then X := 0; end if;
>
>will work just fine
>
>And no, there is clearly no way to use a modular type in
>this case. To understand why, consider that the model of
>generics is always organized to allow shared generics, and
>we can't have base types whose range is dynamic at runtime!
>
How about this one?

generic
    type item_type is private;
    type mod_n_max is mod <>;
package queues is
    type queue is tagged private;
    function empty (q: queue) return boolean;
    function full (q: queue) return boolean;
    procedure add (q: queue; item: in item_type);
    procedure remove (q: queue; item: out item_type);
private
    type arr is array (natural range <>) of item_type;
    procedure move_to_0 (var: out natural);
    procedure move_to_last (var: out natural; values: in arr); 
    
    type queue is tagged record
        values: arr (0..mod_n_max'modulus-1);
        tail: mod_n_max:=0;
        head: mod_n_max:=1;
    end record;
end queues;

Pretty neat, huh?  Not as flexible as my previous (erroneous) idea (you 
need to instantiate the generic every time you want to change the size of 
your queue), but still gets rid of constraint verification problem.  It is 
just a rough, untested idea, but I think it will work.
Thanks for your answer,

Pawel





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

* Re: Modular types inside records
  2000-10-21  0:00     ` Jeff Carter
@ 2000-10-21  0:00       ` Pawe� Niewiadomski
  0 siblings, 0 replies; 11+ messages in thread
From: Pawe� Niewiadomski @ 2000-10-21  0:00 UTC (permalink / raw)



>As you have probably found out, this won't work very well, since your
>array is indexed by Natural and your index variables are Mod_N_Max. You
>can put a bunch of type conversions in your code to work around this,
>but it would be clearer to define
>
>   type Arr is array (Mod_N_Max) of Item_Type;
Yupp, you are perfectly right!

>
>I have no idea why you have included the procedures Move_To_0 and
>Move_To_Last in the private part.
>
Just a remainder from the version with constraint checking.  Forgot to 
remove it before I made a standard Ctrl-C, Ctrl-V procedure.

Thanks a lot
Pawel




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

* Re: Modular types inside records
  2000-10-21  0:00   ` Pawe� Niewiadomski
  2000-10-21  0:00     ` Jeff Carter
@ 2000-10-23  0:00     ` Robert A Duff
  2000-10-23  0:00       ` Pawe� Niewiadomski
  1 sibling, 1 reply; 11+ messages in thread
From: Robert A Duff @ 2000-10-23  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 661 bytes --]

niewiap@widzew.net (Pawe� Niewiadomski) writes:

> Pretty neat, huh?  Not as flexible as my previous (erroneous) idea (you 
> need to instantiate the generic every time you want to change the size of 
> your queue), but still gets rid of constraint verification problem.  It is 
> just a rough, untested idea, but I think it will work.

It can be made to work.

But I don't think this is a good use of modular types.  Instead, use a
normal (signed) integer type ("range 0..Whatever"), and use an explicit
"mod" operation, or an explicit if statement.  That makes the code more
readable, by making it clear what's going on at the "wraparound" place.

- Bob




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

* Re: Modular types inside records
  2000-10-23  0:00     ` Robert A Duff
@ 2000-10-23  0:00       ` Pawe� Niewiadomski
  2000-10-24  0:00         ` Robert A Duff
                           ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Pawe� Niewiadomski @ 2000-10-23  0:00 UTC (permalink / raw)


bobduff@world.std.com (Robert A Duff) wrote in
<wccd7gr385o.fsf@world.std.com>: 

>
>It can be made to work.
>
>But I don't think this is a good use of modular types.  Instead, use a
>normal (signed) integer type ("range 0..Whatever"), and use an explicit
>"mod" operation, or an explicit if statement.  That makes the code more
>readable, by making it clear what's going on at the "wraparound" place.
>
>- Bob
>

I don't think that adding a couple of if statements makes the code more 
readable.  On the contrary:  if someone looks at the record and sees a 
modular type, he says: OK, so I don't have to worry about constraint 
errors; I can get down to the important stuff.  My implementations of the 
empty and full functions are just one-line-long and add and remove 
procedures each take up as much as five lines of code.  Imagine what they 
would look like if you had to check for constraint errors every time.  The 
package body would be much less readable than it is now.
I don't like explicit programming too much, anyways.  I guess I am too much 
of a C++-type simplicity addict.

Pawel




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

* Re: Modular types inside records
  2000-10-23  0:00       ` Pawe� Niewiadomski
@ 2000-10-24  0:00         ` Robert A Duff
  2000-10-25  1:50         ` Nick Roberts
  2000-10-27 22:05         ` Robert Dewar
  2 siblings, 0 replies; 11+ messages in thread
From: Robert A Duff @ 2000-10-24  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 859 bytes --]

niewiap@widzew.net (Pawe� Niewiadomski) writes:

> I don't think that adding a couple of if statements makes the code more 
> readable.

Or a couple of "mod" operators.

>...  On the contrary:  if someone looks at the record and sees a 
> modular type, he says: OK, so I don't have to worry about constraint 
> errors; I can get down to the important stuff.

When I see a modular type, I say: OK, so I don't have to worry about
constraint errors; I have to worry about wrong answers.  Half :-).

>...  My implementations of the 
> empty and full functions are just one-line-long and add and remove 
> procedures each take up as much as five lines of code.  Imagine what they 
> would look like if you had to check for constraint errors every time.

I don't understand that -- you don't *check* for C_E, you write the code
so it doesn't cause C_E.

- Bob




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

* Re: Modular types inside records
  2000-10-25  1:50         ` Nick Roberts
@ 2000-10-25  0:00           ` Pawe� Niewiadomski
  0 siblings, 0 replies; 11+ messages in thread
From: Pawe� Niewiadomski @ 2000-10-25  0:00 UTC (permalink / raw)


Thanks for all your suggestions, guys
Pawel





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

* Re: Modular types inside records
  2000-10-23  0:00       ` Pawe� Niewiadomski
  2000-10-24  0:00         ` Robert A Duff
@ 2000-10-25  1:50         ` Nick Roberts
  2000-10-25  0:00           ` Pawe� Niewiadomski
  2000-10-27 22:05         ` Robert Dewar
  2 siblings, 1 reply; 11+ messages in thread
From: Nick Roberts @ 2000-10-25  1:50 UTC (permalink / raw)


Totally off-base, Pawel!

One of the things you must learn, if you are going to become a professional
Ada programmer, is what is grandly called 'decoupling'. This means, in
essence, making the interfaces between modules as simple as reasonably
possible. In the case of bottom-up programming (which includes your
example), this generally means making the interface as simple as
(reasonably) possible for 'users' of your package.

Does adding the 'mod_n_max' generic parameter make things easier for users
of your package? It surely does not.

Trust me, something like:

   if Front = Buffer'Last then
      Front := Buffer'First;
   else
      Front := Buffer_Index'Succ(Front);
   end if;

is a terrifically simple piece of code, as code goes. In your time, you will
come across multi-KSLOC Gorgons that will make you have to change your
underpants. You will come to eat the kind of fragmentette above in one gulp.

Oh harken ye to the words of the old and grizzled: it's not the car that has
the fanciest gadgets that wins the race, it's the one that manages to
actually finish the race.

Another way to think of it is like this: programming is not an art, it's
just a way of getting a job done. And, believe me, this comes from a man who
deeply believes that programming is an art.

Or, another way is this: you have to know a lot in order to know a little.

Okay, so how do we 'pros' do it, then? By declaring a 'Cyclic_Succ' function
of course:

generic
   type Element_Type is (<>);
function Cyclic_Succ (Item: in Element_Type) return Element_Type;

Neat huh? I'll leave the implementation and use of this function to you.

All the best,

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

PS: If you need to remove Constraint_Error checks, for speed, you can use
pragma Suppress (after testing).






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

* Re: Modular types inside records
  2000-10-23  0:00       ` Pawe� Niewiadomski
  2000-10-24  0:00         ` Robert A Duff
  2000-10-25  1:50         ` Nick Roberts
@ 2000-10-27 22:05         ` Robert Dewar
  2 siblings, 0 replies; 11+ messages in thread
From: Robert Dewar @ 2000-10-27 22:05 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1812 bytes --]

In article <8FD6C49EFPablo@213.25.200.9>,
  niewiap@widzew.net (Pawe� Niewiadomski) wrote:
> I don't like explicit programming too much, anyways.  I guess
I am too much
> of a C++-type simplicity addict.


It does NOT make things simple for the maintainer to hide
things in non-obvious code. Yes, it may be simpler for you
to type, especially if you are a slow typist :-)

Since the wrap around is very crucial to the algorithm here,
you will have to document that clearly if the code does not
document it clearly.

I agree with Bob, the explicit mod or if makes the code
much clearer.

Actually "the I don't like explicit programming"

says a LOT!

In a way I would say the whole design of Ada is to make
code clear and explicit, so if indeed you prefer obscure
code, c++ may indeed have the edge on this particular metric!

P.S. For my taste, modular types with modulus other than a
power of 2 should never have gone into the language.
Historically this was partly an editing error. The designers
were trying to incorporate recommendations from the URG, and
they paid attention to a long design document that had been
submitted to the URG with essentially the Ada 95 model of
generalized modular types. What they missed is that the URG
had voted N-1 (the 1 being the person submitting the idea)
that this was overkill, and rejected the general proposal :-)

But by the time this error was noticed, there was a constituency
of general-modular-type fans, and there were other battles to
be fought. Actually in retrospect the battle should have been
fought for two reasons

1. There are some really horrible strange things, like the
meaning of not on weird modular types.

2. Discussing and getting the details right on these weird
things wasted time



Sent via Deja.com http://www.deja.com/
Before you buy.



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

end of thread, other threads:[~2000-10-27 22:05 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-10-21  0:00 Modular types inside records Pawe� Niewiadomski
2000-10-21  0:00 ` Robert Dewar
2000-10-21  0:00   ` Pawe� Niewiadomski
2000-10-21  0:00     ` Jeff Carter
2000-10-21  0:00       ` Pawe� Niewiadomski
2000-10-23  0:00     ` Robert A Duff
2000-10-23  0:00       ` Pawe� Niewiadomski
2000-10-24  0:00         ` Robert A Duff
2000-10-25  1:50         ` Nick Roberts
2000-10-25  0:00           ` Pawe� Niewiadomski
2000-10-27 22:05         ` Robert Dewar

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