already used in a 'child' scope to denote something else

  • Thread starter valentin tihomirov
  • Start date
V

valentin tihomirov

{
int i = 2;
}
int i = 1;

There is no 'i' defined in the 'parent' context from the moment of
declaration on. So what is the problem? They tell us they pursue language
simplicity. The rule "do not define a variable more than once in the same
context" is natural, and simplest therefore. All normal languages obey it
therefore. Overcomplicating a grammar by injecting more barrieres is a path
right away from simplicity. Another obstacle at the plain place introduced
in C# for no reason is blocking "fall throughs" in switch -- the feature
wich can be very useful sometimes. C# designers demonstrate some excessive
zeal on 'protecting' us from doing things naturally, going strightforward
ways.

"Give a fool rope enough and he'll hang himself."
 
J

Jon Skeet [C# MVP]

{
int i = 2;
}
int i = 1;

There is no 'i' defined in the 'parent' context from the moment of
declaration on. So what is the problem?
From section 10.7 of the spec:

<quote>
The scope of a local variable declared in a local-variable-declaration
is the block in which the declaration occurs.
</quote>

In other words, the "outer" variable i has scope which includes the
part of the block before it was declared. There's then an extra rule:

<quote>
Within the scope of a local variable, it is a compile-time error to
refer to the local variable in a textual position that precedes the
local-variable-declarator of the local variable.
</quote>

The rationale is given in notes of the spec:

<quote>
Note: The scoping rules for local variables are designed to guarantee
that the meaning of a name used in an expression context is always the
same within a block. If the scope of a local variable were to extend
only from its declaration to the end of the block, then in the example
above, the first assignment would assign to the instance variable and
the second assignment would assign to the local variable. In certain
situations but not in the exampe above, this could lead to a compile-
time error if the statements of the block were later to be rearranged.
They tell us they pursue language
simplicity. The rule "do not define a variable more than once in the same
context" is natural, and simplest therefore. All normal languages obey it
therefore. Overcomplicating a grammar by injecting more barrieres is a path
right away from simplicity.
Another obstacle at the plain place introduced
in C# for no reason is blocking "fall throughs" in switch -- the feature
wich can be very useful sometimes.

Very useful sometimes when it's deliberate, but also very painful when
you don't want it and accidentally have it. Note that you *can* use
multiple cases for a single block, you just can't have case/code/case/
code without a break.

I suspect that when working with C, I ran into more times when I
forgot to include the break than times when I deliberately wanted to
fall through.

The switch statement isn't very nicely designed in general, however -
it harks back to C too much, IMO. I would rather have seen cases
require an extra set of braces, and for fallthrough you could then
have an explicit "continue" instead of a break for non-fallthrough.

So yes, I agree that switch isn't great - but taking away the
restriction against fallthrough would make it even worse, IMO.
C# designers demonstrate some excessive
zeal on 'protecting' us from doing things naturally, going strightforward
ways.

Well, I'm happy with both of these decisions.
"Give a fool rope enough and he'll hang himself."

True. The less rope you provide, the more foolish he has to be
though...

Jon
 
V

valentin tihomirov

In other words, the "outer" variable i has scope which includes the
part of the block before it was declared. There's then an extra rule:

It is a fact that statements are executed seqientially, one after another.
It is truth that a block of instructions is executed as one statement. It is
truth that the variables in the imerative languages, which allow deferred
declarations, are visible only past declaration. Acquiring these basic
matters, everybody understands that the parent block variables declared past
the block are not visible inside the block and that the block internal
variables are not visible past the block. The other considerations are
irrationale.


<quote>In certain
situations but not in the exampe above, this could lead to a compile-
time error if the statements of the block were later to be rearranged.
</quote>

Rearranging code always can yeild errors. Does this argument give me power
to infer arbitrary rules?


Very useful sometimes when it's deliberate, but also very painful when
you don't want it and accidentally have it. Note that you *can* use
multiple cases for a single block, you just can't have case/code/case/
code without a break.

I suspect that when working with C, I ran into more times when I
forgot to include the break than times when I deliberately wanted to
fall through.


I suppose that the first thing the programmers should know is the sequence
of instruction execution. Normally, the statements are eveluated
sequentially. Should we put an explicit branch after each and every
statement to avoid the natural "fall through"? The fallthrough ban does not
save you from the infinite kinds of errors you still can make, including
wrong branching. It just infers a fair amount of code where it is
unnecessariy. You should consider avoid programming be safe. I doubt that
the requirement to pile up the loads of syntactic salt improves the quality
of code the unconscious people produce.
 
J

Jon Skeet [C# MVP]

Rearranging code always can yeild errors. Does this argument give me power
to infer arbitrary rules?

I was just giving you the reasons the language designers gave.
Personally, I don't have a problem with it - I find it tends to make
the code more readable to give the variables different names in this
kind of case anyway. I can't say it's bothered me that often - it's
hardly a straitjacket, is it?
I suppose that the first thing the programmers should know is the sequence
of instruction execution.

It's not a matter of knowing the rules, it's a matter of whether the
rules let you easily make mistakes.
Every time I forgot to put a break in, it was a simple matter of
forgetfulness, not a failure to understand what the code would do.

No, this won't prevent every mistake. Yes, it prevents certain ways of
working. However, I believe it helps more than it hinders, which is
why I'm in favour of it.

Regarding your change of subject line, I would retort: "Go ahead. Stop
using C#. That will stop you from being hindered by its rules."
Seriously, if you dislike so many design decisions of a language, why
use it?

Jon
 
V

valentin tihomirov

Regarding your change of subject line, I would retort: "Go ahead. Stop
using C#. That will stop you from being hindered by its rules."
Seriously, if you dislike so many design decisions of a language, why
use it?

Jon

Why to work to satisfy all the perversive desires of the masters who kill
our planet? Yea, we are "free". We are allowed not to use English, even not
to use Windows. At this point you should suggest me to design my own
language (to talk to myself). The liberals can even mention you that you are
free not to breath if you do not like to. In other words: "If you do not
like our way of ruling the world, you are free to die". Are they serious?
 
B

Ben Voigt [C++ MVP]

The switch statement isn't very nicely designed in general, however -
it harks back to C too much, IMO. I would rather have seen cases
require an extra set of braces, and for fallthrough you could then
have an explicit "continue" instead of a break for non-fallthrough.

That does exist... "goto case"
 
J

Jon Skeet [C# MVP]

Why to work to satisfy all the perversive desires of the masters who kill
our planet? Yea, we are "free". We are allowed not to use English, even not
to use Windows. At this point you should suggest me to design my own
language (to talk to myself). The liberals can even mention you that you are
free not to breath if you do not like to. In other words: "If you do not
like our way of ruling the world, you are free to die". Are they serious?

Well, you were the one to suggest "Stop programming" to start with.

Jon
 
V

valentin tihomirov

Well, you were the one to suggest "Stop programming" to start with.

The only reliable way to defend yourself from network attacks is to
disconnect from the network. It is what is used to say when somebody limits
your communication (a provider blocks some TCP ports, for instance) "for
making it safer". If you wish to avoid doing errors, you should stop doing
things. Hinderances on the plain way do not defend you.

Compiler, grammar is needed to protect from doing nonsense, like assinging
date to a boolean or using unassigned variable or writing into constant
memory. It should not protect you from doing sensable things like writng
integer const to integer var or defining a not yet defined variable or
executing statements one after another.
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

valentin said:
It is a fact that statements are executed seqientially, one after another.

Actually, it's not. Statements can be, and some definitely are, executed
in parallell or out of sequence, as long as the result in every relevant
aspect is the same as if they were executed in the sequence specified in
the code.
It is truth that a block of instructions is executed as one statement. It is
truth that the variables in the imerative languages, which allow deferred
declarations, are visible only past declaration.

Not really. By design the variable is visible in the entire block in the
sense that you can not declare another variable with the same name.
Acquiring these basic
matters, everybody understands that the parent block variables declared past
the block are not visible inside the block and that the block internal
variables are not visible past the block. The other considerations are
irrationale.

No, they are most definitely rational.
Rearranging code always can yeild errors. Does this argument give me power
to infer arbitrary rules?

Now you are not being irrational. The rules are not arbitrary at all.
They are definitely relevant to the situation.
I suppose that the first thing the programmers should know is the sequence
of instruction execution.

It's not a matter of knowing how it works, but rather having a language
that lets you easily produce stable code.
Normally, the statements are eveluated
sequentially. Should we put an explicit branch after each and every
statement to avoid the natural "fall through"? The fallthrough ban does not
save you from the infinite kinds of errors you still can make, including
wrong branching. It just infers a fair amount of code where it is
unnecessariy.

In a switch statement you are jumping into one of many code blocks, it's
not at all unreasonable that each block should end with a statement that
specifies where the execution should continue. After all, in the
majority of cases the block will end with a break anyway.

This requirement adds a bit of unnecessary code in a few cases, but a
bit of unnecessary code is very often used to keep the language
consistent and clear. The keyword if, for example, is always followed by
a parenthesis, so the parenthesis is really totally unnecessary, but you
wouldn't argue that it should be removed or even optional, would you?
 
J

Jon Skeet [C# MVP]

valentin tihomirov said:
The only reliable way to defend yourself from network attacks is to
disconnect from the network. It is what is used to say when somebody limits
your communication (a provider blocks some TCP ports, for instance) "for
making it safer". If you wish to avoid doing errors, you should stop doing
things. Hinderances on the plain way do not defend you.

Right - and likewise, the only way it seems that you'll stop being
cross about things that C# stops you from doing is to stop using C#.
Compiler, grammar is needed to protect from doing nonsense, like assinging
date to a boolean or using unassigned variable or writing into constant
memory. It should not protect you from doing sensable things like writng
integer const to integer var or defining a not yet defined variable or
executing statements one after another.

Well, I'm sure I'm not the only one who's been bitten by accidental
fallthrough in switch statements in C. As I said, I would prefer a more
radical overhaul of switch/case, but I'd rather have what we've got
than a version which has all the ugliness of the current version but
with the added problem of fallthrough.

As Ben pointed out, you can always use goto case if you really want the
effect of fallthrough.
 
V

valentin tihomirov

It is truth that a block of instructions is executed as one statement. It
Not really. By design the variable is visible in the entire block in the
sense that you can not declare another variable with the same name.

No, they are most definitely rational.


Now you are not being irrational. The rules are not arbitrary at all. They
are definitely relevant to the situation.

I repeat, code rearrangement can always infer an error. One can tell that
water is wet. Thelling that something is good because of truth/tautalogy is
a bad excuse for lawmaking.


It's not a matter of knowing how it works, but rather having a language
that lets you easily produce stable code.

In the beginning of the post you point out the underlying processor details.
I do not see how you find and stress the details, which should normally be
hidden from programmer, as relevant and important, while disdaining the
first thing any programmer should understand -- the program flow.

In a switch statement you are jumping into one of many code blocks, it's
not at all unreasonable that each block should end with a statement that
specifies where the execution should continue. After all, in the majority
of cases the block will end with a break anyway.

This requirement adds a bit of unnecessary code in a few cases, but a bit
of unnecessary code is very often used to keep the language consistent and
clear. The keyword if, for example, is always followed by a parenthesis,
so the parenthesis is really totally unnecessary, but you wouldn't argue
that it should be removed or even optional, would you?

The 'switch-cases' are really a multi-option kind of 'if' statement. The
code blocks should be wrapped by braces, therefore indeed. However, the
switches are are a structural programming heritage. Morern, OOP languages
replace the code lookups by passing function pointers and, later, by object
references. So, normally, switches should be rare. The important case where
switches ARE INDISPENSABLE is jumping to a beginning of code. This is needed
when you mark a start/entry point to your code. For instance, you allocate
resourses 1, 2, 3 and roll back in case of error in reverse order 3, 2, 1 in
case of error starting at the reached stage. This is the fallthrough feature
which makes the switches indispensable. And they are nothing like 'if'
statements in this invaluable scenario. Sadliy, when this technique is
prohibited. It is especially sad when good features are abandoned in favour
of the people who do not care about program statements execution flow.
 
V

valentin tihomirov

Right - and likewise, the only way it seems that you'll stop being
cross about things that C# stops you from doing is to stop using C#.

... and invent my own language+OS and ... if aI do not like the decisions
made by men in power.

Well, I'm sure I'm not the only one who's been bitten by accidental
fallthrough in switch statements in C. As I said, I would prefer a more
radical overhaul of switch/case, but I'd rather have what we've got
than a version which has all the ugliness of the current version but
with the added problem of fallthrough.

If you were bitten for omitting a statement, it does not mean that this
statememt must be incorporated into the grammar.

As Ben pointed out, you can always use goto case if you really want the
effect of fallthrough.

Would you like to have the effect to a series of your program statements by
emulating the "fallthrough" by explicit goto after every statement? As Bob
http://www.bobcongdon.net/blog/2003/12/c-switch-statement.html points it
out, C# designers should introduce a "safe" must-break-switch rather than
"improving" the switch by disallowing fall-through and then adding the goto
junk.
 
B

Ben Voigt [C++ MVP]

valentin tihomirov said:
.. and invent my own language+OS and ... if aI do not like the decisions
made by men in power.



If you were bitten for omitting a statement, it does not mean that this
statememt must be incorporated into the grammar.



Would you like to have the effect to a series of your program statements
by emulating the "fallthrough" by explicit goto after every statement? As
Bob http://www.bobcongdon.net/blog/2003/12/c-switch-statement.html points
it out, C# designers should introduce a "safe" must-break-switch rather
than "improving" the switch by disallowing fall-through and then adding
the goto junk.

No, forgetting a break is a common enough error that it's not unreasonable
to require an explicit flow control statement. What's wrong with C# is that
an MVP like Jon could not know that fall-through was available with the
"goto case" construct. The error message should be written more like:

Case block ended without flow transfer, you probably wanted "break" or "goto
case" but "return", "continue" or "throw" would also work. And "continue"
should definitely not be redefined to provide fall-through, that would
really make a confusing incompatibility with C.
 
J

Jon Skeet [C# MVP]

valentin tihomirov said:
.. and invent my own language+OS and ... if aI do not like the decisions
made by men in power.

Yes, it's a silly idea - just like your suggestion of "Stop
programming" is, IMO. That was my point.
If you were bitten for omitting a statement, it does not mean that this
statememt must be incorporated into the grammar.

It suggests that it wouldn't be a bad idea. I like ideas that mean I
make fewer mistakes, if they don't constrain me too much - and
disallowing fallthrough has hardly ever constrained me at all.
Would you like to have the effect to a series of your program statements by
emulating the "fallthrough" by explicit goto after every statement? As Bob
http://www.bobcongdon.net/blog/2003/12/c-switch-statement.html points it
out, C# designers should introduce a "safe" must-break-switch rather than
"improving" the switch by disallowing fall-through and then adding the goto
junk.

So then you really wouldn't be able to do what you want *at all*. How
is that better for you? If you don't like using the "goto" then just
don't - I know I don't.

I really don't care that much whether C# allows the use of "goto" or
not, given that I don't use it - but it seems odd to complain that the
language doesn't let you do something, and then complain that you can
do it but you don't happen to like the syntax.
 
J

Jon Skeet [C# MVP]

Ben Voigt said:
No, forgetting a break is a common enough error that it's not unreasonable
to require an explicit flow control statement. What's wrong with C# is that
an MVP like Jon could not know that fall-through was available with the
"goto case" construct.

I'd say that's more of a fault with me than with the language :)

(Then again, there are various areas I don't know much about, if I try
not to use them anyway. I know very little about unsafe code, about
"goto" in general, and about any operator precedence which I wouldn't
want to assume that readers would know.)
The error message should be written more like:
Case block ended without flow transfer, you probably wanted "break" or "goto
case" but "return", "continue" or "throw" would also work.

That probably wouldn't have educated me, as I wouldn't have seen the
error often enough for it to be remembered.
And "continue" should definitely not be redefined to provide
fall-through, that would really make a confusing incompatibility with
C.

Yes, that's a fair point. How about continue with a case label? Still
too confusing? On balance, "goto" probably captures the intent
reasonably well.
 
J

Jon Skeet [C# MVP]

The important case where
switches ARE INDISPENSABLE is jumping to a beginning of code. This is needed
when you mark a start/entry point to your code. For instance, you allocate
resourses 1, 2, 3 and roll back in case of error in reverse order 3, 2, 1 in
case of error starting at the reached stage. This is the fallthrough feature
which makes the switches indispensable.

I've never needed to do that, despite using multiple resources. The
"finally" part of a try/finally or a try/catch/finally statement is the
C# way of handling this.
And they are nothing like 'if' statements in this invaluable
scenario. Sadliy, when this technique is prohibited. It is especially
sad when good features are abandoned in favour of the people who do
not care about program statements execution flow.

Perhaps those people have a different (and IMO better and safer) idiom
in mind, such as "finally".
 
B

Ben Voigt [C++ MVP]


You can get this just as easily with "goto case", or placing the switch
inside a loop, so that only one step is performed each iteration, followed
by (switch) break.

I've seen this used in environments without exception support, such as
kernel code.
I've never needed to do that, despite using multiple resources. The
"finally" part of a try/finally or a try/catch/finally statement is the
C# way of handling this.

C++ RAII is so far superior to try/finally it isn't funny. I learned
try/finally first, but after learning why ISO C++ doesn't have it, I much
prefer the C++ way.

C# support comes in the form of using... which is just an accident waiting
to happen when it isn't used properly.
 
V

valentin tihomirov

Jon Skeet said:
Yes, it's a silly idea - just like your suggestion of "Stop
programming" is, IMO. That was my point.


And what is the point if not using the language you must to use? The idea to
stop doing anything is the development of the popular idea that all possible
hinderances increase safety.



I really don't care that much whether C# allows the use of "goto" or
not, given that I don't use it - but it seems odd to complain that the
language doesn't let you do something, and then complain that you can
do it but you don't happen to like the syntax.

I always told I do not like the hinderances that protect me doing sensable
things, that "protect" me from going simply, easily, naturally,
strightforwardly, directy.
 
V

valentin tihomirov

Perhaps those people have a different (and IMO better and safer) idiom
in mind, such as "finally".

Finally in the constructor? The constructors are ubiquitous but they must
rollback the construction in a case of error. You cannot use finally
therefore. You could use the except. But it is silly to duplicate the code,
which must be supplied in destructor. So, neither 'try' nor 'finally'
replace the seek for code entry point. They rather compliment it. I tried to
explain these considerations in my unfinished blogg
http://valjok.blogspot.com/2007/05/rollbacks-destructors-for-successfully.html .
Unfortunately, C# designers abridged the technique to jump at code starting
point making this my technique ugly.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top