-
-
Save myw/178165ff5002915e0ad3 to your computer and use it in GitHub Desktop.
#include <stdio.h> | |
int func(int, int, int); | |
int | |
main() | |
{ | |
printf("%d\n", func(3, 4, 5)); | |
return 0; | |
} | |
int | |
func(int a, int b, int c) | |
{ | |
int d, h; | |
d = 7; | |
h = 3; | |
while (h < 5) { | |
int d = 1; | |
h++; | |
d++; | |
} | |
return d; | |
} |
#include <stdio.h> | |
int func(int, int, int); | |
int | |
main() | |
{ | |
printf("%d\n", func(3, 4, 5)); | |
return 0; | |
} | |
int | |
func(int a, int b, int c) | |
{ | |
int d, h; | |
d = 7; | |
h = 3; | |
while (h < 5) { | |
d = 1; | |
h++; | |
d++; | |
} | |
return d; | |
} |
function func(a, b, c) { | |
var d, h; | |
d = 7; | |
h = 3; | |
while (h < 5) { | |
var d = 1; | |
h++; | |
d++; | |
} | |
return d; | |
} | |
function main() { | |
console.log(func(3, 4, 5)); | |
} | |
if (require.main === module) { | |
main(); | |
} |
function func(a, b, c) { | |
var d, h; | |
d = 7; | |
h = 3; | |
while (h < 5) { | |
d = 1; | |
h++; | |
d++; | |
} | |
return d; | |
} | |
function main() { | |
console.log(func(3, 4, 5)); | |
} | |
if (require.main === module) { | |
main(); | |
} |
def func(a, b, c): | |
d = 7 | |
h = 3 | |
while h < 5: | |
d = 1 | |
h += 1 | |
d += 1 | |
return d | |
if __name__ == '__main__': | |
print(func(3, 4, 5)) |
yes, exactly
Another way to look at it is through the idea of referential transparency. When does this snippet of code do it you put it in the middle of your program?
a = 1
b = 2
if a < b:
temp = a
a = b
b = temp
A lot of people would expect it to have just the effect of assigning a=2 and b=1 but it has the additional, perhaps unexpected, effect of assigning temp, should it already exist, to 1. In Scheme, this code looks like this:
(let ([a 1
[b 2])
(when (< a b)
(let ([temp a])
(set! a b)
(set! b temp))))
If there is a temp in scope outside of this block of code it has the exact same effect. temp is just briefly shadowed because the developer who added this code probably didn't know about it, but she doesn't have to because the lexical scoping makes it clear what this code is doing regardless of any, potentially hairy, context it might be in.
This is all solved by introducing a let or my or var keyword. Personally I'd require it. I hear this is happening in Python 3. I'm not sure if it's going to change it's scoping though. I'll have to read up on that. Hopefully the introduction of this keyword doesn't work like var in Javascript.
There are no scoping changes planned for Py3 as far as I can tell. ECMAScript 6, however, is planning on adding a let
keyword, which would work normally, unlike that insane var
nonsense: all curly braces would create local scope for variables declared with let
.
The Python example might seem intuitive in this short program but can be terribly confusing. It depends on what you intended. The problem is that there's no difference syntactically between variable assignment and declaration. If you intended variable assignment then you got it right. But if when you wrote "d=1" you were thinking "Make a new variable called d and initialize it to 1" then you have a bug. In most languages, including Scheme, Perl when use strict is on, Java, and ML these are two distinct operations. Furthermore with a good environment you'll get a warning for shadowing the declaration of d, but it's not an error.
In the Javascript version of this code it's absolutely insidious because Javascript has an explicit declaration with 'var' but they outright lie to you and just turn that into assignment.