Willem said:
Keith Thompson wrote:
) Willem, you have a point. There is no One True Way to define the
) set of operations available for a stack.
Thank you, that was exactly the point I was trying to make.
It appears that at least two different persons have been posting under the
name Willem, because this whole discussion has been based on how Willem
believes a stack should be implemented, instead of how it can be
implemented.
) On the other hand, some operations make sense and some do not.
)
) I don't believe you've demonstrated that a push() operation that
) extends the stack without storing a value in the top element makes
) any sense.
I never tried to demonstrate it. I just got very annoyed by people
claiming that thier views on stacks are the One True Way, and using
bad logic to argue their points.
Nobody tried to argue *why* it maked sense to have the stack operations
work the way they say they should work. They just *asserted* it.
Please do take the time to point out who has been making assertions on how
stack operations should work, and quote them exactly where they made those
assertions. Here's a hint: you won't find posts from anyone but yourself.
Therefore, if you believe that presenting that sort of behaviour is the sign
that someone is an idiot, and that it gives you the right to launch a set of
personal attacks based on your petty views, then I expect you to start
posting about how you believe Willem is stupid and an idiot.
) Under what circumstances would you want to use such an operation?
) As far as I can see, extending the stack is *always* immediately
) followed by storing a value in the new top element. How would it
) be advantageous to separate those operations?
The most obvious one would be is your application needs a way to replace
or change the top value of a stack. Then a push() which sets the value
also would be redundant(*).
It appears that, still at this point, you are still unaware of top()'s
existence and purpose.
Another one would be if the 'value' on the stack is actually a large
entity, such as a struct, and passing the whole struct would be
a performance issue, especially if you're only using a part of it.
Irrelevant and absurd. You either store an object in your stack or you
store a reference to an object in your stack. Even if you intend to store
"a part of" a structure in a stack you are still forced to store either
objects or references to those objects.
Either way, there is absolutely no justification for pushing uninitialized
values into a stack and postponing it's initialization, which isn't even
guaranteed to happen due to the design you've came up with.
This is especially true if the stack is a way of being able to step
back to a previous saved state.
As a real-life example of that, look at a postscript interpreter, which
keeps a stack of graphics contexts. Or a chess playing program, which
needs to save the current state of the board to be able to try different
moves.
....which are always represented through objects and therefore are stacked
either as objects or references to those objects. Either way, this does not
provide any justification to push uninitialized values into a stack.
Another example would be when growing the stack would be a very costly
operation, and putting items in slots very cheap. In that case, it would
be very advantageous if you could grow the stack by a large step, and
then insert all the items one by one.
Again, do you even know what a stack is? If you don't know, I can tell you
that a stack is a LIFO data structure. A stack, by it's very definition,
doesn't offer a way to traverse the data structure. It offers a way for you
to access the top() element, it lets you push() elements and it lets you
pop() elements. If you are thinking of a data structure which lets you
traverse the data it stores then you are thinking of some other data
structure, but you aren't thinking of a stack.
One could also imagine having a stack that stores char values, but using
it for different-sized objects/blobs.
Irrelevant. You store the object (or reference to the object), not the data
it represents.
Oh, and as a very real-life example, look at the way that a C compiler
uses stack frames: it allocates a whole frame in one go, and then uses the
space it created for different variables, objects, et cetera.
Stack frames are elements of a call stack. That is, they are the objects
(or references to an object) which are pushed into the stack. A call stack
doesn't push a new stack frame (that is, a new object isn't push()ed into
the stack) unless it needs to store information on that stack (that is,
unless there is a need to push() a value into the stack, and therefore
initialize the value). Therefore, this does not provide any justification
to push uninitialized values into a stack.
Rui Maciel