For me the big difference between dynamic and statically typed languages is catching bugs like:
foo = bar()
if foo:
fooo = baz()
in a static language, you'd have to write int foo = and the third line where you have an assignment fooo would be caught by the compiler. Of course there's advantages to dynamic languages, like being able to write something like
I don't think your example has much to do with typing. The types of foo and fooo can be inferred from the return types of bar and baz, so in a language that supports type inference (e.g. Scala), no annotations are necessary.
As for whether "fooo" is a valid symbol, whether you can declare a variable without a keyword is unrelated to the type system. See, e.g., Go, which has different operators for declaration-with-assignment and reassignment (:= vs. =), but this is merely a syntactical safety net, not an outright necessity.
In the first case, any sane static language will use type inference, so you won't have to write out "int foo", just "let foo" or equivalent. (I'd also argue that any sane static language would disallow or at least heavily discourage mutable variables, but that's neither here nor here).
The second case is easily handled by static languages, for example, in Swift:
var mydata = ["foo": Dictionary<String, MyObject>()]
mydata["foo"]["bar"] = MyObject()
This is only longer than it needs to be because of using two lines, you wouldn't need the explicit declaration to do it in one:
That's what linting is good for, at least in JavaScript where you have optional "var" declarations: You can set jshint to flag as an error any assignment that isn't part of a "var" declaration (or any reference that isn't explicitly defined), which will catch (at compile time) any variable name typos.
It won't catch this.fooo, though, so it's only a partial solution. My editor has great completion, though, so as long as the string is IN the file somewhere, I usually autocomplete it. Way fewer typos that way.
I see there's a PyLint, so MAYBE it has a way of spotting typos like the one you cite? Not sure how it would work in Python, though, other than on variable reads.
Certianly lint handles this. Some lint checks are quite reasonably considered type constraints, even if they historically have been implemented seperately. In particular, uninitialized values and unused variables seem very much in the same theoretical space as linear types.
That's not really a difference between dynamic and statically typed languages — what makes the difference here is having different syntax for variable declaration and assignment. It so happens that most dynamic languages use the same syntax for both, but there's nothing about separating the two that requires static typing. For example, strict mode JavaScript is a dynamic language that can detect this error, because JavaScript uses var to declare variables.
Comments
For me the big difference between dynamic and statically typed languages is catching bugs like:
in a static language, you'd have to write int foo = and the third line where you have an assignment fooo would be caught by the compiler. Of course there's advantages to dynamic languages, like being able to write something like without a lot of boilerplateI don't think your example has much to do with typing. The types of foo and fooo can be inferred from the return types of bar and baz, so in a language that supports type inference (e.g. Scala), no annotations are necessary.
As for whether "fooo" is a valid symbol, whether you can declare a variable without a keyword is unrelated to the type system. See, e.g., Go, which has different operators for declaration-with-assignment and reassignment (:= vs. =), but this is merely a syntactical safety net, not an outright necessity.
In the first case, any sane static language will use type inference, so you won't have to write out "int foo", just "let foo" or equivalent. (I'd also argue that any sane static language would disallow or at least heavily discourage mutable variables, but that's neither here nor here).
The second case is easily handled by static languages, for example, in Swift:
This is only longer than it needs to be because of using two lines, you wouldn't need the explicit declaration to do it in one: This also gets rid of mutable state!That's what linting is good for, at least in JavaScript where you have optional "var" declarations: You can set jshint to flag as an error any assignment that isn't part of a "var" declaration (or any reference that isn't explicitly defined), which will catch (at compile time) any variable name typos.
It won't catch this.fooo, though, so it's only a partial solution. My editor has great completion, though, so as long as the string is IN the file somewhere, I usually autocomplete it. Way fewer typos that way.
I see there's a PyLint, so MAYBE it has a way of spotting typos like the one you cite? Not sure how it would work in Python, though, other than on variable reads.
Certianly lint handles this. Some lint checks are quite reasonably considered type constraints, even if they historically have been implemented seperately. In particular, uninitialized values and unused variables seem very much in the same theoretical space as linear types.
Static typing has no relation to explicit declaration of variables.
That's not really a difference between dynamic and statically typed languages — what makes the difference here is having different syntax for variable declaration and assignment. It so happens that most dynamic languages use the same syntax for both, but there's nothing about separating the two that requires static typing. For example, strict mode JavaScript is a dynamic language that can detect this error, because JavaScript uses var to declare variables.
thanks to tab completion i virtually never run into this bug in javascript or ruby
could you share what editor and what, if any, plugins you're using?
sublime text 3, out of the box.
the only plugin i have is ES6/Babel syntax highlighting.
it mostly "just works"