To give the counter-argument some weight: I disagree, wholeheartedly. Explicit variable declaration is a throwback inherited from statically-typed language, where a variable's type must be declared before use, and has no place in a dynamic language.
> It's just too prone to typos and broken scoping to be worth it.
Predeclared variables are just as prone to typos, which will also break your code -- and just as prone to broken scoping. By accidentally shadowing an external variable you make it unreachable for the remainder of the current function, and all nested functions within.
Clearly, declaring the type of a variable is not necessary in a dynamic language, so the only purpose of a variable declaration is to manually mark it's scope, shadowing any potential name conflict.
There are no situations where shadowing a variable is desirable. It's always best to be able to reach any variable that exists in the current lexical scope, should you find the need.
The only ambiguous situation in which you'd want to use a "var" on purpose is to explicitly shadow an external variable of the same name -- if you accept that shadowing is undesirable, and choosing a more descriptive name for the inner variable is preferable, then QED.
Dynamic languages should not have variable declarations.
> Predeclared variables are just as prone to typos, which will also break your code -- and just as prone to broken scoping. By accidentally shadowing an external variable you make it unreachable for the remainder of the current function, and all nested functions within.
You declared a variable once and use it n times. If you accidentally shadow a variable, via typo, then you only have one place to check for the typo. The compiler/interpreter will complain if you don't happen to also consistently made that typo everywhere you use the variable.
In language with implicit declaration, everywhere you use the variable is as likely to have typo that the compiler/interpreter cannot check for you.
1 place to check vs. n places, is a no-brainer which one is more error prone.
> By accidentally shadowing an external variable ...
In language with explicit declaration you have to accidentally declare same name AND use it with that accidental name. If both doesn't happen, the interpreter will complain.
In language with implicit declaration, one accidental typo is all it takes to accidentally shadow a variable.
You have just made a case against implicit declaration.
> There are no situations where shadowing a variable is desirable. [...] if you accept that shadowing is undesirable, and choosing a more descriptive name for the inner variable is preferable
So, to name a local variable "list", you have to look up on every outer variables involved to make sure nowhere else also use the name "list".
And let's give up on naming an outer variable name "list" because, who knows where some inner function might decide to use such name for local variable.
> choosing a "more descriptive name" for the inner variable
More like "more redundant name". Implementing "date_diff" function? Forget naming different of it "delta", let's name it "date_diff_delta", or else it might conflict with some outer variable name.
Congratulation, you have successfully remove concept of namespace from your language.
> if you accept that shadowing is undesirable
Then you should consider other job than programming.
> Predeclared variables are just as prone to typos, which will also break your code
Not so: declaring variable name & scope ensures immunity to the "I wanted to change this variable, but I'm creating a new one instead", and this can be checked statically even in dynamically typed languages.
> There are no situations where shadowing a variable is desirable.
While I do not agree with this assertion, I can see where you come from and explicit scoping is still superior to implicit for this: if there are no situation where shadowing is desirable, you can make the language statically forbid shadowing. There, done.
> It's always best to be able to reach any variable that exists in the current lexical scope, should you find the need.
It is not, however, desirable to reach and unknowingly alter an existing variable in an ancestral lexical scope when you did not mean to and just happened to pick an existing name in a callback 2-levels down the stack. The result of this is silent corruption of program state, and it is a risk in any implicitly-declared scoping system with mutable bindings.
> The only ambiguous situation in which you'd want to use a "var" on purpose is to explicitly shadow an external variable of the same name -- if you accept that shadowing is undesirable, and choosing a more descriptive name for the inner variable is preferable, then QED.
Then QED nothing, since as I pointed out it is perfectly possible to make variable shadowing statically illegal, ensuring that no variable is hidden and no variable is silently reused or replaced either.
> Dynamic languages should not have variable declarations.
Nope.
Furthermore, explicit scoping significantly increases readability and lowers cognitive burden: readers don't have to wonder whether a given assignment is local to the current lexical scope, it's spelled out for them. And if it's a bare assignment (not a new variable), explicit scoping makes it easier to find out where the variable is first used. Not to mention it allows the language to protect against in-scope reuse (in cases of debatable-quality imperative code with scopes more than a screenful long), as the second declaration may (and generally will) be statically marked as the redeclaration of an existing variable, and will be refused by the language's runtime.
And all of that for the cost, in most languages, of 3 characters. Almost nothing. All the issues you mentioned (since you didn't mention typing) are not issues of explicit scoping but with specific implementations thereof.
> It's just too prone to typos and broken scoping to be worth it.
Predeclared variables are just as prone to typos, which will also break your code -- and just as prone to broken scoping. By accidentally shadowing an external variable you make it unreachable for the remainder of the current function, and all nested functions within.
Clearly, declaring the type of a variable is not necessary in a dynamic language, so the only purpose of a variable declaration is to manually mark it's scope, shadowing any potential name conflict.
There are no situations where shadowing a variable is desirable. It's always best to be able to reach any variable that exists in the current lexical scope, should you find the need.
The only ambiguous situation in which you'd want to use a "var" on purpose is to explicitly shadow an external variable of the same name -- if you accept that shadowing is undesirable, and choosing a more descriptive name for the inner variable is preferable, then QED.
Dynamic languages should not have variable declarations.