> First of all, put a comment at the top of your function that says what to expect about the return value.
I want a language that gives me a nice pleasant syntax for doing that.
And I want a magic pony; but as I said, declaring the return type doesn't tell users anywhere near all they need to know in many cases. Truly self documenting code doesn't exist, and will probably never exist. And since you can't usefully discuss the return value without implicitly disclosing its type in the comments, declaring the type in the code is redundant.
Now granted, there are a few nice features that you get in terms of debugging by declaring the type in a way that the computer can read. But I don't think I have personally ever actually run into a bug in a dynamically typed language that would have been avoided by a static type system.
Conversely, there are some nice things you can do when the compiler isn't breathing down your neck to make sure that all of your types are consistent. If we had a static type system that allowed me to do elegant, type-agnostic things without getting in my way, that would be lovely. Haskell comes close, but even it falls short of the ideal. Ultimately I have never found the trade off to be worthwhile.
As a programmer, you should be trained that when you see "every time", you think "automate this".
I think that's pretty specious. You do need to consistently check to make sure that your code matches your comments and documentation. You simply can't automate that because humans and computers do not speak the same language.
Note that the comment didn't redundantly point out that "from" is a File and "to" is a String.
> But I don't think I have personally ever actually run into a bug in a dynamically typed language that would have been avoided by a static type system.
I actually get to perform this experiment all the time. I work on Dart. Dart has fully dynamically-typed runtime semantics, but also an optional static type checker that the Dart Editor uses to give you static warnings.
Up until recently, I've mostly write my code in a plain text editor. I do write type annotations, but I get no static checking whatsoever. They're basically comments.
Now that I'm using the Editor more, I can open up codebases I've written that were blind to static type checking and see what kinds of warnings it finds. I get some false positives (i.e. the bug is in the type annotation, not the code), but I also find a disheartening number of legit bugs, and this is in code with good test coverage.
I like dynamically-typed languages, but it turns out the static typing people aren't crazy: it really does find bugs.
This magic pony exists. That's what the author is trying to say. You can write magic pony code, and it can be run as JavaScript. Magic Pony -> JS Conversion!
Also, the OP doesn't have an issue dynamic languages as much as weak typed languages. It just happens that JS is weak and dynamic, while AS is strong and static.
Having switched between Java, ActionScript and JavaScript for the last four years, I can assure you that bugs happen all the time in weakly typed languages that wouldn't compile in strongly typed languages. Sure, it doesn't make it past refreshing the browser, but it's not uncommon for a coworker to check in changes to a JavaScript class that completely breaks a part of the application that the dev wasn't thinking about.
For instance, I've seen return objects switch from strings to ints because of how the strings were concatenated (return "Item " + x/returns string/; -> return x/returns int/;). Somewhere else in the function it returns early with "". Now you have other functions in other classes that check someFunction().length... error... sometimes...
The point is, you now have to write unit tests to check the TYPE of each value, and in many cases, it's not easy to tell. To check if an item is an array in JS, you have to do: Object.prototype.toString.call(obj) === '[object Array]'...
Since this checking needs to be done anyways, I'd rather it be done by the compiler rather than by a dev remembering to write a test for each possibility.
> but it's not uncommon for a coworker to check in changes to a JavaScript class that completely breaks a part of the application that the dev wasn't thinking about
You don't need to write unit tests to check the type of each value, you just need to have a decent set of integration tests to make sure you aren't breaking other parts of the app. If errors in the browser after a refresh don't help you catch it, failing integration tests will. This is how we do things on my large scale javascript project and it works out just fine; we have development challenges, for sure, but weak/dynamic typing issues is not one of them.
The point still stays. Why having to write even integration test for something that can be easily checked by compiler. Better focus on writing tests that cover functionality instead of making sure return types are correct.
That's unreliable for client-side work because each frame has its own Array.prototype object which disavows instances that were created by code from different frames. It's a lot like Java classloaders, where if you aren't careful you can end up with several distinct and incompatible classes with identical names and (often) bytecode.
>And I want a magic pony; but as I said, declaring the return type doesn't tell users anywhere near all they need to know in many cases.
Then you're doing it wrong. Write types that encapsulate all the information you need. Don't allow construction of invalid instances. It's not rocket science.
I want a language that gives me a nice pleasant syntax for doing that.
And I want a magic pony; but as I said, declaring the return type doesn't tell users anywhere near all they need to know in many cases. Truly self documenting code doesn't exist, and will probably never exist. And since you can't usefully discuss the return value without implicitly disclosing its type in the comments, declaring the type in the code is redundant.
Now granted, there are a few nice features that you get in terms of debugging by declaring the type in a way that the computer can read. But I don't think I have personally ever actually run into a bug in a dynamically typed language that would have been avoided by a static type system.
Conversely, there are some nice things you can do when the compiler isn't breathing down your neck to make sure that all of your types are consistent. If we had a static type system that allowed me to do elegant, type-agnostic things without getting in my way, that would be lovely. Haskell comes close, but even it falls short of the ideal. Ultimately I have never found the trade off to be worthwhile.
As a programmer, you should be trained that when you see "every time", you think "automate this".
I think that's pretty specious. You do need to consistently check to make sure that your code matches your comments and documentation. You simply can't automate that because humans and computers do not speak the same language.