

The Stack Is An Implementation Detail - baha_man
http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

======
noss
«Leaving performance considerations aside, what possible difference does it
make to the developer whether the CLR’s jitter happens to allocate memory for
a particular local variable by adding some integer to the pointer that we call
“the stack pointer” or adding the same integer to the pointer that we call
“the top of the GC heap”?»

I'm all for avoiding premature optimizations, and giving priority to short and
comprehensible code over faster code. But "leaving performance considerations
aside" is like discussing dictatorship and "leaving human rights issues
aside".

Good programmers have good hunches about performance, better programmers pick
the shortest code anyway, the best programmers measure and then maybe
optimize.

~~~
DarkShikari
The best programmers also know to think about performance when designing a
system--if you completely abide by the strategy of "don't prematurely
optimize", you end up with a system which _wasn't designed with performance in
mind_ , and often is very difficult to optimize later because of this.
Sometimes the entire structure of the program has to be redesigned because the
original method just was not suitable for performance.

A great programmer is able to think about performance at every point in
designing something without obsessing about it to the point where it decreases
reliability, readability, or extensibility.

~~~
noss
I think you are correct, but your scenario is a good example of something
else: Prototyping and "planning to throw one away" (Fred Brooks / The Mythical
Man Month).

Having written one lousy implementation in X months does not mean that the
good implementation, when starting over, will take X more months.

I have never seen a functional specification reaching more than 50% accuracy
on details (most are not even close). When implementing you always discover
more about the problem.

What stops you from starting over tends to be that the customers have
integrated with your system according to published specs, or large roll-outs
have been made already.

~~~
DarkShikari
_I think you are correct, but your scenario is a good example of something
else: Prototyping and "planning to throw one away" (Fred Brooks / The Mythical
Man Month)._

Of course, but one is not always implementing a totally new system that
justifies "throwing one away". Often one is implementing something whose
design is well-known enough that one should expect to be able to do it right
the first time.

 _Having written one lousy implementation in X months does not mean that the
good implementation, when starting over, will take X more months._

Sure, but it still takes Y more totally unnecessary months, even if Y is less
than X.

------
Hoff
The stack is a great huge implementation detail, and doesn't necessarily work
the way you want it to.

With porting an operating system across processors or when performing
significant changes and upgrades to an operating system and its interfaces,
the details of the data and call stack and the thread stacks and register-
passing and register spillage and all the other related ugliness can be (and
often is) exceedingly platform-specific.

Adding applications dependencies on these details means your code can be
somewhere between faster and less portable, or faster and non-portable.

Or your applications can pin the vendor in a corner by depending on a design
statement that the vendor might now regret having made. Whether that might
provide or prevent a thread stack, or changes to the call frames, or stack
randomization or otherwise.

I'm working in several areas where the vendors spend far, far, far too much
time describing the internal details of their implementations. Which is bad on
several levels. It can pin the vendor to the design; into choosing
compatibility or choosing to break applications. And it tends to obscure the
information presented to application programmers with details that are less
than relevant.

There's more here than strictly performance; there's also compatibility and
maintainability, and stability and sustainability, and extensibility.

Absent specific reasons and whenever in doubt, the decision should be to
present an opaque interface. "The stack is an implementation detail."

------
10ren
I've recently come to appreciate a mathematical approach, which I see as
_declaring constraints_. The power of this (for me) is that you can separate
constraints in any way you like, and combine them however you like. This is
important when you need to simplify a problem into parts, in order to be able
to understand it one bit at a time (it's still an art to know _how_ to divide
up the problem, but maths gives you options).

It's very appealing (and obvious) step to then execute these declared
constraints - that is, to code directly in terms of the mathematics.

But here's the problem: the maths doesn't tell you _the_ answer; it just tells
you its constraints. The answer you want is somewhere in that space. Of
course, it's possible to write a language that will always give you _an_ from
within that space. The most well-known way for this issue to show up is in
efficiency: the solution given by the language does fall within the
constraints, but it takes too long. If we had a way to declare the efficiency
as a constraint, this might change... but apparently that's a hard one. Other
constraints are things like: usability, understandability (to coders of
average ability, average education and average deadlines), interoperability
with standards (which are never ideal, but which exist and which work),
portability, modularity and many others that I haven't encountered or
imagined.

Partly the difficulty is in specifying a soft, human constraint in formal
terms; the other part is solving for that constraint, which appears to require
strong AI or bump up against the halting problem - or else we could just
declare the constraint: "fastest possible solution".

~~~
anonymousDan
I've recently started taking the exact same constraint approach. I find it
helps to give me a much more concise mental model of the problem I'm trying to
solve. I guess this is because of the declarative nature of the constraints,
and the fact that aren't trying to keep all the implementation details in your
head. Instead you just ensure that whiles you are programming, you respect the
constraints at all times. I find it particularly useful when the problem
requires maintaining lots of different data structures that interact with each
other.

~~~
10ren
Yes. I actually find it really difficult to stop thinking about the
implementation (and the usability) of what I'm creating. These are good things
to be concerned about, but not when the problem is already too complex.

On another aspect of it: the last couple of days, I've found it very effective
to think of a model as just the nouns, not verbs; data structures, not
algorithms (as in the Brooks quote). Guess this is implicit in the idea of a
constraint, but it's helping.

The other thing is that the model doesn't have to be _precisely_ correct. It
only needs to be correct in the important ways (if I don't already know what
the important aspects are, a complicated model probably won't enlighten me).
This gives me conceptual framework to _think_ in, rather than to be an
authoritative definitive description, perfectly correct in every minor details
(they can be corrected early or late, if they really are minor). I find it
helps to give me a vantage point, to see further. My mind is very fertile with
finding solutions - provided I can _see_ where I am.

------
almost
Yes, you could enumerate all its characteristics and such to try and give the
programmer an idea of how it will behave. Or you can just say "it's allocated
on the stack" and much of that will be obvious. Seems like quite a good
shorthand to me if nothing else.

------
cfrey
An interesting point, but using the stack is not always transparent. You can
ignore how it works for the most part, but eventually you're going to notice
differences in performance or get a stack overflow exception.

