Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I also find objections like the "createBunnyOrToaster" antipattern to be really, really uncompelling. You don't need a static type system to make sure that your functions are sane and consistent, and you don't have to be John Resig either.

First of all, put a comment at the top of your function that says what to expect about the return value. You should be doing this anyway because the return type alone is often not sufficient for future programmers reading your code.

Secondly, every time you write the word "return", look up at the top of your function and make sure you are in accordance with what you said the function would do. If you end up with a paragraph comment about what the return value will be like, refactor.



> You don't need a static type system to make sure that your functions are sane and consistent, and you don't have to be John Resig either.

Right, and you can do structured programming in assembly. But when the language or tools don't help you do that, there are examples like the one the author points out where developers don't.

Don't mistake utility (what can be done) for usability (what is easy to do). Usability always matters.

> 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.

> Secondly, every time you write the word "return", look up at the top of your function and make sure you are in accordance with what you said the function would do.

As a programmer, you should be trained that when you see "every time", you think "automate this". If you and everyone on your team and everyone who has ever been on your team has to remember to do something every single time, your code will accumulate a pile of instances of forgetting.

Fixing that is exactly what tools and languages are for. It's a hell of a lot easier to make a disciplined tool than a more disciplined programmer. (And when you have made a more disciplined programmer, they typically evidence that by asking for more disciplined tools.)


> 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.


> declaring the return type doesn't tell users anywhere near all they need to know in many cases.

It doesn't declare all they need to know, but it covers a good fraction of it. As a really nice bonus, it's machine checkable.

> And since you can't usefully discuss the return value without implicitly disclosing its type in the comments

I don't seem to have this problem. I have lots of comments that are like:

    // Copies [from] to [to].
    copyFile(File from, String to) { ... }
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.


>And I want a magic pony;

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.


Just genuinely curious, as I assume it's some bit of Javascript weirdness I don't know, but why the tostring rigmarole over "obj instanceof Array"


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.


Unfortunately static typing doesn't really fix the automation problems that are most common in software development any better than anything else. I wouldn't mistake a personal preference for static type systems and large complex IDEs for superiority of language or productivity.


I wouldn't mistake an appreciation for static types with a preference for large complex IDEs or a statement of language superiority. I work mostly in a text editor in a language whose static type system is far from mandatory.


put a comment at the top of your function that says what to expect about the return value.

Great, so now the documentation for the function will promise to return a motorcycle, but instead return either a bunny or a toaster.

There are lies, damn lies, and boilerplate code comments.


>Great, so now the documentation for the function will promise to return a motorcycle, but instead return either a bunny or a toaster.

Not if you follow the second part of my above advice.

>There are lies, damn lies, and boilerplate code comments.

Since when is a comment that explains what a function does "boilerplate"? I think you are confused.


I've often had to work with code where the comments indicated an entirely different intention than the implementation. As a result, I'm a little paranoid and skeptical, that's all.

I also don't like the idea of having to comment each and every single function. If you have to write a comment to explain what it does, maybe you haven't named it properly?


There are a few people who are cautious and methodical enough to specify all types in comments and keep them correct. But you need an entire team of them, because type comments which are only mostly correct would be worse than useless. And an entire team wouldn't choose a dynamically-typed language that makes those showstopper bugs more likely.


Well, if you're having major problems keeping the project's code and comments in sync, no compiler will save you.


That's exactly how the compiler saves you. A strongly typed routine signature contract is a like comment that cannot get out of sync.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: