comp.lang.ada
 help / color / mirror / Atom feed
From: Adam Beneschan <adam@irvine.com>
Subject: Re: Pop function
Date: Thu, 15 Dec 2011 08:14:39 -0800 (PST)
Date: 2011-12-15T08:14:39-08:00	[thread overview]
Message-ID: <ee280822-e6ef-49ac-bdfb-e0d37c04866f@f33g2000yqh.googlegroups.com> (raw)
In-Reply-To: 31100824.174.1323919653265.JavaMail.geo-discussion-forums@yqcs5

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









  parent reply	other threads:[~2011-12-15 16:21 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2011-12-28 13:04       ` Rego, P.
replies disabled

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