* 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 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
* 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 ` 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 ` 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-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-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-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