From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,75f02dbbddbbdc88 X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Received: by 10.68.189.233 with SMTP id gl9mr5424504pbc.8.1323966090467; Thu, 15 Dec 2011 08:21:30 -0800 (PST) Path: lh20ni25841pbb.0!nntp.google.com!news1.google.com!postnews.google.com!f33g2000yqh.googlegroups.com!not-for-mail From: Adam Beneschan Newsgroups: comp.lang.ada Subject: Re: Pop function Date: Thu, 15 Dec 2011 08:14:39 -0800 (PST) Organization: http://groups.google.com Message-ID: References: <27517259.83.1323907586856.JavaMail.geo-discussion-forums@yqgn9> <31100824.174.1323919653265.JavaMail.geo-discussion-forums@yqcs5> NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 X-Trace: posting.google.com 1323966090 32052 127.0.0.1 (15 Dec 2011 16:21:30 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Thu, 15 Dec 2011 16:21:30 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: f33g2000yqh.googlegroups.com; posting-host=66.126.103.122; posting-account=duW0ogkAAABjRdnxgLGXDfna0Gc6XqmQ User-Agent: G2/1.0 X-Google-Web-Client: true X-Google-Header-Order: ARLUEHNKC X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618; .NET4.0C),gzip(gfe) Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Date: 2011-12-15T08:14:39-08:00 List-Id: On Dec 14, 7:27=A0pm, "Rego, P." wrote: > > that should be "constant Integer", right? > > Oh yes, sorry!! > > > No. =A0Current_Sender_Ptr is a local variable. =A0When you set > > Current_Sender_Ptr, you're changing the value of the local variable, > > but that does not affect *anything* outside the Pop procedure. =A0Free > > (Current_Sender_Ptr) will then set Current_Sender_Ptr to null. =A0Then > > 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. =A0If you call > > =A0 =A0N :=3D Pop (Sender); > > assuming that Sender points to the head of the list, this call won't > > change Sender at all. =A0After 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. =A0You probably want to make i= t > > 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). =A0So I'd > > do something like > > > =A0 =A0procedure Pop (List_Head : in out T_List_Ptr; Item : out Integer= ) > > is ... > > > and then in Pop, at some point, List_Head :=3D List_Head.Next. =A0Plus > > 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. =A0(Also, it wouldn't be my style to reserve a special > > Integer value to indicate an empty list. =A0It might be OK in some > > applications, but it makes the code that calls Pop more difficult to > > follow.) > > Ok. So it would be like > > =A0 =A0procedure Pop (Sender : in out T_List_Ptr; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 T_Item : out Integer) is > =A0 =A0 =A0 =A0 =A0 Previous_Sender : T_List_Ptr; > =A0 =A0begin > =A0 =A0 =A0 if Sender /=3D null then > =A0 =A0 =A0 =A0 =A0 =A0 =A0Previous_Sender :=3D Sender; > =A0 =A0 =A0 =A0 =A0 =A0 =A0T_Item :=3D Sender.Item; > =A0 =A0 =A0 =A0 =A0if Sender.Next /=3D null then > =A0 =A0 =A0 =A0 =A0 =A0 Sender :=3D T_List_Ptr (Sender.Next); > =A0 =A0 =A0 =A0 =A0end if; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Free (Previous_Sender); > =A0 =A0 =A0 else > =A0 =A0 =A0 =A0 =A0T_Item :=3D 0; > =A0 =A0 =A0 end if; > =A0 =A0end Pop; > > but in this case I could not call > =A0 =A0Some_Obj : access T_List; > =A0 =A0Other_Int : Integer; > =A0 =A0... > =A0 =A0Other_Int :=3D 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 usi= ng 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 /=3D null then ... List.Head :=3D 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