Am Fri, 02 Mar 2007 14:16:30 +0800 schrieb Peter Duniho:
On Thu, 01 Mar 2007 23:57:53 +0800, Paul Werkowitz
<ne********@pri maprogramm.dewr ote:
>[...]
How could you ever assume that f will be called directly in f? My
original
example does not have such an assumption. To be honest: In a real world
application, f might call h, which might call g, which invokes a delegate
that sends a Windows-message which leads to another call of f
Fine. Then just put the "static" variable outside of the function, as
suggested elsewhere. At least that way, it is clear to anyone reading the
code where the data is stored and what its lifetime is.
Yes, that is possible. Whether it is good or better than local statics
needs to be seen. I just wanted to point out that passing another argument
often is not possible. If the situation is easy, you usualy don't need any
additional means to find th problem. In larger apps there are so many
functions... and suddenly f gets called again from a call within f.
Besides of that - even if it was possible, adding arguments to funtions
that don't use them and don't know nothing of them seems no good practice
to me. All of the functions simply would pass the argument to the functions
they call. The value does not have any meaning to them. It has only meaning
to f. I remember the day when we did not have exception handling. We passed
result state up to the calling function, and then again up to the next
level - until some caller handled them. Luckily this is not necessary any
more.
This all is only a nuisance - it clutters code and is unneccesary work, but
not really bad, only silly. But there are also severe conceptional
problems, too. For example, what happens if you want to use h yourself?
What do you tell your client to pass for that additional parameter? You
impose complexity on h and on all callers of h, although they have nothing
to do with the recursion problem of f. You sure know the principle of
locality, which is broken here.
(I know, you can write another overload of h without parameters and call
the modified h.... - yes, this moves the problems out of sight for h's
clients but the problems remain.)
>
>>See above. C# makes no such demand on you. It's true that it doesn't
allow for static local variables, but there are solutions other than
defining variables at the class level.
And these are?
Well, I proposed two, and others have provided additional methods. You
don't have to have a static local variable in order to track recursion
level.
You are right - but this is not the question. You always can use
alternative ways to accomplish something. I know a guy that keeps telling
me that Cobol is everything a serious programmer needs (no joke) - and,
he's right. Assembler would be equally possible.
It's not so much a question whether "there are alternative ways" but more
"what properties do these alternative ways have compared to local statics".
For example, I gave reason why additional parameters - as you suggested -
are not an option for me. I consider the disadvantages for my code as too
much. It it were possible at all.
[snip]
>
There is no "additional complexity". There is simply "different
complexity". How is keeping a static local variable, which you increment
upon function entry and decrement upon exit, not complex in and of
itself? Other solutions are not more complex...they are just different.
A valid argument. I answered in the paragraph above. For example. clients
of h have to deal with complexity which does not belong to their domain.
That kind of complexity I judge more severe that that of local statics.
What leaves the other solution that uses statics, too. Whether you use a
static at class scope or factor it out to another (static) class makes no
difference at all. For me, its not so much of a difference where that
static is located. The much bigger difference is that between instance and
static data. A programer simply *has* to understand the difference, period.
Yes, your kissin cousins are there...
>
>See the problem? The recursion-checking-value has absolutely no meaning
for h or anybody else except f. And thats why it should be confined to f.
But a static local variable isn't truly confined to f. The problem is
that it only *looks* like it is confined to f. The only confinement is in
visibility, and because it is not confined in other ways, it is possible
for a programmer to misunderstand what is going on and create bugs.
You probably mean initialization probs, and threading issues. Yes, the
unloading/relaoding of an AD re-initializes local statics in VB. Maybe they
sell it as a feature, IMHO its wrong.
What a programmer is interested in, is visibility. And no side effects, of
course. If local statics were implemented like class statics except
visibility, I canÄt see any problems.
>Could you please elaborate a little why use of static variables is bad
coding practice? I can't see this.
Well, for one in languages where a local static variable essentially
creates a global variable, you are violating the basic tenet to minimize
global variables. Global variables exist for the entire lifetime of an
application; even when they are not being used, they take up space.
Taking up space you aren't using is wasteful and is apoor programming
practice.
I don't agree with the tenet that globals are bad. Especially when movin
from C to C++ for example, they tend to be heavily overused. But it is as
with any language feature: its not the feature that is bad, it is the
improper use. Don't use globals when you don't have to - but use them when
its appropriate. Look at some arbitrary code and look for static classes
with data members.
Secondly, globals can be null, too. If space was an issue, you can
implement some lifetime management, e.g. with factories and managers. But
since an empty app uses 30 MB of memory on my machine, space mosty is not
an issue. And OS can swap out pages.
And, my local static simply is an int. When we talk about memory, the
additional parameter you suggest cost much more. Not to forget the
additional CPU load (of my dual core Intel).
>
Others have explained how in particular versions of VB, static local
variables have less-than-intuitive behavior. For example, the possibility
of a static local being reinitialized during execution.
Ack. Bad!
>
In C#, one problem your static local has is that if an exception occurs
within the routine, if there is no exception handler in that routine, then
the recursion level as tracked by your static local will be incorrect.
Alternatively, you have to add an exception handler in the routine, which
increases complexity (something you apparently are against).
Absolutely right. If exeption safety is an issue, more work is necessary.
Unfortunately .NET has no deterministic destruction, therefore we cannot
program janitors as elegantly as in C++, but one can use using-clause.
[parts snipped)
>
>But from a greater distance the picture is different.
Again, when you think you don't need local statics: please give a
suitable implementation of the recursion detection problem.
I suspect your definition of "suitable" will restrict possible examples to
those that behave in *exactly* the way a static local would. Given that,
I have to admit that it's unlikely anyone could come up with something you
consider "suitable". However, in reality you don't need something that
works *exactly* the way a static local would. You just need something
that solves the problem at hand (knowing how many levels of recursion
you've called the function), and there are a number of alternatives to a
static local in that case (as has already been pointed out). You
obviously disagree that they are "suitable", but so far you've made no
compelling argument that they are any worse than your proposed use of a
static local.
I hope you can agree that we must look at the advantages and disadvantages
of the alternatives. I have brought arguments that show the problems of the
sugested alternatives. You have brought your arguments why local statics
are no good. Everybody can make up his mind now.
((I have to go now, and hope I can write something to the rest of the
arrticle later))
Paule