* Pop function @ 2011-12-15 0:06 Rego, P. 2011-12-15 0:29 ` Martin Dowie ` (2 more replies) 0 siblings, 3 replies; 27+ messages in thread From: Rego, P. @ 2011-12-15 0:06 UTC (permalink / raw) Hello, Given a list type type T_List is record Next : access T_List; Item : Integer; end record; T_List_Ptr is access T_List; Is it right to implement a pop function like the following? (Free is an Unchecked_Deallocation) function Pop (Sender : access T_List) return Integer is Current_Sender_Ptr : T_List_Ptr := T_List_Ptr (Sender); Current_Item : constant T_List := Sender.Item; begin if Sender /= null then if Sender.Next /= null then Current_Sender_Ptr := T_List_Ptr (Current_Sender_Ptr.Next); end if; Free (Current_Sender_Ptr); return Current_Item; else return 0; end if; end Pop; I mean, if I set Current_Sender_Ptr := T_List_Ptr (Current_Sender_Ptr.Next), it's equivalent to Sender := Sender.Next? (which I could not do directly due to in this case it would not be allowed an anonymous reference, right?) ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 0:06 Pop function Rego, P. @ 2011-12-15 0:29 ` Martin Dowie 2011-12-15 1:23 ` Rego, P. 2011-12-15 2:08 ` Adam Beneschan 2011-12-15 0:34 ` Jeffrey Carter 2011-12-15 2:06 ` Adam Beneschan 2 siblings, 2 replies; 27+ messages in thread From: Martin Dowie @ 2011-12-15 0:29 UTC (permalink / raw) "Rego, P." <pvrego@gmail.com> wrote: > Hello, > > Given a list type > type T_List is > record > Next : access T_List; > Item : Integer; > end record; > T_List_Ptr is access T_List; > > Is it right to implement a pop function like the following? (Free is an > Unchecked_Deallocation) > function Pop (Sender : access T_List) return Integer is > Current_Sender_Ptr : T_List_Ptr := T_List_Ptr (Sender); > Current_Item : constant T_List := Sender.Item; > begin > if Sender /= null then > if Sender.Next /= null then > Current_Sender_Ptr := T_List_Ptr (Current_Sender_Ptr.Next); > end if; > Free (Current_Sender_Ptr); > return Current_Item; > else > return 0; > end if; > end Pop; > > I mean, if I set Current_Sender_Ptr := T_List_Ptr > (Current_Sender_Ptr.Next), it's equivalent to Sender := Sender.Next? > (which I could not do directly due to in this case it would not be > allowed an anonymous reference, right?) If Sender is null, your in trouble before you get to "begin". Also, is it really ok to return 0 from an empty list rather than raising an exception? What does Sender "point to" on return if the head of the list is removed? -- Martin -- -- Sent from my iPad ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 0:29 ` Martin Dowie @ 2011-12-15 1:23 ` Rego, P. 2011-12-15 2:08 ` Adam Beneschan 1 sibling, 0 replies; 27+ messages in thread From: Rego, P. @ 2011-12-15 1:23 UTC (permalink / raw) > If Sender is null, your in trouble before you get to "begin". > Also, is it really ok to return 0 from an empty list rather than raising an > exception? That's the point. Actually I need to return some enumerated like NONE, but 0 would fit as well. > What does Sender "point to" on return if the head of the list is removed? I'd like to return the "next" in the list, or null (so "0" or some NONE), if the the next does not exist. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 0:29 ` Martin Dowie 2011-12-15 1:23 ` Rego, P. @ 2011-12-15 2:08 ` Adam Beneschan 2011-12-15 22:59 ` Martin Dowie 1 sibling, 1 reply; 27+ messages in thread From: Adam Beneschan @ 2011-12-15 2:08 UTC (permalink / raw) On Dec 14, 4:29 pm, Martin Dowie <mar...@re.mo.ve.thedowies.com> wrote: > "Rego, P." <pvr...@gmail.com> wrote: > > Hello, > > > Given a list type > > type T_List is > > record > > Next : access T_List; > > Item : Integer; > > end record; > > T_List_Ptr is access T_List; > > > Is it right to implement a pop function like the following? (Free is an > > Unchecked_Deallocation) > > function Pop (Sender : access T_List) return Integer is > > Current_Sender_Ptr : T_List_Ptr := T_List_Ptr (Sender); > > Current_Item : constant T_List := Sender.Item; > > begin > > if Sender /= null then > > if Sender.Next /= null then > > Current_Sender_Ptr := T_List_Ptr (Current_Sender_Ptr.Next); > > end if; > > Free (Current_Sender_Ptr); > > return Current_Item; > > else > > return 0; > > end if; > > end Pop; > > > I mean, if I set Current_Sender_Ptr := T_List_Ptr > > (Current_Sender_Ptr.Next), it's equivalent to Sender := Sender.Next? > > (which I could not do directly due to in this case it would not be > > allowed an anonymous reference, right?) > > If Sender is null, your in trouble before you get to "begin". First it's "here" instead of "hear", now it's "your" instead of "you're".......... :) -- Adam ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 2:08 ` Adam Beneschan @ 2011-12-15 22:59 ` Martin Dowie 2011-12-16 10:27 ` georg bauhaus 0 siblings, 1 reply; 27+ messages in thread From: Martin Dowie @ 2011-12-15 22:59 UTC (permalink / raw) Adam Beneschan <adam@irvine.com> wrote: > On Dec 14, 4:29 pm, Martin Dowie <mar...@re.mo.ve.thedowies.com> > wrote: >> "Rego, P." <pvr...@gmail.com> wrote: >>> Hello, >> >>> Given a list type >>> type T_List is >>> record >>> Next : access T_List; >>> Item : Integer; >>> end record; >>> T_List_Ptr is access T_List; >> >>> Is it right to implement a pop function like the following? (Free is an >>> Unchecked_Deallocation) >>> function Pop (Sender : access T_List) return Integer is >>> Current_Sender_Ptr : T_List_Ptr := T_List_Ptr (Sender); >>> Current_Item : constant T_List := Sender.Item; >>> begin >>> if Sender /= null then >>> if Sender.Next /= null then >>> Current_Sender_Ptr := T_List_Ptr (Current_Sender_Ptr.Next); >>> end if; >>> Free (Current_Sender_Ptr); >>> return Current_Item; >>> else >>> return 0; >>> end if; >>> end Pop; >> >>> I mean, if I set Current_Sender_Ptr := T_List_Ptr >>> (Current_Sender_Ptr.Next), it's equivalent to Sender := Sender.Next? >>> (which I could not do directly due to in this case it would not be >>> allowed an anonymous reference, right?) >> >> If Sender is null, your in trouble before you get to "begin". > > First it's "here" instead of "hear", now it's "your" instead of > "you're".......... > > :) > -- Adam Groan...I need a holiday...and glasses...and 10 years taken off my age...and the kids to GO TO BED...and to really read what I'm writing (minor dyslexia doesn't help)...before I hit send! :-) -- Martin ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 22:59 ` Martin Dowie @ 2011-12-16 10:27 ` georg bauhaus 0 siblings, 0 replies; 27+ messages in thread From: georg bauhaus @ 2011-12-16 10:27 UTC (permalink / raw) Martin Dowie <martin@re.mo.ve.thedowies.com> wrote: >> First it's "here" instead of "hear", now it's "your" instead of >> "you're".......... >> >> :) >> -- Adam > > Groan...I need a holiday...and glasses...and 10 years taken off my > age...and the kids to GO TO BED...and to really read what I'm writing > (minor dyslexia doesn't help)...before I hit send! :-) Ada's doubly shouting her current location made me wonder who was calling, and why. If this is all a misinterpretation of the original string literal, then maybe "Sorry, father!" is what she might have answered? ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 0:06 Pop function Rego, P. 2011-12-15 0:29 ` Martin Dowie @ 2011-12-15 0:34 ` Jeffrey Carter 2011-12-15 1:35 ` Rego, P. 2011-12-15 8:38 ` Dmitry A. Kazakov 2011-12-15 2:06 ` Adam Beneschan 2 siblings, 2 replies; 27+ messages in thread From: Jeffrey Carter @ 2011-12-15 0:34 UTC (permalink / raw) On 12/14/2011 05:06 PM, Rego, P. wrote: A few unrelated comments: > Is it right to implement a pop function like the following? (Free is an Unchecked_Deallocation) > function Pop (Sender : access T_List) return Integer is Your public interface should never use access types. Anonymous types are a bad idea. Psychologists have found that the 1st few letters of a word are the most important to recognizing what you're seeing. If many of your identifiers start with the same few letters ("T_"), you are making your code harder to read than necessary. -- Jeff Carter "English bed-wetting types." Monty Python & the Holy Grail 15 --- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net --- ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 0:34 ` Jeffrey Carter @ 2011-12-15 1:35 ` Rego, P. 2011-12-15 2:55 ` Alex Mentis 2011-12-15 3:00 ` Jeffrey Carter 2011-12-15 8:38 ` Dmitry A. Kazakov 1 sibling, 2 replies; 27+ messages in thread From: Rego, P. @ 2011-12-15 1:35 UTC (permalink / raw) > Your public interface should never use access types. > Anonymous types are a bad idea. Why so does the language allow it? Currently I could not think a better way of running over a pointer list: get the item, run the top of the list to the next one (and also keep the original pointer), free the original pointer and return the (newest) pointer to the top of the list. The problem I got was exactly when I tried to do this directly from the input access (so the anonymous type problem) > Psychologists have found that the 1st few letters of a word are the most important to recognizing what you're seeing. If many of your identifiers start with the same few letters ("T_"), you are making your code harder to read than necessary. I agree, but that's ok here. Think this as "be a general list type named T_List ..." ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 1:35 ` Rego, P. @ 2011-12-15 2:55 ` Alex Mentis 2011-12-15 3:00 ` Alex Mentis 2011-12-15 3:00 ` Jeffrey Carter 1 sibling, 1 reply; 27+ messages in thread From: Alex Mentis @ 2011-12-15 2:55 UTC (permalink / raw) Rego, P. wrote: > > Your public interface should never use access types. > > Anonymous types are a bad idea. > Why so does the language allow it? Currently I could not think a > better way of running over a pointer list: Instead of type T_List is record Next : access T_List; Item : Integer; end record; T_List_Ptr is access T_List; you should use an incomplete declaration (ARM 3.10.1): type T_List; -- incomplete declaration type T_List_Ptr is access T_List; type T_List is record Next : T_List_Ptr; Item : Integer; end record; -Alex ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 2:55 ` Alex Mentis @ 2011-12-15 3:00 ` Alex Mentis 0 siblings, 0 replies; 27+ messages in thread From: Alex Mentis @ 2011-12-15 3:00 UTC (permalink / raw) Alex Mentis wrote: > Rego, P. wrote: > > > > Your public interface should never use access types. > > > Anonymous types are a bad idea. > > Why so does the language allow it? Currently I could not think a > > better way of running over a pointer list: > > Instead of > > type T_List is > record > Next : access T_List; > Item : Integer; > end record; > T_List_Ptr is access T_List; > > you should use an incomplete declaration (ARM 3.10.1): > > type T_List; -- incomplete declaration > > type T_List_Ptr is access T_List; > > type T_List is > record > Next : T_List_Ptr; > Item : Integer; > end record; > > > -Alex I meant to add, that would alleviate a lot of the type conversion you're doing. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 1:35 ` Rego, P. 2011-12-15 2:55 ` Alex Mentis @ 2011-12-15 3:00 ` Jeffrey Carter 2011-12-15 3:41 ` Rego, P. 1 sibling, 1 reply; 27+ messages in thread From: Jeffrey Carter @ 2011-12-15 3:00 UTC (permalink / raw) On 12/14/2011 06:35 PM, Rego, P. wrote: >> Your public interface should never use access types. Anonymous types are a >> bad idea. > Why so does the language allow it? Currently I could not think a better way > of running over a pointer list: get the item, run the top of the list to the > next one (and also keep the original pointer), free the original pointer and > return the (newest) pointer to the top of the list. The problem I got was > exactly when I tried to do this directly from the input access (so the > anonymous type problem) The language allows lots of things that are bad ideas: anonymous types, programming by extension, the list goes on. That's not a reason to use them. While an unbounded list undoubtedly is implemented using access values, there is no reason to expose them to your clients. The best way to run over a list is to reuse an existing implementation, such as Ada.Containers.Doubly_Linked_List, or PragmARC.List_Unbounded_Unprotected if you don't have access to a compiler for the current language. One wonders why you are trying to write another one. >> Psychologists have found that the 1st few letters of a word are the most >> important to recognizing what you're seeing. If many of your identifiers >> start with the same few letters ("T_"), you are making your code harder to >> read than necessary. > I agree, but that's ok here. Think this as "be a general list type named > T_List ..." It's never OK to make your code harder to read. -- Jeff Carter "English bed-wetting types." Monty Python & the Holy Grail 15 --- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net --- ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 3:00 ` Jeffrey Carter @ 2011-12-15 3:41 ` Rego, P. 0 siblings, 0 replies; 27+ messages in thread From: Rego, P. @ 2011-12-15 3:41 UTC (permalink / raw) > The best way to run over a list is to reuse an existing implementation, such as Ada.Containers.Doubly_Linked_List, or PragmARC.List_Unbounded_Unprotected if you don't have access to a compiler for the current language. One wonders why you are trying to write another one. Well, I did not try Ada.Containers.Doubly_Linked_List before, but it's worth trying for sure. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 0:34 ` Jeffrey Carter 2011-12-15 1:35 ` Rego, P. @ 2011-12-15 8:38 ` Dmitry A. Kazakov 2011-12-15 19:57 ` Jeffrey Carter 1 sibling, 1 reply; 27+ messages in thread From: Dmitry A. Kazakov @ 2011-12-15 8:38 UTC (permalink / raw) On Wed, 14 Dec 2011 17:34:57 -0700, Jeffrey Carter wrote: > Your public interface should never use access types. Yes, but since list as a data structure has the semantics of objects accessed by references it would make sense to have this reflected in the interface. But of course the list element must be type List_Item is access Integer; -- Only the data, no other mess Fortunately Ada supports such implementations (via storage pools). Otherwise, it is not a list what OP wants, but rather a container, e.g. set, bag, maybe an array (map). -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 8:38 ` Dmitry A. Kazakov @ 2011-12-15 19:57 ` Jeffrey Carter 2011-12-15 20:15 ` Dmitry A. Kazakov 2011-12-16 0:31 ` Randy Brukardt 0 siblings, 2 replies; 27+ messages in thread From: Jeffrey Carter @ 2011-12-15 19:57 UTC (permalink / raw) On 12/15/2011 01:38 AM, Dmitry A. Kazakov wrote: > On Wed, 14 Dec 2011 17:34:57 -0700, Jeffrey Carter wrote: > >> Your public interface should never use access types. > > Yes, but since list as a data structure has the semantics of objects > accessed by references it would make sense to have this reflected in the > interface. But of course the list element must be > > type List_Item is access Integer; -- Only the data, no other mess No, a public interface should never use access types, ever. Hiding those is what abstraction is about. Any public interface that uses access types is poorly designed. -- Jeff Carter "I would never want to belong to any club that would have someone like me for a member." Annie Hall 41 --- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net --- ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 19:57 ` Jeffrey Carter @ 2011-12-15 20:15 ` Dmitry A. Kazakov 2011-12-15 21:02 ` Simon Wright 2011-12-16 0:31 ` Randy Brukardt 1 sibling, 1 reply; 27+ messages in thread From: Dmitry A. Kazakov @ 2011-12-15 20:15 UTC (permalink / raw) On Thu, 15 Dec 2011 12:57:47 -0700, Jeffrey Carter wrote: > On 12/15/2011 01:38 AM, Dmitry A. Kazakov wrote: >> On Wed, 14 Dec 2011 17:34:57 -0700, Jeffrey Carter wrote: >> >>> Your public interface should never use access types. >> >> Yes, but since list as a data structure has the semantics of objects >> accessed by references it would make sense to have this reflected in the >> interface. But of course the list element must be >> >> type List_Item is access Integer; -- Only the data, no other mess > > No, a public interface should never use access types, ever. Hiding those is what > abstraction is about. Any public interface that uses access types is poorly > designed. In that case there should be no linked lists at all. A linked list is per its definition a set of elements accessed using pointers. It is possible that the OP wanted something else, but that is another question. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 20:15 ` Dmitry A. Kazakov @ 2011-12-15 21:02 ` Simon Wright 2011-12-15 21:25 ` Jeffrey Carter 2011-12-16 8:23 ` Dmitry A. Kazakov 0 siblings, 2 replies; 27+ messages in thread From: Simon Wright @ 2011-12-15 21:02 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > On Thu, 15 Dec 2011 12:57:47 -0700, Jeffrey Carter wrote: > >> On 12/15/2011 01:38 AM, Dmitry A. Kazakov wrote: >>> On Wed, 14 Dec 2011 17:34:57 -0700, Jeffrey Carter wrote: >>> >>>> Your public interface should never use access types. >>> >>> Yes, but since list as a data structure has the semantics of objects >>> accessed by references it would make sense to have this reflected in the >>> interface. But of course the list element must be >>> >>> type List_Item is access Integer; -- Only the data, no other mess >> >> No, a public interface should never use access types, ever. Hiding >> those is what abstraction is about. Any public interface that uses >> access types is poorly designed. > > In that case there should be no linked lists at all. A linked list is per > its definition a set of elements accessed using pointers. I don't think that using the word "linked" in the name is the same as "using access types in the abstraction"! I've seen linked lists that were implemented (under the hood) with indices into an array of items. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 21:02 ` Simon Wright @ 2011-12-15 21:25 ` Jeffrey Carter 2011-12-16 8:23 ` Dmitry A. Kazakov 1 sibling, 0 replies; 27+ messages in thread From: Jeffrey Carter @ 2011-12-15 21:25 UTC (permalink / raw) On 12/15/2011 02:02 PM, Simon Wright wrote: > "Dmitry A. Kazakov"<mailbox@dmitry-kazakov.de> writes: > >> On Thu, 15 Dec 2011 12:57:47 -0700, Jeffrey Carter wrote: >> >>> No, a public interface should never use access types, ever. Hiding >>> those is what abstraction is about. Any public interface that uses >>> access types is poorly designed. >> >> In that case there should be no linked lists at all. A linked list is per >> its definition a set of elements accessed using pointers. > > I don't think that using the word "linked" in the name is the same as > "using access types in the abstraction"! > > I've seen linked lists that were implemented (under the hood) with > indices into an array of items. Precisely. That's a bounded list; see PragmARC.List_Bounded_Unprotected for an example. And see Ada.Containers.Doubly_Linked_Lists for an example of an unbounded list abstraction with no visible access types. -- Jeff Carter "I would never want to belong to any club that would have someone like me for a member." Annie Hall 41 --- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net --- ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 21:02 ` Simon Wright 2011-12-15 21:25 ` Jeffrey Carter @ 2011-12-16 8:23 ` Dmitry A. Kazakov 1 sibling, 0 replies; 27+ messages in thread From: Dmitry A. Kazakov @ 2011-12-16 8:23 UTC (permalink / raw) On Thu, 15 Dec 2011 21:02:09 +0000, Simon Wright wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >> On Thu, 15 Dec 2011 12:57:47 -0700, Jeffrey Carter wrote: >> >>> On 12/15/2011 01:38 AM, Dmitry A. Kazakov wrote: >>>> On Wed, 14 Dec 2011 17:34:57 -0700, Jeffrey Carter wrote: >>>> >>>>> Your public interface should never use access types. >>>> >>>> Yes, but since list as a data structure has the semantics of objects >>>> accessed by references it would make sense to have this reflected in the >>>> interface. But of course the list element must be >>>> >>>> type List_Item is access Integer; -- Only the data, no other mess >>> >>> No, a public interface should never use access types, ever. Hiding >>> those is what abstraction is about. Any public interface that uses >>> access types is poorly designed. >> >> In that case there should be no linked lists at all. A linked list is per >> its definition a set of elements accessed using pointers. > > I don't think that using the word "linked" in the name is the same as > "using access types in the abstraction"! Not exactly same, right, but still it assumes referential semantics of the list elements. Access type is one possible implementation of. > I've seen linked lists that were implemented (under the hood) with > indices into an array of items. In that case the index must be exposed in the interface, or a private type encapsulating that index. The bottom line, you need some referential object to refer the list element in the interface. You cannot have linked lists defined solely in the terms of element values. List elements have an identity. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 19:57 ` Jeffrey Carter 2011-12-15 20:15 ` Dmitry A. Kazakov @ 2011-12-16 0:31 ` Randy Brukardt 1 sibling, 0 replies; 27+ messages in thread From: Randy Brukardt @ 2011-12-16 0:31 UTC (permalink / raw) "Jeffrey Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message news:jcdjfs$atd$1@adenine.netfront.net... ... > No, a public interface should never use access types, ever. Hiding those > is what abstraction is about. Any public interface that uses access types > is poorly designed. Geee, even I wouldn't go quite *that* far. There are some cases where you have to have reference semantics (the "Parent" function in Claw is an example), and in those cases ONLY it might make sense to visibly use an access type. Ada 2012 provides "aliased" parameters to force reference semantics, and it's possible to encapsulate the access type so that it can't be abused, so this can actually be done safely. But that is an advanced topic. Randy. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 0:06 Pop function Rego, P. 2011-12-15 0:29 ` Martin Dowie 2011-12-15 0:34 ` Jeffrey Carter @ 2011-12-15 2:06 ` Adam Beneschan 2011-12-15 3:27 ` Rego, P. 2 siblings, 1 reply; 27+ messages in thread From: Adam Beneschan @ 2011-12-15 2:06 UTC (permalink / raw) On Dec 14, 4:06 pm, "Rego, P." <pvr...@gmail.com> wrote: > Hello, > > Given a list type > type T_List is > record > Next : access T_List; > Item : Integer; > end record; > T_List_Ptr is access T_List; > > Is it right to implement a pop function like the following? (Free is an Unchecked_Deallocation) > function Pop (Sender : access T_List) return Integer is > Current_Sender_Ptr : T_List_Ptr := T_List_Ptr (Sender); > Current_Item : constant T_List := Sender.Item; that should be "constant Integer", right? > begin > if Sender /= null then > if Sender.Next /= null then > Current_Sender_Ptr := T_List_Ptr (Current_Sender_Ptr.Next); > end if; > Free (Current_Sender_Ptr); > return Current_Item; > else > return 0; > end if; > end Pop; > > I mean, if I set Current_Sender_Ptr := T_List_Ptr (Current_Sender_Ptr.Next), it's > equivalent to Sender := Sender.Next? No. Current_Sender_Ptr is a local variable. When you set Current_Sender_Ptr, you're changing the value of the local variable, but that does not affect *anything* outside the Pop procedure. Free (Current_Sender_Ptr) will then set Current_Sender_Ptr to null. Then Pop will return and Current_Sender_Ptr will go away since it's a local variable, so the work you've done of setting it to the "Next" value will be lost. If you call N := Pop (Sender); assuming that Sender points to the head of the list, this call won't change Sender at all. After the call, Sender will point to an item that has been deallocated, which is very, very bad. What you're probably missing is that Sender is treated as an IN parameter here, so it can't be modified. You probably want to make it an IN OUT parameter, which means that Pop can't be a function (up through Ada 2005; I think that rule is changing in Ada 2012). So I'd do something like procedure Pop (List_Head : in out T_List_Ptr; Item : out Integer) is ... and then in Pop, at some point, List_Head := List_Head.Next. Plus you'll need to rearrange the code so that you don't try to access Sender.Item before checking to make sure Sender isn't null, as Martin pointed out. (Also, it wouldn't be my style to reserve a special Integer value to indicate an empty list. It might be OK in some applications, but it makes the code that calls Pop more difficult to follow.) -- Adam ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 2:06 ` Adam Beneschan @ 2011-12-15 3:27 ` Rego, P. 2011-12-15 12:43 ` Simon Wright 2011-12-15 16:14 ` Adam Beneschan 0 siblings, 2 replies; 27+ messages in thread From: Rego, P. @ 2011-12-15 3:27 UTC (permalink / raw) > that should be "constant Integer", right? Oh yes, sorry!! > No. Current_Sender_Ptr is a local variable. When you set > Current_Sender_Ptr, you're changing the value of the local variable, > but that does not affect *anything* outside the Pop procedure. Free > (Current_Sender_Ptr) will then set Current_Sender_Ptr to null. Then > Pop will return and Current_Sender_Ptr will go away since it's a local > variable, so the work you've done of setting it to the "Next" value > will be lost. If you call > N := Pop (Sender); > assuming that Sender points to the head of the list, this call won't > change Sender at all. After the call, Sender will point to an item > that has been deallocated, which is very, very bad. Ok. > What you're probably missing is that Sender is treated as an IN > parameter here, so it can't be modified. You probably want to make it > an IN OUT parameter, which means that Pop can't be a function (up > through Ada 2005; I think that rule is changing in Ada 2012). So I'd > do something like > > procedure Pop (List_Head : in out T_List_Ptr; Item : out Integer) > is ... > > and then in Pop, at some point, List_Head := List_Head.Next. Plus > you'll need to rearrange the code so that you don't try to access > Sender.Item before checking to make sure Sender isn't null, as Martin > pointed out. (Also, it wouldn't be my style to reserve a special > Integer value to indicate an empty list. It might be OK in some > applications, but it makes the code that calls Pop more difficult to > follow.) Ok. So it would be like procedure Pop (Sender : in out T_List_Ptr; T_Item : out Integer) is Previous_Sender : T_List_Ptr; begin if Sender /= null then Previous_Sender := Sender; T_Item := Sender.Item; if Sender.Next /= null then Sender := T_List_Ptr (Sender.Next); end if; Free (Previous_Sender); else T_Item := 0; end if; end Pop; but in this case I could not call Some_Obj : access T_List; Other_Int : Integer; ... Other_Int := Some_Obj.Pop; because Pop is not a primitive of T_List. The notation Some_Obj.Pop would be just sintatic sugar, but would exist a way we can implement Pop for using with this? (but sure...that's also ok for the non-sugar case) ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 3:27 ` Rego, P. @ 2011-12-15 12:43 ` Simon Wright 2011-12-15 15:54 ` Adam Beneschan 2011-12-15 16:14 ` Adam Beneschan 1 sibling, 1 reply; 27+ messages in thread From: Simon Wright @ 2011-12-15 12:43 UTC (permalink / raw) "Rego, P." <pvrego@gmail.com> writes: > Ok. So it would be like > > procedure Pop (Sender : in out T_List_Ptr; > T_Item : out Integer) is > Previous_Sender : T_List_Ptr; [...] > but in this case I could not call > Some_Obj : access T_List; > Other_Int : Integer; > ... > Other_Int := Some_Obj.Pop; > because Pop is not a primitive of T_List. The notation Some_Obj.Pop > would be just sintatic sugar, but would exist a way we can implement > Pop for using with this? (but sure...that's also ok for the non-sugar > case) I don't see why Pop takes T_List_Ptr as an argument. I would have written procedure Pop (Sender : in out T_List; T_Item : out Integer) is and then it would be primitive (assuming T_List is tagged). And why is the parameter called Sender? that sounds like a name in the domain of the problem you're trying to solve, rather than in the domain of popping an item from a List. Maybe From would be better. And how come a List has an operation Pop? sounds more like a Stack or a Queue. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 12:43 ` Simon Wright @ 2011-12-15 15:54 ` Adam Beneschan 2011-12-15 18:34 ` Simon Wright 0 siblings, 1 reply; 27+ messages in thread From: Adam Beneschan @ 2011-12-15 15:54 UTC (permalink / raw) On Dec 15, 4:43 am, Simon Wright <si...@pushface.org> wrote: > "Rego, P." <pvr...@gmail.com> writes: > > Ok. So it would be like > > > procedure Pop (Sender : in out T_List_Ptr; > > T_Item : out Integer) is > > Previous_Sender : T_List_Ptr; > [...] > > but in this case I could not call > > Some_Obj : access T_List; > > Other_Int : Integer; > > ... > > Other_Int := Some_Obj.Pop; > > because Pop is not a primitive of T_List. The notation Some_Obj.Pop > > would be just sintatic sugar, but would exist a way we can implement > > Pop for using with this? (but sure...that's also ok for the non-sugar > > case) > > I don't see why Pop takes T_List_Ptr as an argument. I would have > written > > procedure Pop (Sender : in out T_List; > T_Item : out Integer) is > > and then it would be primitive (assuming T_List is tagged). I'm not following. Assuming you have some object that represents a "list", that object is going to have to point to the "head" of the list somehow, and the Pop operation is going to have to change that head. Since the OP has defined T_List as one of the elements of the list, rather than as an object that represents the "list" in its entirety, passing an "in out T_List" isn't going to get the job done. You could quibble about whether T_List is an appropriate name to represent a list element. Fine. I would too. But I think our first objective should get our OP to help write code that works, which involves making sure he (I assume) understands the Ada language issues involved, and not adding to any confusion he might have. We can quibble about the names, readability issues, encapsulation issues, etc., later. -- Adam ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 15:54 ` Adam Beneschan @ 2011-12-15 18:34 ` Simon Wright 2011-12-15 19:14 ` Dmitry A. Kazakov 0 siblings, 1 reply; 27+ messages in thread From: Simon Wright @ 2011-12-15 18:34 UTC (permalink / raw) Adam Beneschan <adam@irvine.com> writes: > On Dec 15, 4:43 am, Simon Wright <si...@pushface.org> wrote: >> I don't see why Pop takes T_List_Ptr as an argument. I would have >> written >> >> procedure Pop (Sender : in out T_List; >> T_Item : out Integer) is >> >> and then it would be primitive (assuming T_List is tagged). > You could quibble about whether T_List is an appropriate name to > represent a list element. Fine. I would too. But I think our first > objective should get our OP to help write code that works, which > involves making sure he (I assume) understands the Ada language issues > involved, and not adding to any confusion he might have. We can > quibble about the names, readability issues, encapsulation issues, > etc., later. I see what you mean; you've realised that OP is probably confused, whereas I just got confused myself. I agree about writing code that works, but that does sometimes involve working out how best to state the problem. I don't think that it's quibbling to point to unclear thinking; if the design is wrong that's not an Ada language issue, and using inappropriate names is a red flag for design problems. Here, for example, if I write L : aliased T_List; ... begin ... J := Pop (L'Access); I'm going to get a crash at runtime because I'm trying to deallcate memory that was never allocated. I have in the past implemented lists where the 'head' element was just another member which -- by convention -- wasn't part of the list. That sort of thing needs to be done by consenting adults in private, though. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 18:34 ` Simon Wright @ 2011-12-15 19:14 ` Dmitry A. Kazakov 0 siblings, 0 replies; 27+ messages in thread From: Dmitry A. Kazakov @ 2011-12-15 19:14 UTC (permalink / raw) On Thu, 15 Dec 2011 18:34:53 +0000, Simon Wright wrote: > Here, for example, if I write > > L : aliased T_List; > ... > begin > ... > J := Pop (L'Access); > > I'm going to get a crash at runtime because I'm trying to deallcate > memory that was never allocated. Another reason to have it an explicit access type, BTW. If L were access to specific pool you would not be able to declare L on the stack. > I have in the past implemented lists where the 'head' element was just > another member which -- by convention -- wasn't part of the list. I tried: type Item is access Element_Type; type List is new Item; and then to separate elements and lists in operations. E.g. procedure Delete (Container : in out List; Element : in out Item); Item becomes null, Container set to the new head. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 3:27 ` Rego, P. 2011-12-15 12:43 ` Simon Wright @ 2011-12-15 16:14 ` Adam Beneschan 2011-12-28 13:04 ` Rego, P. 1 sibling, 1 reply; 27+ messages in thread From: Adam Beneschan @ 2011-12-15 16:14 UTC (permalink / raw) On Dec 14, 7:27 pm, "Rego, P." <pvr...@gmail.com> wrote: > > that should be "constant Integer", right? > > Oh yes, sorry!! > > > No. Current_Sender_Ptr is a local variable. When you set > > Current_Sender_Ptr, you're changing the value of the local variable, > > but that does not affect *anything* outside the Pop procedure. Free > > (Current_Sender_Ptr) will then set Current_Sender_Ptr to null. Then > > Pop will return and Current_Sender_Ptr will go away since it's a local > > variable, so the work you've done of setting it to the "Next" value > > will be lost. If you call > > N := Pop (Sender); > > assuming that Sender points to the head of the list, this call won't > > change Sender at all. After the call, Sender will point to an item > > that has been deallocated, which is very, very bad. > > Ok. > > > > > > > What you're probably missing is that Sender is treated as an IN > > parameter here, so it can't be modified. You probably want to make it > > an IN OUT parameter, which means that Pop can't be a function (up > > through Ada 2005; I think that rule is changing in Ada 2012). So I'd > > do something like > > > procedure Pop (List_Head : in out T_List_Ptr; Item : out Integer) > > is ... > > > and then in Pop, at some point, List_Head := List_Head.Next. Plus > > you'll need to rearrange the code so that you don't try to access > > Sender.Item before checking to make sure Sender isn't null, as Martin > > pointed out. (Also, it wouldn't be my style to reserve a special > > Integer value to indicate an empty list. It might be OK in some > > applications, but it makes the code that calls Pop more difficult to > > follow.) > > Ok. So it would be like > > procedure Pop (Sender : in out T_List_Ptr; > T_Item : out Integer) is > Previous_Sender : T_List_Ptr; > begin > if Sender /= null then > Previous_Sender := Sender; > T_Item := Sender.Item; > if Sender.Next /= null then > Sender := T_List_Ptr (Sender.Next); > end if; > Free (Previous_Sender); > else > T_Item := 0; > end if; > end Pop; > > but in this case I could not call > Some_Obj : access T_List; > Other_Int : Integer; > ... > Other_Int := Some_Obj.Pop; > because Pop is not a primitive of T_List. The notation Some_Obj.Pop would be just sintatic sugar, but would exist a way we can implement Pop for using with this? (but sure...that's also ok for the non-sugar case) I don't like picking on people's naming conventions when they seem to be asking about how to get the language to work. But in this case, I'm afraid you've been tripped up by your choice of type names, so I think we do need to go into it this time. You're dealing with two abstract concepts here: a "list" and an "element". A "list" is a collection of "elements" that are ordered, or organized, in a certain way. (I'm not going to worry about how they're organized, since that isn't relevant to my point about naming.) The Pop operation is an operation that applies to a "list", so it should be a primitive of a "list". But I think your problem is that you've defined T_List to be a type that represents one "element", not the entire "list". And so it would make sense that Pop is not a primitive operation of T_List, because Pop should be a primitive operation of the "list" type, and T_List isn't really the "list" type. What I think you want is more like this: (This is how I'd write it, because I don't like anonymous access types in this situation, but that's up to you.) type T_List_Element; type T_List_Element_Acc is access all T_List_Element; type T_List_Element is record Item : Integer; Next : T_List_Element_Acc; end record; type T_List is tagged record Head : T_List_Element_Acc; end record; Now you actually could write a Pop function that is a primitive of a List: function Pop (List : access T_List) return Integer is begin if List.Head /= null then ... List.Head := List.Head.Next; -- or something like that ... I'll leave the rest of the details up to you. But note that there's a big difference between this access parameter and the one you coded originally: in my example, "access T_List" is an access to a record that *contains* a pointer to the first element of the list, not the pointer to the first element itself. This is what makes it possible to change the list head pointer. Anyway, hopefully this will get you started on the right path. **Then**, after you have the basics down, we can have some long arguments about what names you should pick, whether you should start type names with T_, what types should be made private and how things should be encapsulated, whether it's appropriate to return a special value for an empty list or raise an exception, whether anonymous access types are evil, etc. I'm sure everyone on this group has some pretty strong opinions on all those questions. But I'm hoping this will get you started. -- Adam ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Pop function 2011-12-15 16:14 ` Adam Beneschan @ 2011-12-28 13:04 ` Rego, P. 0 siblings, 0 replies; 27+ messages in thread From: Rego, P. @ 2011-12-28 13:04 UTC (permalink / raw) Adam, I've redesigned the lists this way you suggested and, because of this change, I discovered a deeper bug when I used some limited withs. So, thanks twice :-) And thank you all people too :-) ^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2011-12-28 13:04 UTC | newest] Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-12-15 0:06 Pop function Rego, P. 2011-12-15 0:29 ` Martin Dowie 2011-12-15 1:23 ` Rego, P. 2011-12-15 2:08 ` Adam Beneschan 2011-12-15 22:59 ` Martin Dowie 2011-12-16 10:27 ` georg bauhaus 2011-12-15 0:34 ` Jeffrey Carter 2011-12-15 1:35 ` Rego, P. 2011-12-15 2:55 ` Alex Mentis 2011-12-15 3:00 ` Alex Mentis 2011-12-15 3:00 ` Jeffrey Carter 2011-12-15 3:41 ` Rego, P. 2011-12-15 8:38 ` Dmitry A. Kazakov 2011-12-15 19:57 ` Jeffrey Carter 2011-12-15 20:15 ` Dmitry A. Kazakov 2011-12-15 21:02 ` Simon Wright 2011-12-15 21:25 ` Jeffrey Carter 2011-12-16 8:23 ` Dmitry A. Kazakov 2011-12-16 0:31 ` Randy Brukardt 2011-12-15 2:06 ` Adam Beneschan 2011-12-15 3:27 ` Rego, P. 2011-12-15 12:43 ` Simon Wright 2011-12-15 15:54 ` Adam Beneschan 2011-12-15 18:34 ` Simon Wright 2011-12-15 19:14 ` Dmitry A. Kazakov 2011-12-15 16:14 ` Adam Beneschan 2011-12-28 13:04 ` Rego, P.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox